单片机模拟输出PPM信号
PPM信号就是将多个PWM信号放在一起传输,一个PPM的周期为20ms,其中一个通道信号的范围为1~2ms,所以一个PPM信号,最多可以传输10个通道的PWM信号。
PPM信号以0.5ms的低电平信号代表一个通道的起始信号,其后的高电平信号,范围在0.5~1.5ms,代表该通道的PWM占空比。
- 占空比为0,高电平0.5ms
- 占空比50%,高电平信号1ms
- 占空比100%,占空比1.5ms
在所有的通道信号结束之后,用一个0.5ms的低电平信号,代表结束。此时,时间未满20ms的,剩下时间用高电平填充。
明白了原理,我们就思考一下,用单片机怎么模拟输出?
首先采用定时器,在定时中断时去改变PPM输出引脚的电平状态。且在中断发生时,改变定时器的重装载值,也就是改变这个电平信号的持续时间。下面,我以GD32F130单片机来模拟输出四通道的PPM信号。
//定时器初始化与PPM输出引脚初始化
void ppm_init(void)
{GPIO_InitPara GPIO_InitStructure;TIMER_BaseInitPara TIMER_BaseInitParaStructure;NVIC_InitPara NVIC_InitStructure;RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOF,ENABLE);RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER2,ENABLE);GPIO_InitStructure.GPIO_Pin = PPM_Out_Pin ;GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_NOPULL;GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;GPIO_Init(GPIOF,&GPIO_InitStructure );TIMER_DeInit(TIMER2);TIMER_BaseInitParaStructure.TIMER_Prescaler = 72-1; /* 1MHz */TIMER_BaseInitParaStructure.TIMER_CounterMode = TIMER_COUNTER_UP;TIMER_BaseInitParaStructure.TIMER_Period = 500-1; /* 500*1MHz = 500us */TIMER_BaseInitParaStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;TIMER_BaseInit(TIMER2,&TIMER_BaseInitParaStructure); TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);TIMER_INTConfig(TIMER2, TIMER_INT_UPDATE, ENABLE);NVIC_InitStructure.NVIC_IRQ = TIMER2_IRQn;NVIC_InitStructure.NVIC_IRQPreemptPriority = 6;NVIC_InitStructure.NVIC_IRQSubPriority = 0;NVIC_InitStructure.NVIC_IRQEnable = ENABLE;NVIC_Init(&NVIC_InitStructure);TIMER_Enable(TIMER2,ENABLE);PPM_Out_L//输出低电平}
GD32F130的定时器2时钟是72MHz的 ,所以将其72分频,获得1MHz的时钟,即每记一个数,就是1us。
TIMER_BaseInitParaStructure.TIMER_Prescaler = 72-1; /* 1MHz */
前面,我们说过,通道起始是一个0.5ms的低电平信号,所以,首先输出一个低电平,在定时500u中断发生后去改变它的状态。
下面是定时中断函数
//输出PPM信号
u8 ppm_count=1; //步骤计数
u16 toal_time=0;//总的通道高电平时间
extern u16 ppm_data[4];//通道摇杆的AD采样数据
void TIM2_IRQHandler(void)
{float time;TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);switch(ppm_count){case 1://第一通道开始 -----------------------------(1)PPM_Out_Htime=((float)ppm_data[0]/819.0)*200+499;//(通道高电平时间在500us~1500us)toal_time+=time;TIMER_SetAutoreload(TIMER2,(u32)time);ppm_count++;break;case 2://第一通道结束,开始0.5ms低电平---------------(2)PPM_Out_LTIMER_SetAutoreload(TIMER2,499);ppm_count++;break;case 3://第二通道开始------------------------------(3)PPM_Out_Htime=((float)ppm_data[1]/819.0)*200+499;toal_time+=time;TIMER_SetAutoreload(TIMER2,(u32)time);ppm_count++;break;case 4://第二通道结束,开始0.5ms低电平PPM_Out_LTIMER_SetAutoreload(TIMER2,499);ppm_count++;break;case 5://第三通道开始PPM_Out_Htime=((float)ppm_data[2]/819.0)*200+499;toal_time+=time;TIMER_SetAutoreload(TIMER2,(u32)time);ppm_count++;break;case 6://第三通道结束,开始0.5ms低电平PPM_Out_LTIMER_SetAutoreload(TIMER2,499);ppm_count++;break;case 7://第四通道开始PPM_Out_Htime=((float)ppm_data[3]/819.0)*200+499;toal_time+=time;TIMER_SetAutoreload(TIMER2,(u32)time);ppm_count++;break;case 8://第四通道结束,开始0.5ms低电平---------------(4)PPM_Out_LTIMER_SetAutoreload(TIMER2,499);ppm_count++;break;case 9://四路信号结束,20ms剩下的时间高电平----------(5)PPM_Out_Htime=17500-toal_time;TIMER_SetAutoreload(TIMER2,time);ppm_count++;break;case 10://重新开始---------------------------------(6)PPM_Out_LTIMER_SetAutoreload(TIMER2,499);toal_time=0;//通道高电平清零,重新开始ppm_count=1;}}
- 第一通道的起始信号0.5ms低电平结束,根据摇杆通道的AD采样值去计算第一通的高电平时间,GD32F130的ADC是12位的,若摇杆打到最高,采样值为4095,根据前面所说的PPM对应高电平应该为1.5ms,所以Time=(采样值/4095)*1000+499,程序里化简了。累加通道高电平时间,便于最后计算剩下的高电平时间。调用TIMER_SetAutoreload(TIMER2,(u32)time)改变定时器重装载值,步骤计数加一。
第一通道结束,开始0.5ms的第二通道起始信号
同1,计算通道二的高电平时间。
四个通道都结束了,以一个0.5ms的低电平时间结束。
计算剩下的高电平时间,因为一共四通道,所以四个0.5ms的通道起始信号,加上最后一个0.5ms的结束信号,20ms还剩下17.5ms,减去四个通道的高电平累加时间,就是最后的高电平时间
一个ppm信号结束了,重新开始下一个新的PPM信号。
以上仅为个人理解,实践使用该程序,可以玩凤凰模拟器。如有错误,请指正。
单片机模拟输出PPM信号相关推荐
- 51单片机实现类似于Arduino中micros()、millis()函数功能并用于接收ppm信号
最近想要给小车添加航模遥控器遥控功能,毕竟航模遥控器拿在手里还是很有质感,手感很不错的.选择使用ppm信号,ppm信号相关参考:PPM相关 Arduino中micros()函数返回一个单位为无符号长整 ...
- STM32F030F4P6 HAL库 PPM信号输出 24L01 PPM接收机制作
事件起因 因为给PX4测试缺少遥控器,手撸了一套支持PPM的遥控器系统,这篇文章将在接收机上遇到的问题分享一二,供大家借鉴. 1.需求分析 接收机需要输出至少8通道的PPM信号,可以将*通PPM信号分 ...
- STM32解析航模遥控器的PPM信号
一.前言 通常遥控器能输出i-BUS.s-BUS.PPM.PWM信号,其中i-BUS.s-BUS需要配套的电平反向器(硬件取反),PWM信号占用引脚较多,对比而言PPM信号使用起来更为方便. 航模遥控 ...
- STM32 通过定时器产生PPM信号
标题STM32 通过定时器产生PPM信号 说明: 该代码基于STM32F103VET6 和STD标准库实现.若需要在其他单片平台使用需要调整IO,和定时器,底层代码. 定时器要达到us级定时. 实现原 ...
- 【011】基于51单片机的低频信号发生proteus仿真与实物设计
一.资料内容 (1).基于51单片机的低频信号发生proteus仿真设计一份: (2).基于51单片机的低频信号发生proteus仿真设计keli源代码一份: (3).基于51单片机的低频信号发生A ...
- STM32 四轴无人机设计——遥控器PPM信号
1.前言 由于时间原因,我使用的遥控器是直接买的成品,富斯I6x+IA6B接收机,据说是一代神控,富斯的遥控器总共有ibus模式.sbus模式.PPM模式.我使用的是PPM模式. 2.什么是PPM P ...
- 单片机采集电压信号(AD转换器的应用实例)上
单片机采集电压信号(AD转换的应用实例)上 上一篇文章我们讲了如何把一个信号的峰值采集,今天我们来讲如何把它连入单片机上,这里我们采用的是Multisim仿真. 我们都知道单片机采集的信号都是高电平和 ...
- 舵机PWM,SBUS,PPM信号转模拟电压的方案
PWM,SBUS,PPM信号转模拟电压的方案 -----------------本文由"麦粒电子"撰写,并提供相应产品服务和交流.---------------- 案例场景 有个内 ...
- PWM,SBUS,PPM信号转模拟电压的方案
PWM,SBUS,PPM信号转模拟电压的方案 -----------------本文由"麦粒电子"撰写,并提供相应产品服务.---------------- 案例场景 有个内部采用 ...
最新文章
- TinyML-TVM是如何驯服Tiny的(上)
- 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)
- 352. Data Stream as Disjoint Intervals
- 北邮OJ 1022. 16校赛-Saber's Board
- leetcode 62, 63, 980. Unique Paths I, II, III | 62, 63, 980. 不同路径 I, II, III(暴力递归->傻缓存->动态规划)
- python数据库sqlite3_Python数据库之SQLite3
- PetShop4.0--转载
- 云小课|打造企业数据“高内聚,低耦合”--试试GaussDB(DWS)逻辑集群,实现数据物理隔离
- c语言api文档_初学 C 语言没有项目练手?这 20 个小项目拿走不谢
- CentOS设置静态IP
- 瑞利衰落(Rayleigh Fading)
- maven 部署及使用
- qq2008珊瑚虫版SL
- winrar64位怎么破解
- Kafka常见面试题
- 海信电视怎么删除自带应用
- 7-9 打印倒直角三角形图形
- 用Unison实现数据的双向实时同步
- 《Openwrt开发》第四章:newifi3 实现内网穿透(n2n)
- 便捷缴费 支付 (一)