yjbin 发表于 2017-2-10 20:26:04

用单片机接受航模遥控器发射的信号,怎么办啊?

本帖最后由 yjbin 于 2017-2-10 20:29 编辑

淘宝上找来的图片






谁做过啊,有什么资料吗?

饭桶 发表于 2017-2-10 20:32:14

你要做接收机还是处理接收机出来的PWM信号?

yjbin 发表于 2017-2-10 20:56:57

处理接收机出来的信号

饭桶 发表于 2017-2-10 23:38:23

请搜索 舵机信号+单片机

3goodboy 发表于 2017-2-11 00:35:53

接收器出来的是ppm信号,用定时器解码

gbfootball2 发表于 2017-2-11 00:41:14

找一个来源的ppm编码器代码看看

jcrorxp 发表于 2017-2-11 09:28:48

淘宝50块钱买个逻辑分析仪看看不就行了. 很简单的代码, 如果精度要求不高的话.

jifei538610 发表于 2017-2-13 10:42:52

我记得是50HZ的PWM波,用输入捕获就行

hswkcg 发表于 2017-2-13 15:46:37

3goodboy 发表于 2017-2-11 00:35
接收器出来的是ppm信号,用定时器解码

遥控和接收机之间是PPM,但是接收机输出的是PWM,单片机在依据读取到的PWM占空比来进行油门等量的调节,我们测试过接收机输出波形。

yjbin 发表于 2017-2-17 13:25:04

hswkcg 发表于 2017-2-13 15:46
遥控和接收机之间是PPM,但是接收机输出的是PWM,单片机在依据读取到的PWM占空比来进行油门等量的调节, ...

能贴出来吗? 没有逻辑仪呢。 谢谢了

admvip 发表于 2017-2-18 13:10:37

我以前学习遥控器舵机的程序,有详细的注释,你可以参考一下。

main.c
--------------------------------
/****************************************************
       RC 4VF模型遥控器PWM单片机解码与控制
-----------------------------------------------------
MCU    :AVR M8
主    频 :8M
编制日期 :20110211
最后修订 :20110215
程序版本 :Ver1.1
-----------------------------------------------------
程序概述:
        使用M8的TC1的外部触发分别测量RC PWM信号的各个脉冲
宽度,用测量得到的数据按通道分别输出相应控制舵机能够
是别的脉冲信号,实现对RC PWM的信号解调。
    RC PWM参数请在TimeCount.h文件里配置。
    程序借鉴了部分徐江的控制代码,特此声明。
-----------------------------------------------------
程序功能模块:
主程序模块
定时中断处理模块
串口调试模块
-----------------------------------------------------
RC PWM解码器硬件连接
AVR M8 MCU
-----------
PB0    #14      ICP输入 <-------- 4VF PWM 输出信号
PD0    #2       RXD输入 <-------- 串口数据输入
PD1    #3       TXD输出 --------> 串口数据输出
PD2    #4               --------> CH1舵机控制输出
PD3           #5                                --------> CH2舵机控制输出
PD4           #6                                --------> CH3舵机控制输出
PD5           #11                                --------> CH4舵机控制输出
PD6           #12                                --------> CH5舵机控制输出
PD7           #13                                --------> CH6舵机控制输出
-----------------------------------------------------
程序修订记录:
2011.02.12
修改了中断捕获部分的代码,增加了几个标志变量,便于程
序进程控制。将PWM的配置数据和中断使用的全局变量移至
TimeCount.c文件中,在TimeCount.h中做了引用声明。
经过上机调试,发现捕获中断不能被关闭,否则会漏抓一帧
数据,导致输出不连续,分管输出信号的TC0可以在不使用
的时候关闭掉,减轻CPU的运算负担。

2011.02.15
将中断处理PWM输出改为函数处理PWM输出,在主程序中循环
调用PWM_OUT()函数即可实现连续PWM控制波形输出。
****************************************************/

#include "config.h"


void port_init(void)
{
PORTB = 0x00;
DDRB= 0x00;
PORTC = 0x00; //m103 output only
DDRC= 0x00;
PORTD = 0x00;
DDRD= 0x00;
}



//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
Uart_Init();
TimeCount_init();


MCUCR = 0x00;
GICR= 0x00;
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

void main (void)
{
init_devices();

while (1)
{
       PWM_OUT();
}
}




TimeCount.c
---------------------------------------
/************************************************************************
文件名称:TimeCount.C
修改日期:2011/02/11
创建人:admvip

定时器0,定时器1的初始化和中断处理函数
************************************************************************/

#include <iom8v.h>
#include <AVRdef.h>
#include "TimeCount.h"


/*变量定义区*/
volatile unsigned charg_ChannelData;        //通道数据存储数组
volatile unsigned charg_bInAllComplete= FALSE;                        //输入波形采集完成标志
volatile unsigned charg_bOutAllComplete = TRUE;                //输出波形发送完成标志
volatile unsigned charg_nInIndex= 0;                                //当前输入通道号
volatile unsigned charg_nOutIndex = 0;                                //当前输出通道号
volatile unsigned int   g_nPwmWidth = 0;                                //被检测脉冲宽度
volatile unsigned charg_bReceiveStart   = FALSE;                //通道数据接收开始标志
volatile unsigned int   s_nTC0_Count;
/********************************************/
//TIMER0 initialize - prescale:64
// desired value: 8uSec
// actual value:8.000uSec (0.0%)
static void timer0_init(void)
{
        TCCR0 = 0x00;        //stop
        TCNT0 = 0xFF;        //set count
        //TCCR0 = 0x03; //start timer
}

//TIMER1 initialize - prescale:64
// WGM: 0) Normal, TOP=0xFFFF
// Setp value:8.000uSec (0.0%)
static void timer1_init(void)
{
        TCCR1B = 0x00; //stop
        TCNT1H = 0x00; //setup
        TCNT1L = 0x00;
        OCR1AH = 0x00;
        OCR1AL = 0x01;
        OCR1BH = 0x00;
        OCR1BL = 0x01;
        ICR1H= 0x00;
        ICR1L= 0x01;
        TCCR1A = 0x00;
        //TCCR1B bit6:1上升沿捕获bit6:0下降沿捕获
        //TCCR1B |= BIT(6);上升沿捕获   TCCR1B &= ~BIT(6);下降沿捕获
        //根据需要可在捕获中断内变换
        TCCR1B = 0x43; //start Timer
}

void TimeCount_init(void)
{
        timer0_init();
        timer1_init();
        //TIMSK bit5:1使能TC1外部电平捕获bit5:0禁止TC1外部电平捕获
        TIMSK = 0x21;        //timer interrupt sources
        DDRD |= 0xFC;        // 设置PD2-PD7为舵机信号输出端口
}

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

/***********************************************
        TC0溢出中断负责各通道PWM波形输出,每8us刷新一
        次,中断内检测各通道数据,到达脉宽设定的通道结
        束PWM输出。全部通道发送完毕后所有端口置低电平,
        同时关闭TC0溢出中断,等待下一次数据输出。
***********************************************/
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{

        TCNT0 = 0xFF;        //reload counter value
        s_nTC0_Count++;

}



/***********************************************
        TC1输入捕获中断负责接收RC送来的PWM连续脉冲,
        通过检测各通道的脉冲宽度来确定各通道的PWM数据,
        有效通道脉冲全部接收完毕后打开TC0溢出中断实现
        各通道的PWM波形分离输出。
***********************************************/
#pragma interrupt_handler timer1_capt_isr:iv_TIM1_CAPT
void timer1_capt_isr(void)
{
        //timer 1 input capture event, read (int)value in ICR1 using;
        // value=ICR1L;            //Read low byte first (important)
        // value|=(int)ICR1H << 8; //Read high byte and shift into top byte
        if (TCCR1B & BIT(6))        // 是否为上升沿触发?
        {
                TCNT1   = 0;               //TC1计数器归零
                TCCR1B &= ~BIT(6); //修改为下降沿触发

        } else
        {
                g_nPwmWidth = ICR1;                // 下降沿触发后保存有效的脉宽数据
                TCCR1B |= BIT(6);                        // 修改为上升沿触发,为下一次脉冲做准备

                if (g_nPwmWidth > 625)        // 判断是否为超过5ms的脉冲,确定通道数据是否开始接收
                {
                        g_bReceiveStart = TRUE;        // 接收开始标志置位
                        g_nInIndex = 0;                                // 输入索引归零
                } else
                {
                        if (g_bReceiveStart)        // 判断接收开始标志置位,开始接受有效通道数据
                        {
                                g_ChannelData = (unsigned char) g_nPwmWidth;
                                if (g_nInIndex >= CHANNELCOUNT)        // 检测有效通道接收是否完成
                                {
                                        g_bReceiveStart= FALSE;               // 接收开始标志清零
                                        g_bInAllComplete = TRUE;       // 接收完成标志置位
                                        TCCR0 = 0x03;                                               // 启动TC0,准备信号输出
                                }
                        }
                }//if (g_nPwmWidth > 625) End

        }//if (TCCR1B & BIT(6)) End

}

void PWM_OUT(void)
{
        s_nTC0_Count = 0;                               //TC0计数器变量归零
        while (g_bInAllComplete)
        {
                if (s_nTC0_Count < PULSEMaxWIDTH)
                {
                        for (g_nOutIndex = 0; g_nOutIndex < CHANNELCOUNT; g_nOutIndex++)
                        {
                                if (g_ChannelData > s_nTC0_Count)
                                {
                                        //按脉宽数据设置输出高电平,+2是为了调整端口索引和实际端口的差别,改变硬件连接时需要调整
                                        PWMOUTPORT |= BIT(g_nOutIndex+2);
                                } else
                                {
                                        //达到脉宽的通道电平置低
                                        PWMOUTPORT &= ~BIT(g_nOutIndex+2);
                                }//if (g_ChannelData > s_nTC0_Count) End
                        }
                } else
                {
                        // 2.5ms时间到,所有舵机输出置低电平,结束一帧通道波形输出
                        PWMOUTPORT &= ~(BIT(CH1) | BIT(CH2) | BIT(CH3) | BIT(CH4) | BIT(CH5) | BIT(CH6));
                        if (s_nTC0_Count > 375)
                        {
                                //TCCR1B = 0x43; //start Timer
                                s_nTC0_Count = 0;        //TC0计数器变量归零
                                g_bInAllComplete = FALSE;
                                TCCR0 = 0x00;        //关闭TC0定时器,等待下一次输出
                        }
                }//if (s_nTC0_Count < PULSEMaxWIDTH) End
        }
}




lintel 发表于 2017-2-18 15:23:34

大网搜萝莉遥控,有你想要的,做完给这里后来者分享下

huangqi412 发表于 2017-2-19 13:05:16

外中断或者捕捉
页: [1]
查看完整版本: 用单片机接受航模遥控器发射的信号,怎么办啊?