5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)

标题: ppm信号怎么输入单片机啊 我都要哭了4 [打印本页]

作者: 普加乔夫    时间: 2013-8-31 22:10
标题: ppm信号怎么输入单片机啊 我都要哭了4
是这样的 我想把ppm信号输入单片机at89s52 可单片机的捕捉模块式沿下降沿触发 ppm信号式file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\934415937\QQ\WinTemp\RichOle\RKLH)~CQNIC5C)$_N_]%BDD.jpg上升沿信号 我加了反相器74hc04 也还是没用 怎么办 求高手指点 我用是用的网上的程序
//PPM 解码程序
//用INT0接PPM信号
//T0计数,用来测量脉宽
//注意,这个不是标准的PPM信号,刚好和PPM信号相位相反
//测得的PPM信号在LCD上显示
//PPM信号取自天地飞6A接收机
//时间:2012年2月15日0:22:31
# include <reg52.h>
# include <intrins.h>

# define DataPort P2

sbit RS=P0^5;
sbit RW=P0^6;
sbit EN=P0^7;

unsigned char channel=0,i=0;
unsigned int xdata PPM_channel1[10],PPM_channel2[10],PPM_channel3[10],PPM_channel4[10],PPM_channel5[10],PPM_channel6[10];
bit Timer0_OverFlowFlag=0;//定时器0的溢出标志,如果溢出,则有问题;
unsigned char qian,bai,shi,ge;

# define RS_CLR RS=0;
# define RS_SET RS=1;
# define RW_SET RW=1;
# define RW_CLR RW=0;
# define EN_CLR        EN=0;
# define EN_SET EN=1;

//和LCD显示有关的函数定义
void LCD_Check_Busy(void); //查忙函数
void LCD_Clear(void);//清屏函数
void LCD_Init(void);//lcd初始化函数
void LCD_Write_Com(unsigned char com);//控制字写入函数
void LCD_Write_Data(unsigned char Data);//数据写入函数
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);//写入单个字符
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);//写入字符串
unsigned int filter(unsigned int *s);//中值平局滤波;
void DepartNum(unsigned int temp);//用于分解要显示的数据

void DelayUs2x(unsigned char t);
void DelayMs(unsigned int t);


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 DelayUs2x(unsigned char t)
{   
while(--t);
}

void DelayMs(unsigned int t)
{

while(t--)
{
     //大致延时1mS
     DelayUs2x(245);
         DelayUs2x(245);
}
}

//查忙函数
void LCD_Check_Busy(void)
{
unsigned char i=255;
DataPort= 0xff;
RS_CLR;
RW_SET;
EN_SET;
while(i--&&(DataPort&0x80));
EN_CLR;
}

//控制字写入函数,入口参数是控制字
void LCD_Write_Com(unsigned char com)
{
        LCD_Check_Busy();
        RS_CLR;
        RW_CLR;
        DataPort=com;
        EN_SET;
        _nop_();
        EN_CLR;
}

//写入数据,入口参数是要写入的数据
void LCD_Write_Data(unsigned char Data)
{
        LCD_Check_Busy();
        RS_SET;
        RW_CLR;
        DataPort=Data;
        EN_SET;
        _nop_();
        EN_CLR;       
}

//清屏函数
void LCD_Clear(void )
{
        LCD_Write_Com(0x01);
        DelayMs(5);               
}

//LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),*S显示的字符串
void LCD_Write_String(unsigned char x,unsigned char y, unsigned char *s)
{
        if(y==0) LCD_Write_Com(0x80+x);
        else LCD_Write_Com(0xc0+x);
        while(*s)
        {
                LCD_Write_Data(*s);
                s++;
        }
}

//LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),Data显示的字符
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
         if(y==0) LCD_Write_Com(0x80+x);
         else LCD_Write_Com(0xc0+x);
            DelayMs(1);//a little delay for simulation
         LCD_Write_Data(Data);
}


//lcd初始化函数
void LCD_Init(void)
{
        LCD_Write_Com(0x38);// set the display model
        DelayMs(5);
        LCD_Write_Com(0x08);//turn down the display
        //LCD_Write_Com(0x01);//clear the display
        LCD_Clear();
        LCD_Write_Com(0x06);//set the 光标 moving model
        DelayMs(5);
        LCD_Write_Com(0x0c);//显示开和光标设置
}

/****************************************
用于显示的数位分解函数,把数据转化为ASCII码
入口参数是要显示的数据
****************************************/
void DepartNum(unsigned int temp)
{
        qian=temp/1000+0x30;
        bai=temp%1000/100+0x30;
        shi=temp%100/10+0x30;
        ge= temp%10+0x30;
}

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)//判断引导区
        {
                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;
}

unsigned int filter(unsigned int *s)
{
        unsigned char k,j;
        unsigned int sum=0;
        unsigned int temp;
        for(k=0;k<9;k++)
                for(j=k+1;j<10;j++)          
                if(s[k]>s[j])
                {
                        temp=s[k];
                        s[k]=s[j];
                        s[j]=temp;
                }
        for(k=1;k<9;k++)
        sum+=s[k];
        sum=sum/8;
        return sum;
}






作者: yaoyonghe    时间: 2013-8-31 23:59
天文与数字

不懂路过....

话说arduino真简单个说,一个duration搞定

作者: caosix2    时间: 2013-9-1 00:42
最主要的是:你输入之后 想干什么、想得到什么?

作者: dolphintt920    时间: 2013-9-1 01:07
LCD有没有正确显示?上电开机的时候有没有显示InitIform?
先确定LCD显示无误,再把中断关掉,把temp赋固定值看能否正确显示,最后再看捕获和中断设置有没有问题,一个一个的排除。

作者: 3344877133    时间: 2013-9-1 01:10
天书不懂....路过!

作者: bugsplus    时间: 2013-9-1 14:52
只要懂原理即可,没必要搜网上的程序代码。
pcm信号示波器测量下即可获得,也就是20ms的方波,通道信号是1-2ms脉冲;
自己采集处理即可。

作者: peng617580660    时间: 2013-9-1 16:05
中断第一次上升沿,记下此刻的值。第二次把中断换成下降沿使能。用二次得的值减第一次的值就得高电平的脉宽值了。
具体实现要一个模块的测试看功能有没有达到预期。

作者: 普加乔夫    时间: 2013-9-2 10:04
caosix2 发表于 2013-9-1 00:42
最主要的是:你输入之后 想干什么、想得到什么?

输入ppm信号 单片机根据ppm信号的高电平时间 对应输出pwm信号 控制电机的加速和减速

作者: 普加乔夫    时间: 2013-9-2 10:06
dolphintt920 发表于 2013-9-1 01:07
LCD有没有正确显示?上电开机的时候有没有显示InitIform?
先确定LCD显示无误,再把中断关掉,把temp赋固定 ...

显示的是Init_is_OK  程序该怎么改呢


作者: 普加乔夫    时间: 2013-9-2 10:07
bugsplus 发表于 2013-9-1 14:52
只要懂原理即可,没必要搜网上的程序代码。
pcm信号示波器测量下即可获得,也就是20ms的方波,通道信号是1 ...

程序不会啊


作者: 普加乔夫    时间: 2013-9-2 10:08
peng617580660 发表于 2013-9-1 16:05
中断第一次上升沿,记下此刻的值。第二次把中断换成下降沿使能。用二次得的值减第一次的值就得高电平的脉宽 ...

89s52是沿下降沿触发的啊 怎么记录他高电平时间 求个程序说明 怎么让他中断第一次上升沿



作者: caosix2    时间: 2013-9-2 10:55
普加乔夫 发表于 2013-9-2 10:04
输入ppm信号 单片机根据ppm信号的高电平时间 对应输出pwm信号 控制电机的加速和减速

你是在 自己做 “电调” 哦 !!

单片机 如果有 CCP 模块,就很简单:

直接用 CCP 捕捉模块 去测量 输入的脉冲宽度 Esay


作者: peng617580660    时间: 2013-9-2 14:44
本帖最后由 peng617580660 于 2013-9-2 14:49 编辑
普加乔夫 发表于 2013-9-2 10:08
89s52是沿下降沿触发的啊 怎么记录他高电平时间 求个程序说明 怎么让他中断第一次上升沿

这样就用低电平触发,第一次来读外部脚电平。记录此时的时刻1(定时器),然后改为外部低电平触发中断,中断后记录时刻2,这样就得出高电平时刻了。当然软件里要切换这两种模式


另一种方式就是用定时器的输入捕获功能。

作者: 普加乔夫    时间: 2013-9-2 17:44
caosix2 发表于 2013-9-2 10:55
你是在 自己做 “电调” 哦 !!

单片机 如果有 CCP 模块,就很简单:

at89s52没用cpp模块 这是个有刷电调 做出来


作者: 普加乔夫    时间: 2013-9-2 17:45
peng617580660 发表于 2013-9-2 14:44
这样就用低电平触发,第一次来读外部脚电平。记录此时的时刻1(定时器),然后改为外部低电平触发中断,中 ...

能写点程序看看吗


作者: 辽阳子涵    时间: 2013-9-2 18:18
白的可以,只捕捉一个下降沿能测量脉宽吗?用膝盖想想

作者: 辽阳子涵    时间: 2013-9-2 18:19
普加乔夫 发表于 2013-9-2 17:44
at89s52没用cpp模块 这是个有刷电调 做出来

用C8051F系列
很牛X的片子


作者: peng617580660    时间: 2013-9-3 11:08
普加乔夫 发表于 2013-9-2 17:45
能写点程序看看吗


    if(引脚电平==0)
    {
        oldTime = newTime;
    }
    else
    {
            tmp = newTime - oldTime;                             
        if((tmp >= downData) && (tmp <= upData))            
        {
             有效数据;   
        }        
    }

newTime 当前定时器的值
oldTime  上一次的值


开个定时器就行了,不用外部中断貌似也可以。



作者: bugsplus    时间: 2013-9-6 16:48
这个片子不能上升沿中断,可以加个异或门,这样上升沿下降沿都可以中断了;
两次中断的时间差就是脉宽;

作者: 普加乔夫    时间: 2013-9-6 23:04
bugsplus 发表于 2013-9-6 16:48
这个片子不能上升沿中断,可以加个异或门,这样上升沿下降沿都可以中断了;
两次中断的时间差就是脉宽;

我加了个74ch04

作者: bugsplus    时间: 2013-9-7 10:02
普加乔夫 发表于 2013-9-6 23:04
我加了个74ch04

脉冲来就开始计数,下次脉冲再来,看一下时间,时间在1-2ms之内就是脉冲宽,18-19ms就是低电平时间;


作者: 普加乔夫    时间: 2013-9-7 12:42
bugsplus 发表于 2013-9-7 10:02
脉冲来就开始计数,下次脉冲再来,看一下时间,时间在1-2ms之内就是脉冲宽,18-19ms就是低电平时间;

加了74ch04 1-2ms就是低电平了


作者: bugsplus    时间: 2013-9-7 12:56
普加乔夫 发表于 2013-9-7 12:42
加了74ch04 1-2ms就是低电平了

en,那你打开timer测脉冲宽度就可以了

作者: 普加乔夫    时间: 2013-9-7 13:24
bugsplus 发表于 2013-9-7 12:56
en,那你打开timer测脉冲宽度就可以了

写点程序看看行不

作者: 普加乔夫    时间: 2013-9-7 13:26
普加乔夫 发表于 2013-9-7 13:24
写点程序看看行不

#include<reg52.h>
sbit in=P3^2;
sbit LED=P0^0;

void main(void)
{        unsigned int temp;
                        LED=0;
                TMOD=0x90;
                TH1=0;
                TL1=0;       
                while(P3^2);
                TR1=1;
                while(!P3^2);
                while(P3^2);
                TR1=0;
                temp=TH1;
                temp=(temp<<8)|TL1;
                if(temp>100)
                        LED=1;
        while(1);
}
这是没加74ch04写的 但没用 从接收机引出发的ppm信号输入p32脚 led没反应



作者: bugsplus    时间: 2013-9-7 14:20
确定硬件电路没问题?
你最好把uart打开,不然很难查问题;
网上搜搜,串口打印函数;

作者: bugsplus    时间: 2013-9-7 14:40
那个temp>100
这个条件你实际算过吗?20ms时间
说不定每次都溢出了,所以你判断不到

作者: n44303    时间: 2013-9-7 18:39
昨晚把输入检测写好了,现在手机上网,明天贴上来。

可以贴上了:

//ICC-AVR application builder : 2012/7/27 17:49:05
// Target : M16
// Crystal: 16.000Mhz

#include <iom16v.h>
#include <macros.h>


int out_f = 100,
//设置输出频率,单位Hz

ch_in_01,
   
//存储ch1的输入值

ch_in_02,
//存储ch2的输入值

ch_out_01,
//存储ch1的输出值

ch_out_02,
//存储ch2的输出值

int0_rising,

int0_falling,

int1_rising,

int1_falling;


char int0_ovf_count,

int1_ovf_count;
  //这里记录上升沿后timer1的溢出次数


void port_init(void)
{
PORTA = 0x0F;
DDRA  = 0xF0;
//PORTA最高4位为输出端口
PORTB = 0xFF;
DDRB  = 0x00;
PORTC = 0xFF;
DDRC  = 0x00;
PORTD = 0xFF;
DDRD  = 0x30;
}

//TIMER1 initialize - prescale:8
// WGM: 14) PWM fast, TOP=ICRn
// desired value: 10000uSec
// actual value: 10000.000uSec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00;
  //stop
TCNT1H = 0x00;
  //setup
TCNT1L = 0x00;
  OCR1A = ch_out_01;
  OCR1B = ch_out_02;
  ICR1  = out_f*100*2;
   

//16M晶振;8分频;实际TOP数值为20000;TOP值可以用“out_f”进行修改;
TCCR1A|= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
//OC1A/B 比较匹配时输出低电平;WGM13:WGM10配置TC1为快速PWM、TOP值=ICR1;
TCCR1B|= (1<<WGM13)|(1<<WGM12)|(1<<CS11);
//时钟8分频,每2个时钟=1uS;
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
TCNT1H = 0x00 /*INVALID SETTING*/; //reload counter high value
TCNT1L = 0x00 /*INVALID SETTING*/; //reload counter low value
int0_ovf_count++;
int1_ovf_count++;

ch_out_01 = (unsigned long)ch_in_01/100*75+(ch_in_02>>1);
//更新ch1的输出值

ch_out_02 = (unsigned long)ch_in_01/100*75-(ch_in_02>>1);
//更新ch2的输出值
}

#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{//external interupt on INT0  PD2

if(PIND & 0x04)//如果PD2为高电平,证明是上升沿触发

{

int0_rising = TCNT1;

int0_ovf_count = 0;

}

else

{

int0_falling = TCNT1;
//读取当前寄存器数值

ch_in_01 =(unsigned long)int0_ovf_count*ICR1+(unsigned long)int0_falling-(unsigned long)int0_rising;

}
}

#pragma interrupt_handler int1_isr:iv_INT1
void int1_isr(void)
{//external interupt on INT1 PD3

if(PIND & 0x08)//如果PD3为高电平,证明是上升沿触发

{

int1_rising = TCNT1;

int1_ovf_count = 0;

}

else

{

int1_falling = TCNT1;
//读取当前寄存器数值

ch_in_02 =(unsigned long)int1_ovf_count*ICR1+(unsigned long)int1_falling-(unsigned long)int1_rising;

}
}


//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer1_init();
TIMSK |= 1<<TOIE1;   
  
//开timer1溢出中断

  GICR |= (1<<INT1)|(1<<INT0);
//开启外部中断int1,int0
MCUCR |= (1<<ISC10)|(1<<ISC00);
  
//设置int1,int0电平变化触发中断
SEI(); //re-enable interrupts
//all peripherals are now initialized
}








void main(void)
{
init_devices();
while(1)
{
;
}

}

[ 本帖最后由 n44303 于 2012-8-1 23:43 编辑 ]



作者: 普加乔夫    时间: 2013-9-7 19:50
bugsplus 发表于 2013-9-7 14:20
确定硬件电路没问题?
你最好把uart打开,不然很难查问题;
网上搜搜,串口打印函数;

硬件没问题


作者: 普加乔夫    时间: 2013-9-7 19:52
n44303 发表于 2013-9-7 18:39
昨晚把输入检测写好了,现在手机上网,明天贴上来。

可以贴上了:

哥哥 你这是啥芯片啊


作者: bugsplus    时间: 2013-9-9 15:28
兄弟,你还是老老实实自己写代码吧,用别人的更麻烦;、
先把uart打开,能打印调试信息;

作者: bugsplus    时间: 2013-9-9 15:34
#include < reg52.h >
#include < intrins.h >
#include < stdio.h >

#define uchar unsigned char
#define uint  unsigned int

/**********************************************************
*                                                         *
*  延时函数                                               *
*                                                         *
**********************************************************/
void delay(int ms)
{
    uchar i;
    while(ms--)
{
   for(i=0;i<250;i++)  
    {
     _nop_();      
  _nop_();
  _nop_();
  _nop_();
    }
}
}

/**********************************************************
*                                                         *
* 主程序                                                  *
*                                                         *
**********************************************************/
main()
{  
   SCON=0x50;      //串口模式1,允许接收
   TMOD=0x20;      //定时器1为模式2,8-bit 自动装载方式
   PCON=0x00;      //波特率不倍增

   TL1=0xfd;
   TH1=0xfd;      //波特率9600
   TI=1;          //TI 置1,以发送第一个字节
   TR1=1;         //启动定时器 T1

   while(1)
   {
      printf (" 5imx 航模朋友大家好\n"); //向PC机发送数据
      delay(500);
      printf (" welcome to \n");           //向PC机发送数据
   delay(500);
      printf (" test  \n");                  //向PC机发送数据
   delay(500);
   printf (" \n");                                    //向PC端发送数据
   delay(500);
   }
}

/*********************************************************

作者: bugsplus    时间: 2013-9-11 16:00
兄弟,加油啊;这个代码不难,你先把单片机跑起来,打开串口,打印出调试信息,写程序就很快了。
你先把我上面代码复制一下,用串口精灵接串口打印到pc上看一下;

作者: 普加乔夫    时间: 2013-9-14 13:02
bugsplus 发表于 2013-9-11 16:00
兄弟,加油啊;这个代码不难,你先把单片机跑起来,打开串口,打印出调试信息,写程序就很快了。
你先把我 ...

无尽感激  能加我qq吗 934415937


作者: 四书五经008    时间: 2013-9-14 21:56
51用了还是不准确 AVR或其他有输入捕捉的要好用的多 而且好像不能捕捉下降沿

作者: 普加乔夫    时间: 2013-9-15 09:30
我买了一款ppm解码板 试试看看能不能弄好 要能弄好 就开始用stm32


作者: bugsplus    时间: 2013-9-15 10:46
楼主,我觉得你先把51单片机玩转,写这个代码很简单的;
比你开发其他方案简单得多;
1:51调试串口搞出来;
2:外部中断搞起来;
3:timer搞起来;
代码就没几行了。。。。

作者: 普加乔夫    时间: 2013-9-15 19:06
bugsplus 发表于 2013-9-15 10:46
楼主,我觉得你先把51单片机玩转,写这个代码很简单的;
比你开发其他方案简单得多;
1:51调试串口搞出来 ...

好吧



作者: xxldhxx    时间: 2013-9-15 22:54
呵呵我也是正在学这个呢
有性趣联系吧
QQ:546861544

作者: xxldhxx    时间: 2013-9-15 22:57
我是天地飞7的
测试了一下,输出频率40Hz,控制脉宽为5ms,其中2.5ms为固有,2.5ms为调节,油门时2.5ms为零,5ms时为100%
其他控制为3.75为中立点.

作者: xxldhxx    时间: 2013-9-15 22:58
这个健议采用STM8,可以直接得到脉宽


作者: weidimay    时间: 2013-9-16 11:29
厉害,74ch04  反相吗

作者: 普加乔夫    时间: 2013-9-16 12:41
xxldhxx 发表于 2013-9-15 22:58
这个健议采用STM8,可以直接得到脉宽

stm8 只能测脉宽 别的干不了



作者: 普加乔夫    时间: 2013-9-16 12:42
weidimay 发表于 2013-9-16 11:29
厉害,74ch04  反相吗

是的 但现在发现 自己的思路不对

作者: bdblue    时间: 2013-9-16 13:32



楼主何不用AVR,处理PPM方便多了,给你个帖子作参考。多路PPM捕捉,多路PPM输出。http://bbs.5imx.com/bbs/forum.php?mod=viewthread&tid=503098


作者: 普加乔夫    时间: 2013-9-16 13:35
bdblue 发表于 2013-9-16 13:32
楼主何不用AVR,处理PPM方便多了,给你个帖子作参考。多路PPM捕捉,多路PPM输出。http://bbs.5imx.com/ ...

无尽感激


作者: 普加乔夫    时间: 2013-9-16 13:42
bdblue 发表于 2013-9-16 13:32
楼主何不用AVR,处理PPM方便多了,给你个帖子作参考。多路PPM捕捉,多路PPM输出。http://bbs.5imx.com/ ...

我是个新手 先从简单的入手吧

作者: xxldhxx    时间: 2013-9-18 08:26
普加乔夫 发表于 2013-9-16 12:41
stm8 只能测脉宽 别的干不了

STM8做电调控制器,要求不精的话还是可以的,精度速度都可以.

作者: chydn2000    时间: 2013-9-18 20:29
用查询高电平方式,高电平来后启动T0,低电平结束,然后计算电平宽度。

作者: 普加乔夫    时间: 2013-9-18 22:35
chydn2000 发表于 2013-9-18 20:29
用查询高电平方式,高电平来后启动T0,低电平结束,然后计算电平宽度。

我买了个ppm解码板 输出标准的ppm信号 在输入单片机


作者: wangfine1975    时间: 2013-12-10 14:43
直接检测相邻的上升沿或下降沿的脉冲宽度就可以,直接得到通道的值。

作者: 普加乔夫    时间: 2013-12-10 18:16
wangfine1975 发表于 2013-12-10 14:43
直接检测相邻的上升沿或下降沿的脉冲宽度就可以,直接得到通道的值。

这个是示波器测得波形

作者: wangfine1975    时间: 2013-12-11 10:57
看不到图片
52没做过,原来用PIC做过检测接收机出来的信号,做一路的时候基本没问题,做两路的时候不太好使。

作者: 狐狸    时间: 2013-12-12 20:39
用PIC单片机吧,PICBASIC PRO高级编程语言
一个pulsin指令就可以测出单个脉冲的宽度;

作者: 狐狸    时间: 2013-12-12 20:43
本帖最后由 狐狸 于 2013-12-12 20:46 编辑

......
PULSIN PORTB.0,1,W1   '测出B口第1脚的脉宽,数据赋值给W1变量;
PULSIN PORTB.1,1,W2   '测出B口第2脚的脉宽,数据赋值给W2变量;
PULSIN PORTB.2,1,W3   '测出B口第3脚的脉宽,数据赋值给W3变量;
PULSIN PORTB.3,1,W4   '测出B口第4脚的脉宽,数据赋值给W4变量;
.....
后处理程序;
...





作者: 狐狸    时间: 2013-12-12 20:45
18系列单片机就可以满足一般的要求了;
如果要想更好,呵呵,PIC24F系列更爽;

作者: 杰克上尉    时间: 2013-12-13 11:57
高人!!

作者: 普加乔夫    时间: 2013-12-15 22:03
狐狸 发表于 2013-12-12 20:43
......
PULSIN PORTB.0,1,W1   '测出B口第1脚的脉宽,数据赋值给W1变量;
PULSIN PORTB.1,1,W2   '测出B口 ...

看不懂汇编啊 求c

作者: 普加乔夫    时间: 2013-12-15 22:06
wangfine1975 发表于 2013-12-11 10:57
看不到图片
52没做过,原来用PIC做过检测接收机出来的信号,做一路的时候基本没问题,做两路的时候不太好使 ...

(, 下载次数: 50) 这个

作者: wangfine1975    时间: 2013-12-17 08:17
你是准备解码接收机接收到的多通道信号,还是解码单个通道的信号,你都没说明白

作者: 普加乔夫    时间: 2013-12-17 09:40
wangfine1975 发表于 2013-12-17 08:17
你是准备解码接收机接收到的多通道信号,还是解码单个通道的信号,你都没说明白

不好意思啊 我这个图是三通的波形 我想解码三通的信号 能讲讲吗


作者: wangfine1975    时间: 2013-12-17 10:32
本帖最后由 wangfine1975 于 2013-12-17 10:36 编辑

用电平中断吧,用电平中断检测到第一次中断时,T0或T1清0,第二次中断时,记录下T的数值。比如设置个全局变量。
发射机发射两次中间的电平脉宽大于3MS。
当检测到一个大于3MS的脉宽时,下一组信号开始发送,用中断逐次检测到每个通道的值。
我估计每个通道的在0.5-3MS之间。

如果只解第三通道,那么把前两个通道舍弃就可以了

我也不怎么精通,不过这个办法肯定能解出来


作者: 普加乔夫    时间: 2013-12-17 13:08
wangfine1975 发表于 2013-12-17 10:32
用电平中断吧,用电平中断检测到第一次中断时,T0或T1清0,第二次中断时,记录下T的数值。比如设置个全局变 ...

我试试 感激不尽

作者: wangfine1975    时间: 2013-12-17 15:25
本帖最后由 wangfine1975 于 2013-12-17 15:33 编辑

不客气,电调留着你自己用吧
51单片机也是仅仅懂一点,做过的最复杂的东西也不过是个带闹钟的数码显示的电子钟。
实用的东西也是仅仅做了个定时器,用来定时煮米饭用的。


作者: 锦州-小峰    时间: 2013-12-17 19:59
根本看不懂啊





欢迎光临 5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年) (http://5imx.com./) Powered by Discuz! X3.3