[STM32] 基于STM32和hs1527、ev1527、rt1527、fp1527的无线接收解码程序

[复制链接]
 楼主| 感动 发表于 2020-7-18 15:12 | 显示全部楼层 |阅读模式




1527的数据帧结构
无线遥控的编码,从编码类型上来说,分为2类,一类是固定码,也就是编码芯片的地址是不变的,芯片型号以 hs1527、ev1527、rt1527、fp1527、PT2262 为代表。另一种是滚动码,芯片的地址码是变化的,芯片以HS300、HS301为代表。
1 1527 数据帧结构
1527 是一片由 CMOS 设计制造的可预烧内码的学习码编码IC ,由软件解码;内码共有 20 个位元可预烧 1048576 组内码组合,降低使用上编码重复的机率。
1527 每帧数据由 24 个数据位组成,前 20 位为地址码,对于一个芯片来说,地址位的内容是固定的,是出厂前就预制好的,并且理论上每个芯片的地址码是唯一的。后面 4 位为按键码,对应芯片上的K0-K3 4 根数据线,数据线的状态不同,按键码就不同。
在数据位之前,还有一个同步脉冲,也就是每帧数据都是从同步
脉冲开始的。数据位的“1”和“0”是由高低电平宽度(脉冲宽度)的比例决定的。如果高电平宽度为低电平宽度的 3 倍,就表示逻辑“1”,反过来如果低电平为高电平宽度的 3 倍,就表示逻辑“0”。同步脉冲高电平和低电平的比例固定为 4:124.




二、中断方式的解码
把串行输入的编码数据帧,还原成编码之前的状态,读取其中
的地址码和按键码,称之为解码。
数据帧都是由同步头开始,然后是 24位的数据码,并且此数据帧在遥控器按键的过程中是重复出现的,我们首先要判断同步码,判断出了同步码,就知道数据码是从那一位开始了。对于一款量产的无线遥控器来说,他的编码芯片匹配的电阻是一个固定值,也就是说它发射的数据帧的脉冲宽度是不变的,所以我们可以通过测量高低脉冲宽度的方式来分辨同步码、逻辑“1”、逻辑“0”。
具体的方法是这样的,首先启用定时器,装入一个初值,打开
定时器中断,让其以固定的间隔进入中断程序。在中断程序中,我们查询数据输入管脚的状态,如果为高电平,就在高电平状态累加计数,反之就在低电平状态计数,当电平发生上升沿变化的时候,判断接收到的高低电平宽度的值是否符合同步信号的要求,如果符合就进入数据位的接收,以同样的方式判断逻辑“1”或逻辑“0”。如果接受过程中出现不符合要求的电平状态,就退出接收,为了增加可靠性,我们一般要求规定时间内,成功接收到完全相同的 2 帧数据才算有效。
接收完成后,24 个数据位被放入 3 个字节中。下一步我们要对接收到的数据进行处理,判断编码的类型,分离地址码和按键码。
代码如下


  1. #include "1527.h"   

  2. /**
  3.   * [url=home.php?mod=space&uid=247401]@brief[/url]  初始化控制LED的IO
  4.   * @param  无
  5.   * @retval 无
  6.   */
  7. uint8_t RF;
  8. uint8_t decode_ok;            //解码成功
  9. uint8_t  hh_w,ll_w;           //高,低电平宽度
  10. uint8_t  ma_x;                //接收到第几位编码了
  11. uint8_t  bma1,bma2,bma3,bma4; //用于接收过程存放遥控编码,编码比较两次,这是第一次
  12. uint8_t  mma1,mma2,mma3,mma4;
  13. uint8_t mmb1,mmb2,mmb3,mmb4; // 用于接收过程存放遥控编码,第二次
  14. //extern uint8_t mmb1,mmb2,mmb3,mmb4;

  15. uint8_t rf_ok1,rf_ok2,rf_ok;         //解码过程中的临时接收成功标志,接收到一个完整的遥控命令后置1,通知解码程序可以解码了
  16. uint8_t old_rc5;             //保存上一次查询到的电平状态
  17. uint8_t tb_ok;               //接收到同步的马时置1   
  18. uint8_t D0,D1,D2,D3 ;
  19. uint16_t s ,s1;
  20. uint8_t bt_auto;     //自动设置遥控接收波特率标志
  21. extern uint8_t rf_data[4];
  22.        
  23. void 1527_Init() //1527 IO口初始化
  24. {
  25.         GPIO_InitTypeDef GPIO_InitStruct;
  26.         NVIC_InitTypeDef NVIC_InitStructure;
  27.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  28.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  29.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  // PB9 输入端
  30.         GPIO_InitStruct.GPIO_Pin     = GPIO_Pin_9;
  31.         GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_IN_FLOATING;
  32.         GPIO_InitStruct.GPIO_Speed   = GPIO_Speed_50MHz;
  33.         GPIO_Init(GPIOB, &GPIO_InitStruct);

  34.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  35.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  36.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
  37.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  38.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  39.         NVIC_Init(&NVIC_InitStructure);

  40.         TIM_TimeBaseStructure.TIM_Period = 100;
  41.         TIM_TimeBaseStructure.TIM_Prescaler =7;                                                                                   
  42.         TIM_TimeBaseStructure.TIM_ClockDivision =        
  43.         TIM_CKD_DIV1;
  44.         TIM_TimeBaseStructure.TIM_CounterMode =
  45.         TIM_CounterMode_Up;
  46.         TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  47.         TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
  48.         TIM_ClearFlag(TIM4,TIM_FLAG_Update);
  49.         TIM_Cmd(TIM4,ENABLE );  
  50. }
  51. void TIM4_IRQHandler()
  52. {
  53.     if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  54.     {
  55.         TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

  56.         //接收数据的电平 PB9
  57.         RF = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9);
  58.         if (!RF)
  59.         {
  60.             ll_w++;   // 检测到低电平 低电平时间加1,记录本次电平状态old_rc5
  61.             old_rc5=0;
  62.         }               
  63.          else         // 检测到高电平
  64.          {
  65.             hh_w++;
  66.             if (!old_rc5)  // 检测到从低到高的跳变,已检测到一个完整(高-低)电平周期 判同步码    2/5 100/130
  67.             {   
  68.                 if (((hh_w>=2)&&(hh_w<=5))&&((ll_w>=100)&&(ll_w<=130)))
  69.                 {
  70.                     tb_ok = 1 ;
  71.                     ma_x = 0;
  72.                     bma1=0; bma2=0; bma3=0; bma4=0;   
  73.                 }
  74.                 else if ((tb_ok)&&((ll_w>=8)&&(ll_w<=13))) //8/13
  75.                 {   
  76.                     ma_x++; //已经接收到同步码,判0
  77.                     if(ma_x>23)
  78.                     {
  79.                         if(!rf_ok1) //rf_ok1临时接收成功
  80.                         {   //将接收到的编码复制到解码寄存器中
  81.                             mma1=bma1;
  82.                             mma2=bma2;
  83.                             mma3=bma3;
  84.                             mma4=bma4;
  85.                             // 通知解码子程序可以解码了                                                        
  86.                             rf_ok1=1;                    
  87.                             tb_ok=0;
  88.                             s=1000;                             
  89.                             }
  90.                             else
  91.                             {//将接收到的编码复制到解码寄存器中  
  92.                                 mmb1=bma1;
  93.                                 mmb2=bma2;
  94.                                 mmb3=bma3;
  95.                                 mmb4=bma4;  
  96.                                 // 通知解码子程序可以解码了                                             
  97.                                 rf_ok2=1;                     
  98.                                 tb_ok=0;                                                                        
  99.                             }
  100.                         }
  101.                      }  
  102.                      else if ((tb_ok)&&((ll_w>=2)&&(ll_w<=7)))   // 2/7
  103.                      {
  104.                          switch (ma_x)
  105.                          {
  106.                          case 0 : { bma1=bma1 | 0x80;
  107.                              break; }   //遥控编码第1位
  108.                          case 1 : { bma1=bma1 | 0x40;  
  109.                              break; }
  110.                          case 2 : { bma1=bma1 | 0x20;
  111.                              break; }
  112.                          case 3 : { bma1=bma1 | 0x10;
  113.                              break; }
  114.                          case 4 : { bma1=bma1 | 0x08;
  115.                              break; }
  116.                          case 5 : { bma1=bma1 | 0x04;
  117.                              break; }
  118.                          case 6 : { bma1=bma1 | 0x02;
  119.                              break; }
  120.                          case 7 : { bma1=bma1 | 0x01;
  121.                              break; }
  122.                          case 8 : { bma2=bma2 | 0x80;
  123.                              break; }
  124.                          case 9 : { bma2=bma2 | 0x40;
  125.                              break; }
  126.                          case 10: { bma2=bma2 | 0x20;
  127.                              break; }
  128.                          case 11: { bma2=bma2 | 0x10;
  129.                              break; }
  130.                          case 12: { bma2=bma2 | 0x08;
  131.                              break; }
  132.                          case 13: { bma2=bma2 | 0x04;
  133.                              break; }
  134.                          case 14: { bma2=bma2 | 0x02;
  135.                              break; }
  136.                          case 15: { bma2=bma2 | 0x01;
  137.                              break; }
  138.                          case 16: { bma3=bma3 | 0x80;
  139.                              break; }
  140.                          case 17: { bma3=bma3 | 0x40;
  141.                              break; }
  142.                          case 18: { bma3=bma3 | 0x20;
  143.                              break; }
  144.                          case 19: { bma3=bma3 | 0x10;
  145.                              break; }
  146.                          case 20: { bma3=bma3 | 0x08;
  147.                              break; }// 按键状态第1位
  148.                          case 21: { bma3=bma3 | 0x04;
  149.                              break; }
  150.                          case 22: { bma3=bma3 | 0x02;
  151.                             break; }
  152.                          case 23: { bma3=bma3 | 0x01;              
  153.                                   if(!rf_ok1)
  154.                                   {
  155.                                       mma1=bma1;
  156.                                       mma2=bma2;
  157.                                       mma3=bma3;
  158.                                    // mma4=bma4;                                           // 将接收到的编码复制到解码寄存器中                             
  159.                                      rf_ok1=1;         // 通知解码子程序可以解码了
  160.                                      tb_ok=0;
  161. //                                   bt_auto=0;
  162.                                      s=1000;
  163.                                      break;                                 
  164.                                   }
  165.                                   else
  166.                                   {
  167.                                       mmb1=bma1;
  168.                                       mmb2=bma2;
  169.                                       mmb3=bma3;
  170.                                     //mmb4=bma4;               // 将再次接收到的编码复制到解码寄存器中,                             
  171.                                     rf_ok2=1;                                      // 通知解码子程序可以解码了
  172.                                     tb_ok=0;
  173.                                     break;                                                                          
  174.                                  }                                    
  175.                          }
  176.                     }
  177.                     ma_x++;
  178.                  }
  179.                  else
  180.                  {ma_x=0; tb_ok=0;bt_auto=0;bma1=0;bma2=0; bma3=0; hh_w=1;ll_w=0;}                                      //接收到不符合的高-低电平序列
  181.                  ll_w=0;hh_w=1;
  182.              }         
  183.              old_rc5=1;      // 记录本次电平状态
  184.        }
  185.        if(rf_ok1)  //规定时间内接受到2帧相同的编码数据才有效
  186.         {
  187.             s--;
  188.             if(!s) rf_ok1=0;
  189.             if(rf_ok2)
  190.             {
  191.             if((mma1==mmb1)&&(mma2==mmb2)&&(mma3==mmb3))
  192.             {
  193.                 rf_ok=1;
  194.                 rf_ok1=0;
  195.                 rf_ok2=0;                    
  196.             }
  197.             else
  198.             {
  199.                 rf_ok=0;
  200.                 rf_ok1=0;
  201.                 rf_ok2=0;

  202.              }         
  203.         }                  
  204.     }

  205.     if((rf_ok))      //判断是否接收成功
  206.     {   
  207.         //TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
  208.         rf_ok=0;
  209.         rf_data[0]=mma1;
  210.         rf_data[1]=mma2;
  211.         rf_data[2]=mma3;

  212.         decode_ok=1;

  213.         //TIM_ITConfig(TIM4  , TIM_IT_Update, ENABLE);
  214.         }
  215.     }

  216. }


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
zeshoufx 发表于 2020-7-20 08:50 | 显示全部楼层
谢谢分享【无线接收解码】
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:关注我的博客https://blog.csdn.net/gd1984812 淘宝店 https://shop570248211.taobao.

35

主题

57

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部