济南电子爱好者 发表于 2012-7-7 21:41:46

51单片机解码PPM波

本帖最后由 济南电子爱好者 于 2012-7-7 21:50 编辑

      好久没有来论坛了,这段时间一直在学习USB方面的应用和开发。制作四轴被耽搁了下来。今天利用空余的时间看了下PMM波相关的程序,结合论坛里的程序。利用51单片机成功解码PPM波。
这是我是CY7C68013ADIY的逻辑分析仪采集的冠丽四通控的PPM波,预留两通没有使用。

先说说PPM波,从图上可以看出周期为20ms,冠丽控实际是6通控,但预留两通没有使用。通道的高电平区间为0.765~1.6ms低电平时间为0.395ms
引导波形的高电平 时间为10.165ms。


我的单片机是 11.0592MHZ   这样算的话,显示的值 应该是706到1491之间,中立位为   1100正好和理论值相符。
这里在提点单片机相关的知识,51单片机是低电平触 发中断,我这里用的是while(int0==0)来等待高电平 的到来。不知道这样做是否合理,不过实践看来还是可以的。
这里我发程序打包发上来,大家要顶啊。

teraxion 发表于 2012-10-16 21:39:56

好东西必须顶!

fengyiyu1006 发表于 2012-10-16 22:54:31

同分享一个stm32的解码程序,自己写的,但是目前还之能解一个通道,大家可以一起完善……

中断配置
    NVIC_InitTypeDef NVIC_InitStructure;

      NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; //设TIM2输入捕获中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   //配置优先级组
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 10;

TIM配置(用的是TIM2)
      TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
      TIM_ICInitTypeDefTIM_ICInitStruct;

      TIM_TimeBaseInitStruct.TIM_Period      = 0xffff;            // 计数上限为最大
    TIM_TimeBaseInitStruct.TIM_Prescaler   = 72;             // 计数器频率
    TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;                   // 不分割
    TIM_TimeBaseInitStruct.TIM_CounterMode   = TIM_CounterMode_Up; // 向上计数
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct );          // 初始化TIM2的时基单元
    TIM_ITConfig(TIM2,TIM_IT_Update, DISABLE );
      TIM_ClearFlag(TIM2,TIM_FLAG_Update);

      TIM_ICInitStruct.TIM_Channel   = TIM_Channel_1;// 选择通道1
      TIM_ICInitStruct.TIM_ICPolarity= TIM_ICPolarity_Rising;      // 上升沿触发(根据示波器实验观察结果调整)
    TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;             // 每次检测到捕获输入就触发一次捕获
    TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;          // 通道方向选择
    TIM_ICInitStruct.TIM_ICFilter    = 0x5;
      TIM_ICInit(TIM2,&TIM_ICInitStruct );
      TIM_ITConfig(TIM2, TIM_IT_CC1, DISABLE );
      TIM_ClearFlag(TIM2,TIM_FLAG_CC1 );

中断函数
void TIM2_IRQHandler(void)
{
      TIM_ICInitTypeDefTIM_ICInitStruct;
      if(j==0)
       {
      j=1;
       TIM2->CNT = 0x00;
       TIM_ICInitStruct.TIM_Channel   = TIM_Channel_1;// 选择通道4
       TIM_ICInitStruct.TIM_ICPolarity= TIM_ICPolarity_Falling;      // 下降沿触发(根据示波器实验观察结果调整)
   TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;             // 每次检测到捕获输入就触发一次捕获
   TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;          // 通道方向选择
   TIM_ICInitStruct.TIM_ICFilter    = 0x5;
       TIM_ICInit(TIM2,&TIM_ICInitStruct );
       TIM_ClearFlag(TIM2,TIM_FLAG_CC1 );
       TIM_ITConfig(TIM2, TIM_IT_CC1,ENABLE);
       }
      else
      {
      j=0;
      buffer = TIM2->CNT;
      USART_SendData(USART1, buffer);
       TIM_ICInitStruct.TIM_Channel   = TIM_Channel_1;// 选择通道4
       TIM_ICInitStruct.TIM_ICPolarity= TIM_ICPolarity_Rising;      // 上升沿触发(根据示波器实验观察结果调整)
   TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;             // 每次检测到捕获输入就触发一次捕获
   TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;          // 通道方向选择
   TIM_ICInitStruct.TIM_ICFilter    = 0x5;
       TIM_ICInit(TIM2,&TIM_ICInitStruct );
       TIM_ClearFlag(TIM2,TIM_FLAG_CC1 );
       TIM_ITConfig(TIM2, TIM_IT_CC1,ENABLE);
      }

}

在主函数中:    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);      
                TIM_Cmd(TIM2,ENABLE);

小伙仔小明 发表于 2012-10-16 23:21:45

学习!顶…………

kjspace123 发表于 2012-11-27 09:49:39

顶啊 都是牛人

风起 发表于 2013-2-3 23:04:17

刚开始学习这方面的东西,如获至宝啊

00superman00 发表于 2013-2-4 20:14:41

PPM信号从哪里引出的

济南电子爱好者 发表于 2013-3-11 12:01:54

00superman00 发表于 2013-2-4 20:14 static/image/common/back.gif
PPM信号从哪里引出的

PPM是直接从摇控器中引出来的

hanshiruo 发表于 2013-3-11 12:49:43

好啊 顶

残忆视觉 发表于 2013-3-17 10:48:19

顶,好东西{:tongue:}

wangjt1988 发表于 2013-3-17 12:20:23

fengyiyu1006 发表于 2012-10-16 22:54 static/image/common/back.gif
同分享一个stm32的解码程序,自己写的,但是目前还之能解一个通道,大家可以一起完善……

中断配置


额...有这么复杂么....    PPM能解出一个通道,其他通道顺理成章都可以解出来啊

fengyiyu1006 发表于 2013-3-17 12:48:20

wangjt1988 发表于 2013-3-17 12:20 static/image/common/back.gif
额...有这么复杂么....    PPM能解出一个通道,其他通道顺理成章都可以解出来啊 ...

这是去年写的代码,当时刚接触ppm解码,现在可以读取所有通道的了
方法还是这种,中断和定时器

fengyiyu1006 发表于 2013-3-17 12:49:42

wangjt1988 发表于 2013-3-17 12:20 static/image/common/back.gif
额...有这么复杂么....    PPM能解出一个通道,其他通道顺理成章都可以解出来啊 ...

void ppm_isr()
{       
        if (ppm_step == 0)
        {
                TIM1->CCER &= 0XFFFD; //change to raising
          TIM1->CNT = 0;
          TIM1->SR &= 0XFFFC; //clear flag
                ppm_step = 1;
        }
        else if (ppm_step == 1)
        {
                TIM1->CCER |= 0X02; //change to falling
          buffer = TIM1->CNT;
          TIM1->SR &= 0XFFFC; //clear flag
                if (buffer < 2500)
                {
                  ppm_step = 0;
                }
                else
                {
                        TIM1->CNT = 0;
                        ppm_step = 2;                       
                        rt_mb_send(&mb_ppm, (rt_uint32_t)&start_ppm); //发送邮箱,告诉线程已经可以开始处理了
                }
        }
        else if (ppm_step == 2)
        {
                TIM1->CCER &= 0XFFFD; //change to raising
          channel = TIM1->CNT;
          TIM1->SR &= 0XFFFC; //clear flag
                ppm_step = 3;
                ppm_c++;
                if(ppm_c == 6)
                {
                        ppm_c = 0;
                        ppm_step = 0;
                        goto end;
                }
        }
        else if (ppm_step == 3)
        {
                TIM1->CCER |= 0X02; //change to falling
          TIM1->CNT = 0;
          TIM1->SR &= 0XFFFC; //clear flag
                ppm_step = 2;
        }
       
        end:__nop();
}

wangjt1988 发表于 2013-3-17 14:36:05

fengyiyu1006 发表于 2013-3-17 12:49 static/image/common/back.gif
void ppm_isr()
{       
        if (ppm_step == 0)


额...都上系统了,厉害,不过ppm采集只用低电平到高电平的边沿就行了,不用在中断里面重新设置边沿(我的天地飞9遥控是这样,直接从模拟器口引出的ppm)

艾儿海绵 发表于 2013-3-18 15:43:40

询问下那个遥控的PPM波怎么引导单片机中啊?

艾儿海绵 发表于 2013-3-18 15:52:07

艾儿海绵 发表于 2013-3-18 15:43 static/image/common/back.gif
询问下那个遥控的PPM波怎么引导单片机中啊?

就是具体接单片机的哪个引脚啊?

fengyiyu1006 发表于 2013-3-19 16:37:10

wangjt1988 发表于 2013-3-17 14:36 static/image/common/back.gif
额...都上系统了,厉害,不过ppm采集只用低电平到高电平的边沿就行了,不用在中断里面重新设置边沿(我的天地 ...



由于我没找到接收机的模拟ppm口在哪,所以用或门把所有电平加在一起了
只采集上升沿只能获取周期,怎么判断高电平时间?而且我需要先找到信号头

fengyiyu1006 发表于 2013-3-19 16:38:04

艾儿海绵 发表于 2013-3-18 15:52 static/image/common/back.gif
就是具体接单片机的哪个引脚啊?

你用哪个定时器哪个通道,就把信号接入哪个引脚,这个没有限制的

理化狂人 发表于 2013-8-29 00:51:39

谢谢啦{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}

sukuanam 发表于 2013-8-29 08:38:49

{:handshake:}{:handshake:}{:handshake:}

TXAM 发表于 2013-9-1 15:31:40

正在研究这个,顶一个

qq949069556 发表于 2013-11-24 16:45:38

谢谢 楼主分享

光轮 发表于 2013-12-6 00:13:22

顶一个,正在学习

starsun 发表于 2014-1-5 19:59:48

楼主太棒了,

立白洗衣粉 发表于 2014-1-14 09:14:31

似乎3楼的程序不对 ,在中断服务函数 怎么能一直那么替换呢!我看别的书上写的都是定时器自动做了计时功能,你只要调用函数把那个计时器里面的数值拿出来 就可以了不用那么麻烦的!

wkman 发表于 2014-1-14 14:11:44

{:shocked:}此 PPM 是啥意思{:sweat:}

mocun 发表于 2014-3-4 14:47:16

很有用,做迷你四轴很实用

vctor、南 发表于 2014-4-16 22:29:03

学习了~~~{:smile:}

yanglei920509 发表于 2014-4-16 22:32:57

mark。。。

sylarwcy 发表于 2014-4-16 23:26:51

我要编码,愁死。。。
页: [1]
查看完整版本: 51单片机解码PPM波