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;}}
  1. 第一通道的起始信号0.5ms低电平结束,根据摇杆通道的AD采样值去计算第一通的高电平时间,GD32F130的ADC是12位的,若摇杆打到最高,采样值为4095,根据前面所说的PPM对应高电平应该为1.5ms,所以Time=(采样值/4095)*1000+499,程序里化简了。累加通道高电平时间,便于最后计算剩下的高电平时间。调用TIMER_SetAutoreload(TIMER2,(u32)time)改变定时器重装载值,步骤计数加一。
  2. 第一通道结束,开始0.5ms的第二通道起始信号

  3. 同1,计算通道二的高电平时间。

  4. 四个通道都结束了,以一个0.5ms的低电平时间结束。

  5. 计算剩下的高电平时间,因为一共四通道,所以四个0.5ms的通道起始信号,加上最后一个0.5ms的结束信号,20ms还剩下17.5ms,减去四个通道的高电平累加时间,就是最后的高电平时间

  6. 一个ppm信号结束了,重新开始下一个新的PPM信号。

以上仅为个人理解,实践使用该程序,可以玩凤凰模拟器。如有错误,请指正。

单片机模拟输出PPM信号相关推荐

  1. 51单片机实现类似于Arduino中micros()、millis()函数功能并用于接收ppm信号

    最近想要给小车添加航模遥控器遥控功能,毕竟航模遥控器拿在手里还是很有质感,手感很不错的.选择使用ppm信号,ppm信号相关参考:PPM相关 Arduino中micros()函数返回一个单位为无符号长整 ...

  2. STM32F030F4P6 HAL库 PPM信号输出 24L01 PPM接收机制作

    事件起因 因为给PX4测试缺少遥控器,手撸了一套支持PPM的遥控器系统,这篇文章将在接收机上遇到的问题分享一二,供大家借鉴. 1.需求分析 接收机需要输出至少8通道的PPM信号,可以将*通PPM信号分 ...

  3. STM32解析航模遥控器的PPM信号

    一.前言 通常遥控器能输出i-BUS.s-BUS.PPM.PWM信号,其中i-BUS.s-BUS需要配套的电平反向器(硬件取反),PWM信号占用引脚较多,对比而言PPM信号使用起来更为方便. 航模遥控 ...

  4. STM32 通过定时器产生PPM信号

    标题STM32 通过定时器产生PPM信号 说明: 该代码基于STM32F103VET6 和STD标准库实现.若需要在其他单片平台使用需要调整IO,和定时器,底层代码. 定时器要达到us级定时. 实现原 ...

  5. 【011】基于51单片机的低频信号发生proteus仿真与实物设计

    ​一.资料内容 (1).基于51单片机的低频信号发生proteus仿真设计一份: (2).基于51单片机的低频信号发生proteus仿真设计keli源代码一份: (3).基于51单片机的低频信号发生A ...

  6. STM32 四轴无人机设计——遥控器PPM信号

    1.前言 由于时间原因,我使用的遥控器是直接买的成品,富斯I6x+IA6B接收机,据说是一代神控,富斯的遥控器总共有ibus模式.sbus模式.PPM模式.我使用的是PPM模式. 2.什么是PPM P ...

  7. 单片机采集电压信号(AD转换器的应用实例)上

    单片机采集电压信号(AD转换的应用实例)上 上一篇文章我们讲了如何把一个信号的峰值采集,今天我们来讲如何把它连入单片机上,这里我们采用的是Multisim仿真. 我们都知道单片机采集的信号都是高电平和 ...

  8. 舵机PWM,SBUS,PPM信号转模拟电压的方案

    PWM,SBUS,PPM信号转模拟电压的方案 -----------------本文由"麦粒电子"撰写,并提供相应产品服务和交流.---------------- 案例场景 有个内 ...

  9. PWM,SBUS,PPM信号转模拟电压的方案

    PWM,SBUS,PPM信号转模拟电压的方案 -----------------本文由"麦粒电子"撰写,并提供相应产品服务.---------------- 案例场景 有个内部采用 ...

最新文章

  1. TinyML-TVM是如何驯服Tiny的(上)
  2. 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)
  3. 352. Data Stream as Disjoint Intervals
  4. 北邮OJ 1022. 16校赛-Saber's Board
  5. leetcode 62, 63, 980. Unique Paths I, II, III | 62, 63, 980. 不同路径 I, II, III(暴力递归->傻缓存->动态规划)
  6. python数据库sqlite3_Python数据库之SQLite3
  7. PetShop4.0--转载
  8. 云小课|打造企业数据“高内聚,低耦合”--试试GaussDB(DWS)逻辑集群,实现数据物理隔离
  9. c语言api文档_初学 C 语言没有项目练手?这 20 个小项目拿走不谢
  10. CentOS设置静态IP
  11. 瑞利衰落(Rayleigh Fading)
  12. maven 部署及使用
  13. qq2008珊瑚虫版SL
  14. winrar64位怎么破解
  15. Kafka常见面试题
  16. 海信电视怎么删除自带应用
  17. 7-9 打印倒直角三角形图形
  18. 用Unison实现数据的双向实时同步
  19. 《Openwrt开发》第四章:newifi3 实现内网穿透(n2n)
  20. 便捷缴费 支付 (一)

热门文章

  1. CSS单位中px、en和rer的区别?
  2. Android 关于display的几个问题
  3. STAT0023 STATISTICS FOR PRACTICAL COMPUTING
  4. 网工必备工具软件——一看就懂,一听就会,一做就废
  5. pitfall override private method
  6. 加权均值滤波matlab,模糊加权均值滤波器
  7. 解决java中使用getImage()导入图片失败问题
  8. 科学研究是有闲人群的玩艺———读爱因斯坦的短文有感
  9. 青山绿水 峡谷奇观---野三坡之行(转)
  10. 不可不知的CPU风扇清理技巧