hejiehenry 发表于 2012-2-15 17:04:06

从航模接收机中映出PPM信号,用单片机解码,用LCD1602显示各通道的脉宽(接收机是天地飞6A

最近在做一个三轴的项目,想从接收机中引出PPM信号,用单片机解码,在论坛上看了好多帖子,终于成功了,现在和大家分享一下,第一做这个,欢迎各位高手拍砖!

单片机:stc12c5a56s2
接收机:天地飞6A
液晶屏:LCD1602

hejiehenry 发表于 2012-2-15 17:05:08

标题打错了,是“引出”。

hejiehenry 发表于 2012-2-15 17:26:07

首先是从接收机中引出 PPM信号。
之前有看“hn_ny_dxs 夏风”的帖子:天地飞6-C控+接收机 改造^_^
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=2218730&bbs_page_no=1&search_mode=3&search_text=hn_ny_dxs&bbs_id=9999
里面有说是从VHC164的1、2脚引出PPM信号,但是我试了一下,用示波器看的结果是积分信号,如图:
http://cache.amobbs.com/bbs_upload782111/files_52/ourdev_719081DTJJZM.jpg
(原文件名:164 一二管脚的积分波形_副本.jpg)
这个积分信号刚好和PPM的脉宽相等,本来想用“hn_ny_dxs 夏风”帖中的方法引出,但是发现最小积分信号的峰值电压只有0.75v左右(占空比5%),除了同步信号积分峰值电压有2.45v,其它各通道的最大积分峰值电压只有1.3v(占空比10%);这个不符合单片TTL电路关于高电平的定义:输出高电平>2.4V,输出低电平<0.4V。所以就没用引出这个积分信号。(这里顺便说一句,夏风的焊接焊接不错哦,那么小的管脚都焊接得好!)

hejiehenry 发表于 2012-2-15 17:38:58

所以采用了“bitlyf”帖子:各位TX们,天地飞接收机FRP06-P怎么引出PPM信号?
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3551519&bbs_page_no=1&search_mode=3&search_text=bitlyf&bbs_id=9999
的方案,从LSM393的1管脚引出信号,波形图如下:
http://cache.amobbs.com/bbs_upload782111/files_52/ourdev_719083COROI8.jpg
(原文件名:LSM393一管脚波形图.jpg)

这个是方波,高电平3.29v,满足TTL电路关于高电位的定义。

但是有一个问题又出来了:
这个波形和标准的PPM波形是相反的。


不过没有关系,两个相邻的下降沿之间的时间差刚好依次是:
同步波形、通道1、通道2、通道3、通道4、通道5、通道6

利用这个关系,刚好可以利用单片机INT0对下降沿进行检测,在中断服务程序中读取Timer0的数据就可以计算出脉宽


(要出去吃饭了,吃完饭在回来发代码)

hejiehenry 发表于 2012-2-15 17:56:41

代码的关键部分:

void main(void)
{       
    unsigned char *InitIform;
        unsigned int temp;
        InitIform="Init_is_OK";
        LCD_Init();
        DelayMs(10);
        LCD_Write_String(3,0,InitIform);


//初始化Timer0
        TMOD=0x01;//timer0 方式1
        ET0=1;//允许timer0中断

//初始化INT0
        IT0=1;//负跳变触发中断;
        EX0=1;

        EA=1;
       
        DelayMs(10000);
        while(1)
        {
          temp=filter(PPM_channel1);
                DepartNum(temp);
                LCD_Write_Char(0,0,'A');
                LCD_Write_Char(1,0,qian);
                LCD_Write_Char(2,0,bai);
                LCD_Write_Char(3,0,shi);
                LCD_Write_Char(4,0,ge);

          temp=filter(PPM_channel2);                
                DepartNum(temp);
                LCD_Write_Char(5,0,'B');
                LCD_Write_Char(6,0,qian);
                LCD_Write_Char(7,0,bai);
                LCD_Write_Char(8,0,shi);
                LCD_Write_Char(9,0,ge);

          temp=filter(PPM_channel3);
                DepartNum(temp);
                LCD_Write_Char(10,0,'C');
                LCD_Write_Char(11,0,qian);
                LCD_Write_Char(12,0,bai);
                LCD_Write_Char(13,0,shi);
                LCD_Write_Char(14,0,ge);

          temp=filter(PPM_channel4);
                DepartNum(temp);
                LCD_Write_Char(0,1,'D');
                LCD_Write_Char(1,1,qian);
                LCD_Write_Char(2,1,bai);
                LCD_Write_Char(3,1,shi);
                LCD_Write_Char(4,1,ge);
               
          temp=filter(PPM_channel5);
                DepartNum(temp);
                LCD_Write_Char(5,1,'E');
                LCD_Write_Char(6,1,qian);
                LCD_Write_Char(7,1,bai);
                LCD_Write_Char(8,1,shi);
                LCD_Write_Char(9,1,ge);

          temp=filter(PPM_channel6);
                DepartNum(temp);
                LCD_Write_Char(10,1,'F');
                LCD_Write_Char(11,1,qian);
                LCD_Write_Char(12,1,bai);
                LCD_Write_Char(13,1,shi);
                LCD_Write_Char(14,1,ge);

//                DelayMs(1000);
        }
                                          
}


void ISIR_INT0(void) interrupt 0
{
        unsigned int PPM_temp;
        if(TR0)
        {
                TR0=0;//停止计数;
                PPM_temp=TH0;
                PPM_temp=(PPM_temp<<8)|TL0;
                TH0=0;
                TL0=0;
                TR0=1;//给TH0和TL0赋初值后重新启动定时器
        }
        else
        {
                TH0=0;//如果是第一次启动中断,则启动timer0
                TL0=0;
                TR0=1;
        }
        if(PPM_temp>3000|| Timer0_OverFlowFlag)//判断引导区,如果脉宽大于3000us,则是引导区
        {
                channel=0;
                Timer0_OverFlowFlag=0;
                i++;
                if(i==10) i=0;
        }
        switch(channel)
        {
        case 1: PPM_channel1=PPM_temp; break;
        case 2: PPM_channel2=PPM_temp; break;
        case 3: PPM_channel3=PPM_temp; break;
        case 4: PPM_channel4=PPM_temp; break;
        case 5: PPM_channel5=PPM_temp; break;
        case 6: PPM_channel6=PPM_temp; break;
        case 7: break;
        case 8: break;
        default:break;
        }
        channel++;
}

void ISIR_Timer0(void) interrupt 1
{
        Timer0_OverFlowFlag=1;               //timer0最大值是65536us,理论上不会溢出,如果溢出则出错,重新从通道1开始
}


PPM信号接INT0

hejiehenry 发表于 2012-2-15 18:01:41

完整代码:

点击此处下载 ourdev_719092QR7R2T.txt(文件大小:6K) (原文件名:PPM 解码.txt)

此代码有滤波的作用,实际测试效果不错。

XIE2099 发表于 2012-2-15 23:21:52

谢谢,改天试试看

killin 发表于 2012-2-16 10:47:33

MARK,以前做过个有刷电调,跟楼主一样的滤波的方法。

zyw19987 发表于 2012-2-16 12:46:07

PPM 解码

hpjywd 发表于 2012-2-27 15:04:04

看看显示效果

davidai 发表于 2012-2-27 15:20:59

Mark!

frozen 发表于 2012-2-27 16:10:49

mark

dearterry30 发表于 2012-2-28 11:58:16

mark

kingyong 发表于 2012-3-25 09:14:42

{:smile:} 不错

liliuqun 发表于 2012-3-25 21:50:28

LZ用的是什么平台

huang137 发表于 2012-3-26 02:55:56

本帖最后由 huang137 于 2012-3-26 02:57 编辑

我觉得大家对PPM信号和PWM信号容易混淆,以20mS宽度每帧中间包含4mS同步头和1-8个2mS周期的PWM信号的信号叫做PPM信号,也可以把一个对多个固定周期的PWM信号的合集看作是PPM信号。接收机输出到舵机的信号是这个PPM信号里面分离出来的PWM信号

inspiriting 发表于 2012-6-4 14:37:52

PPM了解中的飘过

济南电子爱好者 发表于 2012-7-7 20:11:03

这个程序 我看了一下有点问题啊。 unsigned int filter(unsigned int *s)这个方法是对得到的10组数据进行加权平均,那个为何还要先排序呢!还有51单片机是负跳变触发中断,实际的PPM波是高电平的宽度代表信号量的大小,这是怎么一回事?

易水寒冰198787 发表于 2012-8-2 15:28:28

谢谢分享!!!

振正2012 发表于 2012-9-5 21:05:48

很有用!!顶一个!

P31014039 发表于 2012-9-20 18:50:36

具体各种飞行模式下脉宽是多少?做个东西,需要这个信息,告诉我一下,谢谢。

我de2012 发表于 2012-9-21 21:36:40

mark一下

天天在读书 发表于 2012-10-3 20:17:51

我用楼主的方法试了一下,大致可以用,但是即使用了滤波得到的脉宽值还是偶尔会变大(不会变小),而且当某一个通道的脉宽变化时,下一个通道的脉宽值会跟着减小或增大。。。很疑惑啊,希望楼主能解答下,我用的是C8051的单片机。

小默 发表于 2012-11-9 09:57:30

ppm信号格式,怎么产生ppm信号,???

大漠游民 发表于 2013-1-13 22:11:43

谢谢分享,谢谢

kexiao 发表于 2013-1-13 23:56:53

有用的资料PPM PWM

yangshichang110 发表于 2013-1-14 21:36:20

huang137 发表于 2012-3-26 02:55 static/image/common/back.gif
我觉得大家对PPM信号和PWM信号容易混淆,以20mS宽度每帧中间包含4mS同步头和1-8个2mS周期的PWM信号的信号 ...

看了这个解释,突然好像理解了什么~

liming 发表于 2013-1-14 23:44:52

顶楼主,好资料。

紫枫0628 发表于 2013-2-3 09:42:43

楼主,你知道WFR06S怎么引出PPM么{:sad:}

jinjianghua 发表于 2013-3-4 16:21:52

楼主这ppm 高电平时间会变吗???

残忆视觉 发表于 2013-3-16 10:17:08

直接转换为PWM信号可以吗{:shocked:}

wujohn 发表于 2013-9-1 22:28:14

请问一下你这个接收器输出给飞控板是不是特定的数目端口??也就是说PPM是特定的端口。

wujohn 发表于 2013-9-1 22:29:15

wujohn 发表于 2013-9-1 22:28 static/image/common/back.gif
请问一下你这个接收器输出给飞控板是不是特定的数目端口??也就是说PPM是特定的端口。 ...

其实我就是不是很清楚我的遥控机的六个通道输给飞控板的到底是PWM,还是PPM??

蓝色の理想 发表于 2013-9-1 22:42:20

学习了~

zrongdong 发表于 2013-9-1 23:19:56

楼主的上位机能分享吗?

王二狗子 发表于 2013-9-3 16:21:57

谢谢楼主提供的资料~~~~~`

firstzys 发表于 2013-11-19 22:32:02

PPM?{:sweat:}

0049 发表于 2013-12-11 13:13:57

本帖最后由 0049 于 2013-12-11 13:17 编辑

huang137 发表于 2012-3-26 02:55
我觉得大家对PPM信号和PWM信号容易混淆,以20mS宽度每帧中间包含4mS同步头和1-8个2mS周期的PWM信号的信号 ...

那请问要捕捉这分离出来的1~8路PWM信号用20ms的周期分别捕捉就可以吗?

zksniper 发表于 2013-12-11 13:41:37

说白了,是一次给你一包糖,你自己分开了吃;还是一个糖一个糖的给你,你去吃。

starsun 发表于 2014-1-5 17:38:18

很早就有人研究这个啦

吉祥瑞 发表于 2014-2-22 09:49:46

都是高手啊

zgcxd 发表于 2014-2-27 12:23:59

了解下!!

firstzys 发表于 2014-5-22 11:40:25

有用啊~

Andre.Gorz 发表于 2014-5-22 12:24:31

你说的单片机应该是stc12c5a60s2吧?

wqq_wqq_wqq 发表于 2014-6-22 18:14:30

看看看看看看看看看看看看看看看看看看看看看看看看看看看看

babylu200661 发表于 2014-8-7 21:49:18

MARK,正在想用从这个接收引出做个带开关的板子

firstzys 发表于 2014-8-28 20:47:43

huang137 发表于 2012-3-26 02:55
我觉得大家对PPM信号和PWM信号容易混淆,以20mS宽度每帧中间包含4mS同步头和1-8个2mS周期的PWM信号的信号 ...

我一直以为PPM和PWM是一样的,原来PPM是PWM的合集
页: [1]
查看完整版本: 从航模接收机中映出PPM信号,用单片机解码,用LCD1602显示各通道的脉宽(接收机是天地飞6A