zxhgr 发表于 2017-3-6 20:29:02

图解DIY航模遥控器和接收机

什么也不说直接看图说话接收PCB板
http://www.moz8.com/data/attachment/album/201703/06/200013pqjptn33usnzwsw2.jpg

http://www.moz8.com/data/attachment/album/201703/06/200014p5d6iq5wqwwt6cwq.jpg


http://www.moz8.com/data/attachment/album/201703/06/200015jodcshs6s57ft8zw.jpg

http://www.moz8.com/data/attachment/album/201703/06/200019efsfgtc694g2czqp.jpg

zxhgr 发表于 2017-3-7 10:05:07

下载图片资料

王东阳 发表于 2021-7-9 16:33:44

谢谢大佬啊,真是有志者事竟成。

474020794 发表于 2021-1-28 23:45:31

虽说我是小白,但是感觉楼主真的很牛,加油

deepfreeze 发表于 2020-11-7 00:11:00

代码太长了,没看完,不过我也就仅仅能看懂rc中断和时间的那一部分(好像是叫这个名)

王东阳 发表于 2020-10-20 15:52:20

膜拜,厉害了啊。

飞龙在天苏 发表于 2020-7-16 08:58:58

zxhgr 发表于 2017-3-6 20:35
遥控器 功能图片




楼主威武!!!厉害啦

haokanma77 发表于 2020-6-1 14:16:07

感觉特别厉害。绝对的高手

yinianwuyu 发表于 2020-5-4 14:22:30

感谢分享,这个是STM32的。厉害

wwee128 发表于 2020-4-22 20:23:24

编辑这么多,真是不容易啊

LoLoLo 发表于 2020-4-15 12:54:36

zxhgr 发表于 2017-3-7 13:08
谢谢,后续该造一款商品遥控器DIY

楼主棒棒的

wwee128 发表于 2020-4-15 12:21:36

这也太全了,流口水了,好好学习

zxhgr 发表于 2017-3-6 20:31:32

遥控器板http://www.moz8.com/data/attachment/album/201703/06/200018u8eg0a49phn8pa99.jpg

http://www.moz8.com/data/attachment/album/201703/06/200020xz1j913ahj9kzukk.jpg
http://www.moz8.com/data/attachment/album/201703/06/200021df7gai2lfvauilfb.jpg
http://www.moz8.com/data/attachment/album/201703/06/200022pdfdsddye6ydyd6x.jpg
http://www.moz8.com/data/attachment/album/201703/06/200023u9s9ngn4cjtxnzsv.jpg
http://www.moz8.com/data/attachment/album/201703/06/200023p33u55boscofm3ic.jpg
http://www.moz8.com/data/attachment/album/201703/06/200024uuc3dge6wwo77h3c.jpg

http://www.moz8.com/data/attachment/album/201703/06/200024rfkwrpzfs6g3kgfu.jpg

zxhgr 发表于 2017-3-6 20:33:24

外壳选择 改造

http://www.moz8.com/data/attachment/album/201703/06/200025yptcgzhh945550h5.jpg


http://www.moz8.com/data/attachment/album/201703/06/200026iig33fic5i5txhbh.jpg



http://www.moz8.com/data/attachment/album/201703/06/200026tlltr7wa7rw973rg.jpg



http://www.moz8.com/data/attachment/album/201703/06/200028vtrnxabcynpqctte.jpg






http://www.moz8.com/data/attachment/album/201703/06/200026ju3go3beug5l5fwf.jpg


http://www.moz8.com/data/attachment/album/201703/06/200027o6ld4gs2gd42kt6t.jpg


http://www.moz8.com/data/attachment/album/201703/06/200027h9w06dbvrvumqry7.jpg

星云 发表于 2017-3-6 20:35:31

罗莉4

zxhgr 发表于 2017-3-6 20:35:49

遥控器 功能图片
http://www.moz8.com/data/attachment/album/201703/06/200036o1csy7zjhcu1yhq8.jpg


http://www.moz8.com/data/attachment/album/201703/06/200035m2n2inn0zi29niuq.jpg


http://www.moz8.com/data/attachment/album/201703/06/200034kv3sn66st45d363v.jpg




http://www.moz8.com/data/attachment/album/201703/06/200033id3f2vu4gvdf4ift.jpg


http://www.moz8.com/data/attachment/album/201703/06/200032jrnntzhyddrrht8r.jpg


http://www.moz8.com/data/attachment/album/201703/06/200032kzbycsalzoc9bc95.jpg





http://www.moz8.com/data/attachment/album/201703/06/200031rc2a5vw7e74hfa4w.jpg


http://www.moz8.com/data/attachment/album/201703/06/200031lg9betcaram7m68b.jpg


http://www.moz8.com/data/attachment/album/201703/06/200030msz5jfrxwrs52swe.jpg


http://www.moz8.com/data/attachment/album/201703/06/200029ek7zp82ribgl13gn.jpg


http://www.moz8.com/data/attachment/album/201703/06/200029g69m6u66lmxhh166.jpg





zxhgr 发表于 2017-3-6 20:37:30

奉上原理图 和PCB图
http://www.moz8.com/data/attachment/album/201702/14/091841ofofsfyssffjfk05.jpg



http://www.moz8.com/data/attachment/album/201702/14/100815puw8tvru9zevu8wg.jpg



http://www.moz8.com/data/attachment/album/201702/14/092146m5f2d3tszt4dctyo.jpg


http://www.moz8.com/data/attachment/album/201702/14/100820te3q7l0krf4vfx14.jpg



zxhgr 发表于 2017-3-6 20:40:18

遥控器我采用的是STM32作为主控芯片,综合考虑这款芯片的性价比最高。无线发射与接收模块采用经济适用的24L01+模块,这款模块成本低,技术成熟、稳定性好空中传输速率选择在250K,以提高传输距离。采用跳频通讯方式能够很好地避开通讯中的信道冲突。理论上可以65535个遥控器仪器同时使用,相互不会产生干扰。
      采用硬件SPI通讯,使用W25X40 FLASH芯片作为存储单元。使用低成本的12864液晶作为显示单元。使用TL431基准芯片为ADC采样提供基准电压信号,是遥控器的ADC采集稳定可靠。左手油门和右手油门可以软件设定,但是需要硬件支持。
      ShockBurst模式下nRF24L01可以与成本较低的低速MCU相连高速信号处理是由芯片内部的射频协议处理的nRF24L01提供SPI接口数据率取决于单片机本身接口速度ShockBurst模式通过允许与单片机低速通信而无线部分高速通信减小了通信的平均消耗电流在ShockBurstTM接收模式下当接收到有效的地址和数据时IRQ通知MCU随后MCU可将接收到的数据从RX FIFO寄存器中读出 在ShockBurstTM发送模式下nRF24L01自动生成前导码及CRC校验。数据发送完毕后IRQ通知MCU减少了MCU的查询时间也就意味着减少了MCU 的工作量同时减少了软件的开发时间nRF24L01内部有三个不同的RX FIFO寄存器6个通道共享此寄存器和三个不同的TX FIFO寄存器在掉电模式下待机模式下和数据传输的过程中MCU可以随时访问FIFO寄存器这就允许SPI接口可以以低速进行数据传送并且可以应用于MCU硬件上没有SPI接口的情况下

遥控器支持模拟器,可以直接连接解密狗,输出标准的PPM信号。使用这个遥控器可以再电脑上模拟飞行。
下面接收遥控器和接收机之间的通许协议。通讯协议分为4种类型,分别是遥控器发出的PCM帧和广播帧。接收机发出的对码帧和数据帧。
遥控数据格式由32个字节数据组成。
遥控和接收机对码原理:
遥控器部分工作原理:遥控器上电后,首先检查上次对码的接收机信息,并发送上一次对码成功信息的地址,1秒后没有收到上次对码成功的接收机信息,遥控器会同时发送广播信息以接收其它接收机的配对信息。当遥控器接收到接收机的配对信息并确认后,停止发送广播信息。只发送接收机的信息。1秒以后仍然没有接收到信息,遥控器会扫频发送广播信息。
接收机部分工作原理:接收机上电后,首先检查上一次对码的遥控器信息,并等待接收遥控器信息。短接对码接口后,接收机会将广播地址打开,扫频接收广播信息。直到对码成功。

1.      遥控发出PCM信号格式
信号内容如下所示
第1字节:帧头0x5A
第2字节:帧头0xA5
第3字节:帧识别码0x00广播信息帧0x01 PCM信号帧 0x02 信息帧
第4字节:PCM通道数 遥控器发出的PCM通道取值范围4-16
第5-7字节 :CH1和CH2通道数据
第8-10字节 :CH3和CH4通道数据
第11-13字节 :CH5和CH6通道数据
第14-16字节 :CH7和CH8通道数据或者功能码
第17-19字节 :CH9和CH10通道数据或者功能码
第20-22字节 :CH11和CH12通道数据或者功能码 失控保护(CH1-CH2)
第23-25字节 :CH13和CH14通道数据或者功能码 失控保护(CH3-CH4)
第26-28字节 :CH15和CH16通道数据或者功能码 失控保护(CH5-CH6)
第29字节 : 频率表位置0-15
第30-31字节:识别码 遥控器地址最后2个字节以识别是否配对的遥控器发出指令
第32字节 :校验和 去除帧头和校验和之外的所有数据不记溢出累加和
图表如下所示
1-2Byte      3Byte      4Byte      5-13Byte      14-28 Byte      29Byte      30-31Byte      32Byte
帧头      帧识别码      PCM通道数      CH1-CH4通道      CH1-CH4通道或功能码      频率表位置      遥控器识别码      校验和

2.      遥控发出对码信号格式
信号内容如下所示
遥控器发出对码信号是在指定的地址发送,也就是遥控器和接收机有一个固定的广播地址,遥控器在没有对码成功之前,会定期的发送广播信号,时间间隔为1秒。向广播地址发送遥控器的信息。接收机在对码状态会接收该广播地址的信息,收到信息后,接收机发送要求配对请求给遥控器,遥控器允许后配对成功。
   第1字节:帧头0x5A
第2字节:帧头0xA5
第3字节:帧识别码0x00广播信息帧0x01 PCM信号帧 0x02 信息帧
       第4字节:遥控通道类别 如0x06说明6通道遥控器0x08说明8通道遥控器
       第5字节:操作方式 0 美国手1 日本手2 中国手3 自定义
第6字节:跳频频道数量
       第7-11字节:遥控器接收地址
       第12-27字节:跳频频率表 16个字节
       第28字节:遥控器类别
第29字节:频率表位置0-15   
第30-31字节:识别码 遥控器地址最后2个字节以识别是否配对的遥控器发出指令
第32字节 :校验和 去除帧头和校验和之外的所有数据不记溢出累加和


图表如下所示
1-2Byte      3Byte      4Byte      5Byte      6Byte      7-11Byte      12-27Byte      28Byte      29Byte      30-31Byte      32Byte
帧头      帧识别码      通道类别      操作方式      跳频数量      遥控接收地址      跳频频率表      遥控器类别      频率表位置      遥控器识别码      校验和
3.      接收机发出对码信号格式
信号内容如下所示
第1字节:帧头0x5A
第2字节:帧头0xA5
第3字节:帧识别码0x80对码信息帧0x82 信息帧
第4字节:跳频频道数量
第5字节:电池类别
第6字节:PPM通道数
第7-11字节:接收机数据接收地址
第12-27字节:跳频频率表 16个字节
第28字节:接收机类别码
第29字节: 频率表位置0-15
第30-31字节: 识别码 接收机地址最后2个字节以识别是否配对的接收机发出指令
第32字节 :校验和 去除帧头和校验和之外的所有数据不记溢出累加和
图表如下所示
1-2Byte      3Byte      4Byte      5Byte      6Byte      7-11Byte      12-27Byte      28Byte      29Byte      30-31Byte      32Byte
帧头      帧识别码      跳频频道数量      电池类别      PPM通道数      接收机接收地址      跳频频率表      接收机类别码      频率表位置      接收机识别码      校验和
4.      接收机发出的数据信号格式
信号内容如下所示
第1字节:帧头0x5A
第2字节:帧头0xA5
第3字节:帧识别码0x80对码信息帧0x82 信息帧
第4字节:接收机对码遥控类别次数 不同遥控器次数
第5字节:电池类别
第6字节:PPM通道数
第7字节:接收机类别码
第8-9字节:电池电压
第10-11字节:电池电流
第12-28字节:功能扩展
第29字节 :频率表位置0-15
第30-31字节: 识别码 接收机地址最后2个字节以识别是否配对的接收机发出指令
第32字节 :校验和 去除帧头和校验和之外的所有数据不记溢出累加和
图表如下所示
1-2Byte      3Byte      4Byte      5Byte      6Byte      7Byte      8-9Byte      10-11Byte      12-28Byte      29Byte      30-31Byte      32Byte
帧头      帧识别码      对码次数      电池类别      PPM通道数      接收机类别码      电池电压      电池电流      功能扩展      频率表位置      接收机识别码      校验和


遥控器软件选择FreeRTOS,现将部分代码分享出来
int main(void)
{      
         __set_PRIMASK(1);//关全局中断
      
   W25_dat.Sector=0xffff;//设置W25x40内存数据不可用
      
   BSP_Config();//硬件及软件配置
   
         AppResourcesInit();//任务资源初始化      
      
   #if TASK_DEBUG
         xTaskCreate(Simulation_Task,"Simulation_Task1",512,NULL,1,NULL);      //仿真调试监视任务
         xTaskCreate(UartDebug_Task,"UartDebug_Task",512,NULL,3,NULL);      //串口仿真调试监视任务
         UartRxQueue = xQueueCreate(10, sizeof(P_DAT) );//创建串口接收队列
   #endif
         xTaskCreate(Dog_Task,"Dog_200mS",256,NULL,5,NULL);      //看门狗监视任务         
         xTaskCreate(AppInit_Task,"AppInit",512,NULL,9,&AppInitHandleTaskStart);      //应用初始化任务
         
      
         
   
         vTaskStartScheduler();//开始调度任务
      while(1)
      {}
}
void AppInit_Task( void *pvParameters )          //应用初始化任务
{

      #if TASK_DEBUG      
u8 buf;
      #endif
portTickType xLastWakeTime;         
      const TickType_t xTicksToWait = 50 / portTICK_PERIOD_MS; /* 延迟50ms */
      xLastWakeTime=xTaskGetTickCount();//获取当前心跳值         
      #if TASK_DEBUG               
   DPrintfGetTheKey(); //获取打印资源                        
               DPrintf("\r\n初始化任务已经启动\r\n");                        
   DPrintfGiveUpKey();//释放打印资源                        
      #endif
      
for( ;; )
      {                  
                vTaskDelayUntil(&xLastWakeTime,xTicksToWait);
               
    Spi2GetTheKey();//获取Spi2的钥匙               
   
                /**********************FLASH芯片初始化************************/
                W25_dat.ChipID=W25_DeviceID();//读取芯片的8位型号ID唤醒芯片               
                W25_dat.Jedec_Id=W25_JEDEC_ID();//读取芯片的制造商ID和16位型号ID
    if(W25_ReadSector(0)==0)W25_ReadSector(0);//读指定扇区的数据到内存 如果失败在读取一次
               
                if((W25_dat.page!=0x18)||(W25_dat.page!=0x18))//判断FLASH是否需要初始化
               {//以下更新内存
                         W25_dat.page=0x18;W25_dat.page=0x18;
                         ee_wrfun();//初始化写EE数据
                         for(;W25_WeadeSector()==0;);//将内存的数据写入FLASH                                 
               }
                else//读取已经初始化的数据
                {
                        ee_rdfun();//初始化读EE数据
                }               
                Spi2GiveUpKey();//归还Spi2的钥匙
               
                /***************打印输出初始化数据*****************/
                #if TASK_DEBUG               
   DPrintfGetTheKey(); //获取打印资源                        
               DPrintf("\r\nFLASH初始化完成\r\n");                                 
               U8_Uchar(&W25_dat.ChipID,buf,3);buf='\r';buf='\n';buf=0;
               DPrintf("\r\nFLASH ID编号:");DPrintf((const signed char *)buf);               
               
               DPrintf("\r\n初始化任务删除自身任务\r\n");                        
   DPrintfGiveUpKey();//释放打印资源                        
                #endif      
    LcmInit();//液晶初始化?
    lcd_rst_flag=1;//液晶完成初始化
                AppTaskCreate();//创建任务
                vTaskDelete(AppInitHandleTaskStart);//应用初始化任务执行一次后删除任务
      }
}
void Dog_Task( void *pvParameters )          //看门狗监视任务
{
EventBits_t uxBits;
portTickType xLastWakeTime;         
      const TickType_t xTicksToWait = 200 / portTICK_PERIOD_MS; /* 延迟200ms */
      xLastWakeTime=xTaskGetTickCount();//获取当前心跳值
      /*
          开始执行启动任务主函数前使能独立看门狗。
          设置LSI是128分频,下面函数参数范围0-0xFFF,分别代表最小值3.2ms和最大值13107.2ms
          下面设置的是1s,如果1s内没有喂狗,系统复位。
      */
      bsp_InitIwdg(0x138);

#if TASK_DEBUG      
    DPrintfGetTheKey(); //获取打印资源                        
                DPrintf("\r\n监视任务已经启动 \r\n");               
    DPrintfGiveUpKey();//释放打印资源      
#endif
for( ;; )
      {   
                vTaskDelayUntil(&xLastWakeTime,xTicksToWait);
    /* 等待所有任务发来事件标志 */
                uxBits = xEventGroupWaitBits(DogEventGroup, /* 事件标志组句柄 */
                                                               TASK_BIT_0_1,       /* 等碩ASK_BIT_0_1被设置 */
                                                               pdTRUE,             /* 退出前TASK_BIT_0_1被清除,这里是TASK_BIT_0_1都被设置才表示“退出”*/
                                                               pdTRUE,             /* 设置为pdTRUE表示等待TASK_BIT_0_1都被设置*/
                                                               xTicksToWait);          /* 等待延迟时间 */
               
                if((uxBits & TASK_BIT_0_1) == TASK_BIT_0_1)
                {
                        IWDG_Feed();//喂狗                        
                        #if TASK_DEBUG               
      //DPrintfGetTheKey(); //获取打印资源      
                        //DPrintf("喂狗成功\r\n");      
      //DPrintfGiveUpKey();//释放打印资源                        
                        #endif                        
                }
          else
                {
                        #if TASK_DEBUG      
      //DPrintfGetTheKey(); //获取打印资源                        
                        //DPrintf("等待喂狗指令\r\n");      
   // DPrintfGiveUpKey();//释放打印资源                                       
                        #endif               
                }
      }
}
void UartDebug_Task( void *pvParameters )//串口仿真调试任务
{
      u8 buf;
P_DAT p_dat;      
      u16 len;
      for(;;)
      {
                xQueueReceive(UartRxQueue,&p_dat,portMAX_DELAY);
               
                if(p_dat.id==1)                        
                {
                        len=UsartTaskRead(&p_dat,buf,USART1_MAX_LEN);//解析读取数据
                        Uart1GetTheKey();//获取串口1的钥匙
                        Usart1Tx(buf,len);         //发送数据      
                        Uart1GiveUpKey();//归还串口1的钥匙                        
                }               
      }
      
}
void Simulation_Task( void *pvParameters )//仿真调试监视任务
{
      portTickType xLastWakeTime;         
uint8_t pcWriteBuffer;
      const TickType_t xTicksToWait = 5000 / portTICK_PERIOD_MS; /* 延迟5000ms */
      xLastWakeTime=xTaskGetTickCount();//获取当前心跳值

      DPrintfGetTheKey(); //获取打印资源      
      DPrintf("\r\n仿真任务已经启动 \r\n");               
DPrintfGiveUpKey();//释放打印资源

      for(;;)
      {
                vTaskDelayUntil(&xLastWakeTime,xTicksToWait);//延迟10s

                DPrintfGetTheKey(); //获取打印资源
                DPrintf("=================================================\r\n");
                DPrintf("   任务名称任务状态 优先级剩余栈任务序号 \r\n\r\n");
                vTaskList( (char *)&pcWriteBuffer );                                                
                DPrintf((const signed char *)pcWriteBuffer);
               
                DPrintf("=================================================\r\n");
                DPrintf("任务名称   运行计数      使用效率 \r\n\r\n");
                vTaskGetRunTimeStats( (char *)&pcWriteBuffer );                                                
                DPrintf((const signed char *)pcWriteBuffer);      
               
                DPrintfGiveUpKey();//释放打印资源
      }
      
}
void AppTaskCreate(void)//创建任务
{
      RF2401xQueue = xQueueCreate(10, sizeof(RF_DAT) );//创建RF接收队列
      xTaskCreate(Task0,"Task0",512,NULL,3,NULL);
      xTaskCreate(ADC_Task,"ADC_Task",256,NULL,8,NULL);      
      xTaskCreate(URT_DEBUG_Task,"URT_DEBUG_Task",512,NULL,5,NULL);
      xTaskCreate(NRF2401_Task,"NRF2401_Task",512,NULL,9,NULL);
      xTaskCreate(NRF2401TX_Task,"NRF2401TX_Task",512,NULL,9,NULL);//最高优先级
      xTaskCreate(Task_lcd,"Task_lcd",512,NULL,3,NULL);
      xTaskCreate(Tim5mS_Task,"Tim10mS",512,NULL,8,NULL);      //5毫秒定时器任务
      
}

void Tim5mS_Task( void *pvParameters )          //5毫秒定时器任务
{ u8 i,rf_da;
      RF_DATrf_dat;
portTickType xLastWakeTime;         
      const TickType_t xTicksToWait = 5/ portTICK_PERIOD_MS; /* 延迟5ms */
      xLastWakeTime=xTaskGetTickCount();//获取当前心跳值
for( ;; )
      {                  
                vTaskDelayUntil(&xLastWakeTime,xTicksToWait);//延迟5ms
                rf_da++;
    if(rf_da>=2){rf_da=0;rf_dat.id=1; rf_dat.p=NULL;xQueueSend(RF2401xQueue,&rf_dat,pdPASS);}
               
    if(bz_con){bz_con--;GPIO_SetBits(GPIOA,GPIO_Pin_12);}//蜂鸣器控制
    else{GPIO_ResetBits(GPIOA,GPIO_Pin_12);}
                              
    key_bmbuf=GPIO_ReadInputData(GPIOB);
                key_bmcnt++;if(key_bmcnt>=20){key_bmcnt=0;if(key_bmflag==0){key_bmflag=1;for(i=0;i<50;i++){key_bmbuff=key_bmbuf;}}}
                UsartRxQuery();//串口接收查询函数      
                /* 发送事件标志,表示任务正常运行 */
                xEventGroupSetBits(DogEventGroup, TASK_BIT_1);
      }
}

Mr-iuy 发表于 2017-3-6 20:43:11

大神贴看不懂

枫飞秋语 发表于 2017-3-6 20:46:44

星云 发表于 2017-3-6 20:35
罗莉4

真的假的????

一般不扯淡 发表于 2017-3-6 20:47:11

代码一行都不懂,帮顶

gdf1 发表于 2017-3-6 20:57:59

楼主最好来个bom元件表,这个控支持6或9 模式控制输出吗?

5bWpwjPFQK 发表于 2017-3-6 21:13:37

拿别人的东西来装b。

52myzb 发表于 2017-3-6 21:36:03

枫飞秋语 发表于 2017-3-6 20:46 static/image/common/back.gif
真的假的????

假的,萝莉说了,4代也是51的,stc新出的单片机,所以萝莉还在等车,哈哈

落木。 发表于 2017-3-6 22:04:07

希望楼主出个教程,像萝丽大神那样的

忽远忽近 发表于 2017-3-6 22:20:31

厉害了我的国

boblhl 发表于 2017-3-6 22:50:01

这些代码我不认识它们,但它们肯定认识我,能来点实际的东西不

螺丝 发表于 2017-3-6 23:30:54

非常好

adikesi 发表于 2017-3-6 23:54:06

楼主真的太厉害了!帅呆了

wjl992006 发表于 2017-3-7 07:52:56

不错不错学习了

zxhgr 发表于 2017-3-7 08:09:21

看看 回复的帖子 有贬 有鼓励 ,再次我要申明以下几点:1、以上发布的材料和图片资料都是本人设计制作 2、对于有些人说抄袭之类的话语 我只能说肤浅。3、资料整理之后我可以开源上传到到本论坛。4、材料清单可以开源 5、材料采购清单及采购厂商都可以发布出来 。

一切为了交流心得 希望志同道合的朋友一起交流 完善

页: [1] 2 3 4 5 6 7
查看完整版本: 图解DIY航模遥控器和接收机