找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3262|回复: 1
收起左侧

红外调制解调协议stm32源码

[复制链接]
ID:366223 发表于 2018-7-6 12:40 | 显示全部楼层 |阅读模式
红外通信源码
  1. #include "include.h"

  2. /********************************************************************
  3. 发送红外数据的逻辑协议在"ir.c"里面         -->   _deflag处查找                        *                                                                                                                                                                                                                                                                                                               
  4. *********************************************************************/

  5. u16 tempi = 0;
  6. u8 IR_val = 0;

  7. int main(void)
  8. {
  9. //        u8 i;
  10.        
  11.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2       
  12.         uart_init(9600);
  13.         delay_init();
  14.        
  15.         ir_re_init(); //IR接收初始化        PA1--TIM5--CH2
  16.         TIM3_2PWM_Init(1893,0);//不分频。PWM频率=38Khz //IR -- PWM发射初始化  PA7--TIM3--CH2
  17.        
  18.         KEY_Init();
  19.         LED_Init();
  20.        
  21.         LED0=0;

  22.         while(1)
  23.         {       
  24.                 if(tempi >= 250)
  25.                 {
  26.                         tempi = 1;                               
  27.                 }
  28.                 IR_sent(tempi);
  29.                 printf("1:%d\r\n",tempi);

  30.                 if(IR_receive_finish(&IR_val) == 0)
  31.                 {
  32.                         LED1=0;
  33.                         if(tempi==IR_val)
  34.                         {
  35.                                 tempi += 1;
  36.                                
  37.                                 printf("2:%d\r\n",IR_val);

  38.                         }
  39.                         delay_ms(100);

  40. //                        uart1_printf("recev",IR_RXBUff,16);  //串口1打印出数组tab内的16个数据
  41.                 }
  42.                 LED1=1;
  43.                 LED0=1;               
  44.         }
  45. }
复制代码
  1. #include "ir.h"

  2. //[7]:保留
  3. //[6]:保留
  4. //[5]://标记下降沿是否已经被捕获
  5. //[4]://标记上升沿是否已经被捕获                                                                  
  6. //[3:0]:溢出计时器
  7. u8 key_sta=0;
  8. u16 LOW_value=0;
  9. u16 HIGH_value=0;
  10. u16 ii=0;

  11. u16 tab[500];
  12. u16 IR_RXBUff[500];
  13. //u16 IR_TXBUff[500];

  14. u8 num_b[8] = {0};                      //十进制转二进制数组
  15. u16 num_val[16] = {0};                        //发送数组



  16. void ir_re_init(void)                   //IR接收初始化        PA1--TIM5--CH2
  17. {
  18.         GPIO_InitTypeDef GPIO_InitStructure;
  19.         NVIC_InitTypeDef NVIC_InitStructure;
  20.         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  21.         TIM_ICInitTypeDef TIM_ICInitStructure;
  22.        
  23.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  24.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
  25.        
  26.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  27.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
  28.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  29.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  30.        
  31.         TIM_TimeBaseStructure.TIM_Period = 0XFFFF; //设定计数器自动重装值 最大10ms溢出  
  32.         TIM_TimeBaseStructure.TIM_Prescaler =(72-1);         //预分频器,1M的计数频率,1us加1.          
  33.         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  34.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

  35.         TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
  36.        
  37.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;
  38.         TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling;//下降沿触发
  39.         TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
  40.         TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
  41.         TIM_ICInitStructure.TIM_ICFilter=0x00;
  42.         TIM_ICInit(TIM5,&TIM_ICInitStructure);
  43.        
  44.         TIM_Cmd(TIM5,ENABLE);
  45.        
  46.         NVIC_InitStructure.NVIC_IRQChannel= TIM5_IRQn;
  47.        
  48.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
  49.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
  50.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  51.         NVIC_Init(&NVIC_InitStructure);
  52.        
  53.         TIM_ITConfig( TIM5,TIM_IT_CC2,ENABLE);
  54. }



  55. void TIM5_IRQHandler(void)              //IR接收中断
  56. {
  57.   if(TIM_GetFlagStatus(TIM5, TIM_FLAG_CC2) == SET)//触发中断                    
  58.         {               
  59.                 if(R_DATA==1)
  60.                 {
  61.                         if(key_sta&0x20)
  62.                         {
  63.                                 LOW_value=TIM_GetCapture2(TIM5);
  64.                                 IR_RXBUff[ii]=LOW_value;
  65.                                 ii++;
  66.                                 TIM_SetCounter(TIM5, 0);//清零计数器的值
  67.                                 TIM_OC2PolarityConfig(TIM5, TIM_ICPolarity_Falling);
  68.                                 key_sta&=0xdf;//下降沿捕获清除             清除 0x20
  69.                         }
  70.                         key_sta|=0x10;//上升沿被成功捕获              标记0x10       
  71.                 }
  72.                 else if(R_DATA==0)
  73.                 {
  74.                         if(key_sta&0x10)
  75.                         {
  76.                                 HIGH_value=TIM_GetCapture2(TIM5);
  77.                        
  78.                                 IR_RXBUff[ii]=HIGH_value;
  79.                                 ii++;       
  80.                                 key_sta&=0xef;//上升沿捕获清除            清除0x10
  81.                         }
  82.                         TIM_SetCounter(TIM5, 0);//清零计数器的值
  83.                         TIM_OC2PolarityConfig(TIM5, TIM_ICPolarity_Rising);
  84.                         key_sta|=0x20;//下降沿被成功捕获            标记 0x20       
  85.                 }               
  86.         }
  87.          TIM_ClearFlag(TIM5,TIM_IT_CC2);
  88. }

  89. //0为成功
  90. u8 IR_receive_finish(u8 *p)     //IR接收完成标志  (此处给的10ms等待)
  91. {
  92.         u8 i,j;
  93.         u8 val_t = 0;
  94.         u16 k=0;
  95.        
  96.         while(ii<=10 && k<50000)   //等待开始接收数据,50ms没有收到数据就跳出
  97.         {
  98.                 k++;
  99.                 delay_us(1);
  100.         }
  101.         delay_ms(30);
  102. //        printf("%d\r\n",ii);
  103.     if(ii>20)
  104.         {
  105.                 delay_ms(500);
  106.         }
  107. //        printf("%d\r\n",ii);
  108.         if(ii>=15 && k<50000)
  109.         {
  110.                 for(i=0;i<16;i+=2)                       //把38k波解调成逻辑0|1   存到一个字节的各个位
  111.                 {
  112.                         if((IR_RXBUff[i]>=Half_IR)||(IR_RXBUff[i+1]>=Half_IR))
  113.                         {
  114.                                 num_b[i/2] = 1;
  115.                         }
  116.                         else if((IR_RXBUff[i]<Half_IR)&&(IR_RXBUff[i+1]<Half_IR))
  117.                         {
  118.                                 num_b[i/2] = 0;
  119.                         }
  120.                 }
  121.                
  122.                 for(j=0;j<8;j++)                       //把2进制数变为十进制数
  123.                 {
  124.                         if(num_b[j]==1)
  125.                         {
  126.                                 val_t |= 1<<j;
  127.                         }
  128.                 }
  129.                 *p = val_t;
  130.                 ii = 0;
  131.                 key_sta = 0;
  132.                 return 0;
  133.         }
  134.         return 1;
  135. }



  136. //PWM输出初始化
  137. //arr:自动重装值
  138. //psc:时钟预分频数
  139. void TIM3_2PWM_Init(u16 arr,u16 psc)    //IR -- PWM发射初始化  PA7--TIM3--CH2
  140. {  
  141.         GPIO_InitTypeDef         GPIO_InitStructure;
  142.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  143.         TIM_OCInitTypeDef        TIM_OCInitStructure;

  144.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//
  145.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能
  146.                                                                                     
  147.    //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
  148.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PA7--TIM3--CH2
  149.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
  150.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  151.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  152.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K
  153.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
  154.         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  155.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  156.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  157.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  158.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  159.         TIM_OCInitStructure.TIM_Pulse =0; //设置待装入捕获比较寄存器的脉冲值
  160.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High  ; //输出极性:TIM输出比较极性高
  161.        
  162.         TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //☆注意这块的通道数的选择☆

  163.         TIM_Cmd(TIM3, ENABLE);  //使能TIM4
  164. }





  165. void IR_sent(u8 val)                                                                                //IR发射   (5ms发完16位)
  166. {
  167.         u8 jj=0;
  168.         u8 i,j,k=0;
  169.        
  170.         //IR发射前要关闭红外接收,防止干扰频繁进中断导致单片机hard fuilt
  171.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,DISABLE);   //IR接收初始化 PA1--TIM5--CH2
  172.         //IR发射前要关闭红外接收,防止干扰频繁进中断导致单片机hard fuilt
  173.        
  174.         for(i=0;i<8;i++)       //把十进制数字变为二进制数字  
  175.         {
  176.                 if( ( val&(1<<i) ) )     
  177.                 {
  178.                         num_b[i] = 1;   
  179.                 }
  180.                 else
  181.                 {
  182.                         num_b[i] = 0;
  183.                 }
  184.         }
  185. //调制数据
  186.         for(k=0;k<16;k+=2)      //把将二进制的各个位的逻辑0|1加载到38k红外波上 _deflag
  187.         {
  188.                 j=k/2;
  189.                 if(num_b[j]==1)
  190.                 {
  191.                         num_val[k]   = L_IR;
  192.                         num_val[k+1] = H_IR;
  193.                 }
  194.                 else if(num_b[j]==0)  //为0
  195.                 {
  196.                         num_val[k]   = L_IR;
  197.                         num_val[k+1] = L_IR;
  198.                 }       
  199.         }
  200.        
  201.         LED0 = 0;
  202.        
  203.         for(jj=0;jj<16;jj+=2)    //PWM发射初始化  PA7--TIM3--CH2
  204.         {
  205.                 if(num_val[jj]==0)
  206.                 {
  207.                         TIM_SetCompare2(TIM3,0);
  208.                 }
  209.                 else
  210.                 {
  211.                         if(num_val[jj]!=0)
  212.                         {
  213.                                 TIM_SetCompare2(TIM3,(1893/3));                                                       
  214.                                 delay_us(num_val[jj]);       
  215.                                 TIM_SetCompare2(TIM3,0);
  216.                                 if(num_val[(jj+1)]!=0)
  217.                                 {
  218.                                         TIM_SetCompare2(TIM3,0);                                       
  219.                                         delay_us(num_val[(jj+1)]);//程序死在这里了                                                               
  220.                                 }       
  221.                         }
  222.                 }
  223.         }
  224.         TIM_SetCompare2(TIM3,(1893/3));       
  225.         delay_us(200);
  226.         TIM_SetCompare2(TIM3,0);

  227.         //IR发射前要关闭红外接收,防止干扰频繁进中断导致单片机hard fuilt
  228.         delay_ms(1);        //延时1毫秒下面这句时钟使能才会有效.
  229.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  //IR接收初始化 PA1--TIM5--CH2
  230.         //IR发射前要关闭红外接收,防止干扰频繁进中断导致单片机hard fuilt
  231.        
  232.         LED0 = 1;
  233. }
复制代码


全部资料51hei下载地址:
红外调制解调协议源码.rar (364.8 KB, 下载次数: 40)

回复

使用道具 举报

ID:391196 发表于 2019-7-25 11:03 | 显示全部楼层
找了好久,非常感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表