如题需要产生一个无规则,通用性的波形函数。
先讲最优解,方便复制就跑。不着急的兄弟可以看一下我的解题思路。
#define Type int //方便修改之后要变换的存储类型 Type arr[] = { 3, 1, 2, 1, 1 }; //电平翻转3次,起始电平为1,持续时间分别为2,1,1个时间周期 void Waveform(Type* arr) //以51举例,直接操作对应引脚 { Type x,j;//x存放电平情况,j存放电平翻转次数 j = *(arr++); P1^1 = *(arr++); //起始电平 while (j--) { x = *(arr++); delay(x); P1^1=~P1^1; } } void main() { Waveform(arr); while(1); }
我看到此题的第一想法是创建一个数组,数组内存放单个周期的电平情况,就如此波形。数组如下
int arr[40]={1,1,0,1,0,0};//后面的就不写了
注:全文波形以前面这部分为例子
有了数组之后再创建一个函数,传入数组首元素地址,每隔一个单位时长根据数组内容翻转电平。
void Waveform(int* arr) //以51举例,直接操作对应引脚 { int x; for(x=0;x<40;x++) { P1^1=*(arr+x); delay(1); } } void main() { Waveform(arr); while(); }
但是这样就会遇到一个问题,假如波形持续时间超过40个单位时长了呢?于是我就想创建一个字符串,这样波形持续时间就可以变长变短了。
char* arr="110100" void Waveform(char* arr) //以51举例,直接操作对应引脚 { while(*arr!='\0') { P1^1=*(arr++)-48;//因为*之后出来的是ASCII的值,字符'0'对应48 delay(1); } } void main() { Waveform(arr); while(); }
但是还是有问题,这个delay的延时只有一个单位周期,而且如果波形持续时间过长,这个字符串必然很长。我们是不是可以尝试改变,如果波形不变化就持续延时。这样,我就要知道一个概念,一个波形的产生需要的要素。第一个是起始电平,第二个是波形持续时间,只需要在这个持续的时间到了就翻转电平即可。
虽说如此,写程序的时候,你会发现如果我高电平要持续10个单位周期,低电平需要5个。这个怎么表示呢?这个也很好解决,利用ASCII码表。因为“空格”的ASCII值是32,而空格之前的值我们无法打印,于是我们以空格为起始值进行创建函数。
char* arr="1! !";//首元素表示起始电平,之后的符号表示持续时间 void Waveform(char* arr) //以51举例,直接操作对应引脚 { int x; P1^1=*(arr++)-48; while(*arr!='\0') { x=*(arr++)-31;//因为空格为32 delay(x); P1^1=~P1^1;//注意:在整个函数结束的时候,引脚电平为结束电平的相反 } } void main() { Waveform(arr); while(); }
但是这样依然有问题,因为ASCII码表仅仅有127个字符,假如我的波形是1个单位周期的低电平,199个单位周期的高电平怎么办呢?于是,我想到了动态内存管理,这样有效的解决了如果高低电平单位周期持续时间过长,但是ASCII码表不足的问题。
可是在写程序的时候,我想到了一个问题,如何把数据简单直观的写入这串刚开辟的内存空间呢?
#define num 5 //表示波形变化次数,如果波形变化四次,num就是5,因为第一个要预留给起始电平 #define Type int //为防止电平持续时间过长,一个字节存放不下,就用int。此处可改为char void Waveform(Type* arr) //以51举例,直接操作对应引脚 { int x,j=num; P1^1 = *(arr++); //引脚为起始电平 while (--j) { x = *(arr++); //读取电平持续时间 delay(x); P1^1=~P1^1; } } void main() { int* ptr = NULL; ptr = (int*)malloc(num*sizeof(Type)); if (NULL != ptr) //判断ptr指针是否为空 { int i = num; *ptr = 1; //将起始电平写入 /*********** 将电平持续时间写入,这里是个麻烦事情 ***********/ } Waveform(ptr); free(ptr);//释放ptr所指向的动态内存 ptr = NULL; while(1); }
通过上面这串代码,我们发现将电平持续时间写入比较麻烦。而且,程序难度较大,在大规模的工程中,如果忘记释放申请的空间和没有把ptr置为空指针,会出现问题(具体问题百度)。
那么,有没有那种既简单,长度,数据类型可变换的方案呢?有!而且很简单,就是我们一开始讲的数组,在我们建立数组的时候,我们不要往里面一开始就规定数组大小。即 arr【】,里面不写入数据。
但是,写程序的时候,依然有问题。什么问题呢?就是我们的Waveform函数不知道数组的大小,应该什么时候截止。那么我们就可以在数组的首元素写好波形变换次数就行。现在,我们可以确认好数组的组成了,首元素是波形变换次数,第二个元素是波形起始电平。之后的就是波形持续时间。
#define Type int //方便修改之后要变换的存储类型 Type arr[] = { 3, 1, 2, 1, 1 }; //电平翻转3次,起始电平为1,持续时间分别为2,1,1个时间周期 void Waveform(Type* arr) //以51举例,直接操作对应引脚 { Type x,j;//x存放电平情况,j存放电平翻转次数 j = *(arr++); P1^1 = *(arr++); //起始电平 while (j--) { x = *(arr++); delay(x); P1^1=~P1^1; } } void main() { Waveform(arr); while(1); }
以上函数已具备无规律性和通用性。我们只需要更改arr这个数组里面的值,即可创立一个可变的随机波形。