首页 > 其他分享 >PPM协议的输出实现

PPM协议的输出实现

时间:2024-03-31 11:11:06浏览次数:11  
标签:count 输出 协议 0.5 PPM 2000 ms pwm mod

关于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信号了。

image

代码

点击查看代码
//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;

	}


}

标签:count,输出,协议,0.5,PPM,2000,ms,pwm,mod
From: https://www.cnblogs.com/MoQinglan/p/18106429

相关文章

  • C语言——倒序输出一个整数【字符篇】
    上次我们讲了如何使用数组方法倒序输出一个整数,在我们往期的学习中,我们知道,字符串可以实现很多数组类似的操作效果,那么,如何使用它来达到我们的目的呢?在C语言中,可以使用 strrev 函数直接实现倒序输出字符串。 strrev 函数用于反转字符串。使用该函数前需要包含头文件<st......
  • 输入输出-中断-总线-可靠性
    输入输出技术计算机系统中存在多种内存与接口地址的编制方式,常见的是下面两种:内存与接口地址独立编址方法内存地址和接口地址是两个完全独立的两个地址空间。访问数据时所使用的指令也完全不同,用于接口的指令只用于接口的读/写,其余的指令全都是用于内存的。因此,在编程序或......
  • 【BlossomRPC】如何自定义一个RPC协议?
    文章目录如何设计一个RPC协议?RPC项目配置中心项目网关项目如何设计一个RPC协议?在上面的需求描述中我们知道,RPC非常重要的一环,就是自己制定符合自己需求的通信协议,这里,我简单的列出了我的协议。publicclassRpcHeaderimplementsSerializable{//publicst......
  • 【BlossomRPC】手把手教你写一个RPC协议
    文章目录新的开始什么是RPC?设计一个RPC需要些什么?新的开始经常会遇到一些项目,看着看着就发现看不懂文档了,也就是会出现一些跳过讲解的文章,使得自己很难了解某种中间件的开发全貌,所以想着自己先设计一个比较简易的RPC框架,在实现所有功能的前提下,向公司内部的技术分享......
  • 绚烂之境:Python Rich,让终端输出更炫酷!
    转载请注明出处❤️作者:测试蔡坨坨原文链接:caituotuo.top/c8c7bd95.html初识rich你好,我是测试蔡坨坨。在代码的世界里,每一行都是一个故事,每一个变量都是一个角色,而打印则是展示这些故事与角色的窗口。然而,这个窗口并非都是朴实无华的,有时候,我们需要一种更加「艺术」的方式来展......
  • SPI通信协议详解
    文章目录介绍SPI硬件电路移位示意图SPI时序开始与结束时序单元交换字节时序单元模式0(最常用)模式1模式2模式3发送时序指定地址写指定地址读介绍SPISPI由时钟线、主机发送线、主机接收线、从机选择线(一个或多个)组成,拥有高速的速率,使用比较简单,但是需要的线更多,更容......
  • Java基础 TCP协议下,收发数据代码实现
     --------------------------------------------------------------------------------------------------------------------------------- 代码实现:1.发送数据:publicstaticvoidmain(String[]args)throwsException{//1.创建Socket对象。细节:在创建对象的同......
  • c语言:用do-while输出前40项的斐波那契数值
    求Fibonacci数列的前40个元素。该数列的特点是第1、2两个数为1、1。从第3个数开始,每数是其前两个数之和。  分析:从题意可以用如下等式来表示斐波那契数列:     1,1,2,3,5,8,13,21…     f1=1     (n=1)     f2=1   ......
  • 输出所有可能的栈的合法出栈序列
    voidlegalstack(tack*st,intin[],intout[],intlen,inti,intj){ intx; staticintnum=1; if(empty(st)&&j>=len) { cout<<"第"<<num++<<"种:"; for(inti=0;i<len;i++) { ......
  • mount命令输出中每行的格式及其表示意义
     本文结构:a、原图展示b、格式说明c、各部分详解d、注意 a、原图 b、格式:<设备名>on<挂载点>type<文件系统类型>[<挂载选项>]c、各部分的表示意义:<设备名>:这表示已挂载设备的名称或标识符。对于硬盘分区,它可能是像/dev/sda1这样的设备文件;对于网络文件系统(如......