一、前言

  • 通常遥控器能输出i-BUS、s-BUS、PPM、PWM信号,其中i-BUS、s-BUS需要配套的电平反向器(硬件取反),PWM信号占用引脚较多,对比而言PPM信号使用起来更为方便。
  • 航模遥控器性能强大,深受DIY用户的热爱,考虑到目前针对PPM信号解析的文章较少,本文将对其进行探讨。

二、文章实验器材展示

  • 本人采用【FS-i6X航模遥控器】来完成本实验。
  • 本实验中,遥控器的输出为6通道

三、使用逻辑分析仪读取的PPM信号

  • 本人将遥控器配置成了6通道的输出模式,以下截图为读取到的一帧数据。

  • 从下面这张大的截图中,我们可以发现规律:在每一帧数据之间会有一段较长的上升沿,这段上升沿的持续时间会波动,持续时间通常在8000微秒左右;紧接着,后面会产生8次上升沿,其中前面的6次分别对应着6个通道的输出,关于最后2个上升沿本人也不太清楚(不影响后续工作)。

  • 上述两张关于PPM信号报文的规律将成为编程的依据。

四、STM32定时器的输入捕获功能

  • 要想实现对PPT信号的采集处理,最重要的就是读取每一次上升沿的持续时间,这里要用到的就是定时器的输入捕获功能。

定时器配置为输入捕获示例程序:

//定时器5通道2输入捕获配置TIM_ICInitTypeDef  TIM5_ICInitStructure;void TIM5_Cap_Init(u16 arr,u16 psc)
{    GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);    //使能TIM5时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;  //PA1 清除之前设置  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA1 输入  GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_ResetBits(GPIOA,GPIO_Pin_1);                      //PA1 下拉//初始化定时器5 TIM5  TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc;   //预分频器   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位//初始化TIM5输入捕获参数TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01   选择输入端 IC1映射到TI1上TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;   //上升沿捕获TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;    //配置输入分频,不分频 TIM5_ICInitStructure.TIM_ICFilter = 0x0a;//IC1F=0000 配置输入滤波器 不滤波TIM_ICInit(TIM5, &TIM5_ICInitStructure);//中断分组初始化NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允许更新中断 ,允许CC2IE捕获中断 TIM_Cmd(TIM5,ENABLE );  //使能定时器5
}

定时器中断服务函数

u8  TIM5CH1_CAPTURE_STA=0;  //输入捕获状态
u16 TIM5CH1_CAPTURE_VAL;    //输入捕获值
u16 remote_control_value[9];//定时器5中断服务程序
void TIM5_IRQHandler(void)
{ if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获   {     if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)        {      if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了{if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了{TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次TIM5CH1_CAPTURE_VAL=0XFFFF;}else TIM5CH1_CAPTURE_STA++;}     }if (TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//捕获1发生捕获事件{  if(TIM5CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿      {               TIM5CH1_CAPTURE_STA|=0X80;     //标记成功捕获到一次上升沿TIM5CH1_CAPTURE_VAL=TIM_GetCapture2(TIM5);TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC2P=0 设置为上升沿捕获}else                                 //还未开始,第一次捕获上升沿{TIM5CH1_CAPTURE_STA=0;         //清空TIM5CH1_CAPTURE_VAL=0;TIM_SetCounter(TIM5,0);TIM5CH1_CAPTURE_STA|=0X40;       //标记捕获到了上升沿TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling);      //CC2P=1 设置为下降沿捕获}         }                                              }TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位}

五、PPM信号的解析

主函数的处理过程如下:

int main(void){      delay_init();            //延时函数初始化    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);  //串口初始化为115200LED_Init();               //LED端口初始化TIM3_PWM_Init(20000-1,72-1);         //不分频。PWM频率=72000/(899+1)=80KhzTIM5_Cap_Init(0XFFFF,72-1);   //以1Mhz的频率计数 while(1){if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿{temp=TIM5CH1_CAPTURE_STA&0X3F;temp*=65536;//溢出时间总和temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间printf("HIGH:%d us\r\n",temp);//打印总的高点平时间if(temp > 3000){flag_i = 0;       flag_k = 0;}   if(flag_i == 0){remote_control_value[flag_k] = temp;flag_k = flag_k + 1;if(flag_k == 9){flag_i = 1;actual_ch_value[1] = remote_control_value[5];actual_ch_value[2] = remote_control_value[1];actual_ch_value[3] = remote_control_value[6];actual_ch_value[4] = remote_control_value[2];actual_ch_value[5] = remote_control_value[7];actual_ch_value[6] = remote_control_value[3];             }                       }               TIM5CH1_CAPTURE_STA=0;//开启下一次捕获}}}

六、实验效果展示

  • 在线调试截图

  • 实物展示

七、疑问

STM32解析航模遥控器的PPM信号相关推荐

  1. 用stm32读取遥控器接收机PPM信号各通道值

    引言 无人机遥控器接收机接收方式可以在遥控上设置成PPM模式和S.BUS模式,用示波器观察接收机信号输出引脚可以得到一系列的方波,很像PWM方波,而我们所需要的是七,八个或更多的通道信号,多路的PWM ...

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

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

  3. STM32 四轴无人机的设计——处理遥控器PPM信号

    1.前言 上一次我们已经成功接收并储存了从遥控器发送的PPM信号,但是你们知道遥控器的哪个通道对应PPM信号的哪一帧吗?没关系,我知道,哈哈,我自己测量了一下,将对应通道的数据帧位置统计了出来. 2. ...

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

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

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

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

  6. 《手把手教你学嵌入式无人机》——2.航模遥控器通信协议

    一.接收机的使用 接收机可以直接用来控制舵机.电调(有刷或无刷),同时也可以通过特定的通信协议与单片机通信,单片机再进行对外围设备的控制. 实事上,舵机.电调内部也都有单片机,接收机控制舵机.电调也是 ...

  7. STM32 NEC红外遥控器解码

    STM32 NEC红外遥控器解码 红外遥控编码格式 一体化红外接收头 STM32显示遥控器按下的数字代码 代码片 总结 原文链接:https://www.yourcee.com/newsinfo/29 ...

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

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

  9. 开源自制的6通道航模遥控器(一) 超简单不超过100行代码

    前言 前段时间跟着LOLI大神的教程制作了LOLI三代控,效果很好.但是,由于LOLI三代控的接收机带有数据回传功能,也就是接收机的无线模块也承担了发射数据功能,所以接收机也要使用带有功率放大芯片的N ...

最新文章

  1. ofbiz之entity 实体解析 扩展 视图 复合列写法
  2. 《3D数学基础》系列视频:这次,真的是广告!
  3. 多解决些问题,少谈些框架和流程
  4. python numpy.arange() 函数的使用方法 (在给定间隔内返回均匀间隔的值)
  5. Android之如何解决Android Studio左边的的project不见了
  6. 记录奥运-当今五大Java记录框架之间的竞赛
  7. 【2016年第6期】面向国际的生命组学大数据管理体系建设
  8. SQL中 Left Join 与 Right Join 与 Inner Join 与 Full Join的区别
  9. cesium3dtiles位置改变
  10. mysql表死锁查询
  11. APICloud连接夜神模拟器--博客园老牛大讲堂
  12. ServletConfig对象--配置初始化参数以及获取初始化参数
  13. 伺服电机转矩常数的标定方法
  14. HTTPs SSL OV、DV和EV证书的区别
  15. windows消息机制
  16. 关于ping命令出现大量dup原因
  17. IE-LAB网络实验室:华为AAA认证详解
  18. 【go-zero】go-zero开发环境 如何聚合所有api? caddy反向代理服务分发 微服务设计api聚合方法 best practice
  19. 用python简易英汉互译界面_python之做一个简易的翻译器(一)
  20. 黑马程序员——ios面试学习一:Mac系统使用教程——黑马 ios 技术博客

热门文章

  1. windows 组播收不到消息_只需2步,轻松解决登录微信电脑版后,手机收不到消息提醒的问题...
  2. 一个可以提升180%推广效果的信息流广告投放策略
  3. slam十四讲,ch5joinmap报错,已解决
  4. 网页内嵌的视频添加 vtt 外挂字幕
  5. python 下载qq群文件_利用多线程快速下载腾讯QQ群文件的方法
  6. k8s之亲和性、反亲和性
  7. Filling the Gaps: Multivariate Time Series Imputation by Graph Neural Networks
  8. 论文笔记:Mind the Gap An Experimental Evaluation of Imputation ofMissing Values Techniques in TimeSeries
  9. 01 数据库和MySQL简介
  10. CollapsingToolbarLayout用法详解(简洁易懂)