PPM协议的输出实现

关于PPM输出的具体实现我们必然先知道其原理,本人是参考站内qiyuexin大佬的PPM 信号解析这篇文章。

基本要点

1.ppm每个通道所占用的时间并不固定
2.ppm的精度主要受制于时钟精度
3.对于一个通道数据每次开头都有0.5ms的固定低电平,之后跟着0.5ms的固定的高电平,之后是0 - 1ms的数据长度。也就是说每个数据之间没有固定的时间间隔,上一个数据结束后就是下一个通道的数据。
4.ppm一般10个控制通道,每帧的长度是固定的20ms。

具体实现

通过定时器产生一个10us的中断事件,在中断内进行计数,计数到2000即20ms代表已经完成1个数据帧。
pwm_count 0 -> 2000时表示计数了一个数据帧
这里笔者犹豫了一段时间,最后决定既然每个通道都有固定的0.5ms的固定低电平,和0.5ms的固定的高电平,那就直接把他做成一个固定的片段,在输出时候先进行此片段,之后紧跟着就是数据便可。于是我们创建了一个名为mod的变量,mod = 0时执行通道开头的0.ms低和0.5ms高,mod = 1时是数据。
对于数据,因为本身就在一个循环之中,只要一直if(count <= PPM_out[1])就可以,输出完一个通道之后cnt++,下一次循环输出的就是就是PPM_out[2]的数值了。
`

if (mod == 0)//开始信号
{
	if(count <= 50)	//0.5m 低电平表示通道起始信号
	{
		PPM_out_pin_reset;
	}
	else if(count > 50 && count <= 100)	//0.5m 高电平数据起始信号
	{
		PPM_out_pin_set;

	}
	else
	{
		count = 0;
		mod = 1;//进入数据时间
	}

}else if (mod == 1)
{
	if(count <= PPM_out[cnt])	//0.5m 低电平表示通道起始信号
	{
		PPM_out_pin_set;//数据
	}
	else
	{
		count = 0;
		mod = 0;//进入数据时间
		cnt ++;			
		if (cnt > 9)
		{
			mod = 2;
		}


	}
}

`

之后一直循环到数据都输出完成时,mod = 2来保持之后的高电平(引导或称结束脉冲),在循环到pwm_count = 2000,一帧完成之后对所有的计数器进行清零。

`

if(pwm_count==2000)//对计数进行复位
{
	pwm_count = 0;
	cnt = 0;
	mod = 0;

}

`
至此已经能输出正确的pwm信号了。

代码

点击查看代码
//2000 -> 20ms
//200  -> 2ms
//100  -> 1ms
//50   -> 0.5ms
//1    -> 0.01ms
u16 count=0;
u16 pwm_count=0;	//总计数 周期20ms,10us进次
unsigned char mod = 0;
unsigned char cnt = 0;

void PPM_loop(void)//1us进来1次
{

	pwm_count++;

	count++;
	if (mod == 0)//开始信号
	{
		if(count <= 50)	//0.5m 低电平表示通道起始信号
		{
			PPM_out_pin_reset;
		}
		else if(count > 50 && count <= 100)	//0.5m 高电平数据起始信号
		{
			PPM_out_pin_set;

		}
		else
		{
			count = 0;
			mod = 1;//进入数据时间
		}

	}else if (mod == 1)
	{
		if(count <= PPM_out[cnt])	//0.5m 低电平表示通道起始信号
		{
			PPM_out_pin_set;//数据
		}
		else
		{
			count = 0;
			mod = 0;//进入数据时间
			cnt ++;
			if (cnt > 9)
			{
				mod = 2;
			}

		}
	}

	if(pwm_count==2000)//对计数进行复位
	{
		pwm_count = 0;
		cnt = 0;
		mod = 0;

	}


}

热门相关:美食萌后:皇上,休了你   我在镇夜司打开地狱之门   锦绣田园:医女嫁贤夫   误踩老公底线:甜心难招架!   九阳剑圣