0
点赞
收藏
分享

微信扫一扫

无规则波形发生函数


       

无规则波形发生函数_单片机

如题需要产生一个无规则,通用性的波形函数。

先讲最优解,方便复制就跑。不着急的兄弟可以看一下我的解题思路。

#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};//后面的就不写了

 注:全文波形以前面这部分为例子

无规则波形发生函数_单片机_02

 有了数组之后再创建一个函数,传入数组首元素地址,每隔一个单位时长根据数组内容翻转电平。

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这个数组里面的值,即可创立一个可变的随机波形。

举报

相关推荐

0 条评论