找回密码
 注册

QQ登录

只需一步,快速开始

搜索

stm32做的红外万能遥控器带自学习复制,亲测可用控制空调

[复制链接]
路漫漫 发表于 2020-5-20 20:29:25 | 显示全部楼层 |阅读模式
红外接收头收到红外码后马上发送一个一样的红外码出去,需要做万能遥控的自行保存红外码再发出去即可
完整源码: stm32红外万年遥控自学习源码.zip (315.74 KB, 售价: 2 E币)
部分源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "Infrared.h"


  6. int main(void)
  7. {        
  8.         u8 t;
  9.         u8 len;        
  10.         u16 times=0;

  11.         delay_init();                     //延时函数初始化        
  12.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  13.         uart_init(9600);         //串口初始化为9600
  14.         TIM2_PWM_Init(1895,0);
  15.         Infrared_GPIO_Configuration();
  16.         Infrared_EXTI_Configuration();
  17.         while(1)
  18.         {

  19.         }         
  20. }
复制代码
  1. /***************************************************************************************
  2. *        FileName                                        :                Infrared.c
  3. *        CopyRight                                        :
  4. *        ModuleName                                :      
  5. *
  6. *        CPU                                                        :
  7. *        RTOS                                                :
  8. *
  9. *        Create Data                                        :        2015/04/21
  10. *        Author/Corportation                        :        Ray
  11. *
  12. *        Abstract Description                :      
  13. *
  14. *--------------------------------Revision History--------------------------------------
  15. *        No        version                Data                        Revised By                        Item                        Description
  16. *        1                v1.0                        2015/4/21        Ray                                                                                                Create this file
  17. *        2                v2.0                        2015/4/23        Ray                                                                                                Sucessfully control the air conditioner
  18. *        3                v2.1                        2015/4/24 Ray                                                                                                Packaging the Infrared Module
  19. *
  20. ***************************************************************************************/



  21. /**************************************************************
  22. *        Debug switch Section
  23. **************************************************************/


  24. /**************************************************************
  25. *        Include File Section
  26. **************************************************************/
  27. #include "Infrared.h"


  28. /**************************************************************
  29. *        Macro Define Section
  30. **************************************************************/

  31. //debug调试宏定义,根据表达式a的真假执行has_bug或no_bug
  32. #define BUG_DETECT_PRINT(a,has_bug,no_bug) { if(a) \
  33. printf("%s",has_bug); \
  34. else \
  35. printf("%s",no_bug);}


  36. /**************************************************************
  37. *        Struct Define Section
  38. **************************************************************/


  39. /**************************************************************
  40. *        Prototype Declare Section
  41. **************************************************************/


  42. /**************************************************************
  43. *        Global Variable Declare Section
  44. **************************************************************/
  45. u8 Flag_LearnState = 0;
  46. u16 PulseTab[MAX_PULSE_LEN];


  47. /**************************************************************
  48. *        File Static Variable Define Section
  49. **************************************************************/


  50. /**************************************************************
  51. *        Function Define Section
  52. **************************************************************/

  53. #ifdef INFRARED_RECEIVE
  54. /**
  55. *  @name                                                void Infrared_GPIO_Configuration()
  56. *        @description                红外接收端GPIO口设置
  57. *        @param                                        PA.01 作外部中断接收口
  58. *        @return               
  59. *  @notice
  60. */
  61. void Infrared_GPIO_Configuration()
  62. {
  63.         GPIO_InitTypeDef GPIO_InitType;
  64.       
  65.         RCC_APB2PeriphClockCmd(INFRARED_RCC_GPIOx,ENABLE);
  66.         GPIO_InitType.GPIO_Mode = GPIO_Mode_IPU;                        //上拉输入
  67.         GPIO_InitType.GPIO_Pin = INFRARED_GPIO_Pinx;
  68.         GPIO_InitType.GPIO_Speed = GPIO_Speed_50MHz;
  69.         GPIO_Init(INFRARED_GPIOx,&GPIO_InitType);
  70.         GPIO_EXTILineConfig(INFRARED_EXTI_GPIOx,INFRARED_EXTI_Line);
  71. }



  72. /**
  73. *  @name                                                void Infrared_EXTI_Configuration()
  74. *        @description                红外线接受端外部中断初始化设置,设置为 线路1,使用PA.1作为外部中断的输入端
  75. *        @param                                       
  76. *        @return               
  77. *  @notice                                        若改变外部中断的输入端,此函数内的线路设置也需改变s
  78. */
  79. void Infrared_EXTI_Configuration()
  80. {
  81.         EXTI_InitTypeDef EXTI_InitType;
  82.         NVIC_InitTypeDef NVIC_InitType;
  83.       
  84.         EXTI_InitType.EXTI_Line = EXTI_Line1;
  85.         EXTI_InitType.EXTI_Mode = EXTI_Mode_Interrupt;
  86.         EXTI_InitType.EXTI_Trigger = EXTI_Trigger_Falling;
  87.         EXTI_InitType.EXTI_LineCmd = ENABLE;
  88.         EXTI_Init(&EXTI_InitType);
  89.       
  90.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                        //NVIC 中断设置
  91.         NVIC_InitType.NVIC_IRQChannel = EXTI1_IRQn;
  92.         NVIC_InitType.NVIC_IRQChannelPreemptionPriority = 0;
  93.         NVIC_InitType.NVIC_IRQChannelSubPriority = 0;
  94.         NVIC_InitType.NVIC_IRQChannelCmd = ENABLE;
  95.         NVIC_Init(&NVIC_InitType);
  96. }


  97. /**
  98. *  @name                                        void EXTI1_IRQHandler()
  99. *        @description        外部中断1中断处理程序,用于采集红外波形
  100. *        @param                       
  101. *        @return                                全局变量Flag_LearnState可以用于返回是否有学习到波形
  102. *  @notice
  103. */
  104. void EXTI1_IRQHandler()
  105. {
  106.         u16 pulseWidth = 0;
  107.         u16 i = 0;
  108.       
  109.         Flag_LearnState = 0;
  110.         //中断指示
  111.       
  112.         while(1)
  113.         {
  114.                 if(IR_RDATA)                                                //有高脉冲出现,代表空闲信号
  115.                 {
  116.                         pulseWidth = 0;
  117.                         while(IR_RDATA)
  118.                         {
  119.                                 pulseWidth++;
  120.                                 delay_us(19);
  121.                                 if(pulseWidth >= 2000)                        // >40ms 则结束记录
  122.                                         break;
  123.                         }
  124.                        
  125.                         if(pulseWidth<=15 || pulseWidth>=2000)                // >40ms || <300us 则结束记录
  126.                                 break;
  127.                         PulseTab[i] = pulseWidth*20;
  128.                         i++;
  129.                 }               
  130.                 else                                                                                //载波信号,偶数位为低电平(载波),奇数位为高电平(空闲)
  131.                 {      
  132.                         pulseWidth = 0;
  133.                         while(IR_RDATA == 0)                       
  134.                         {
  135.                                 pulseWidth++;
  136.                                 delay_us(19);
  137.                         }
  138.                         if(pulseWidth<=15 || pulseWidth>=2000)                 // >40ms || <300sus  则结束记录
  139.                                 break;
  140.                         PulseTab[i] = pulseWidth*20;
  141.                         i++;               
  142.                 }
  143.         }
  144.         PulseTab[i++] = pulseWidth;
  145.         PulseTab[i] = 0xffff;
  146.       
  147.         Flag_LearnState = 1;
  148.         Infrared_Send();
  149.         EXTI_ClearITPendingBit(EXTI_Line1);

  150.         return;
  151. }

  152. #endif




  153. #ifdef INFRARED_SEND
  154. /**
  155. *  @name                                                void Infrared_Send()
  156. *        @description                红外发射,根据 PulseTab[]内的数据发波形
  157. *        @param                       
  158. *        @return               
  159. *  @notice
  160. */
  161. void Infrared_Send()
  162. {
  163.         u16 i;
  164.       
  165.         EXTI->IMR &= ~(0x00000002);                        //关中断,避免发送的红外线被自己接受
  166.         for(i=0; i<MAX_PULSE_LEN && PulseTab[i]!=0xffff; i++)
  167.         {
  168.                 if(i%2 == 0)
  169.                 {
  170.                         TIM_Cmd(TIM2,ENABLE);
  171.                         delay_us(PulseTab[i]);
  172.                         TIM_Cmd(TIM2,DISABLE);
  173.                         GPIO_SetBits(GPIOA,GPIO_Pin_0);
  174.                 }
  175.                 else
  176.                 {
  177.                         GPIO_SetBits(GPIOA,GPIO_Pin_0);
  178.                         delay_us(PulseTab[i]);
  179.                 }
  180.         }
  181.         GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  182.       
  183.         EXTI->IMR |= (0x00000002);                //开中断
  184. }


  185. /**
  186. *  @name                                        void TIM2_PWM_Init(u16 arr,u16 psc)
  187. *        @description        初始化定时器2的设置,将定时器2用于PWM调制,PWM输出口为 PA.0
  188. *        @param                                arr --        u16,定时器重装值
  189.                                                                         psc --        u16,定时器分频值                                                      
  190. *        @return               
  191. *  @notice                                PWM频率 = 72M/((arr+1)*(psc+1)),这里用作红外发射的载波,需要生成38kHz的方波,故取arr = 1895,psc = 0。
  192. */
  193. void TIM2_PWM_Init(u16 arr,u16 psc)
  194. {
  195.         /* 初始化结构体定义 */
  196.         GPIO_InitTypeDef GPIO_InitStructure;
  197.         TIM_TimeBaseInitTypeDef        TIM_TimeBaseInitStructure;
  198.         TIM_OCInitTypeDef         TIM_OCInitStructure;
  199.         /* 使能相应端口的时钟 */
  200.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //使能定时器2时钟
  201.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //使能GPIO外设时钟
  202.       
  203.         /* GPIOA.0初始化 */
  204.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                        // TIM2 CH1
  205.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // PA.0 复用推挽输出
  206.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  207.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  208.         GPIO_SetBits(GPIOA,GPIO_Pin_0);
  209.         /* TIM2 初始化*/
  210.         TIM_TimeBaseInitStructure.TIM_Period = arr;         //下一个更新事件装入活动的自动重装载寄存器周期的值
  211.         TIM_TimeBaseInitStructure.TIM_Prescaler = psc;        //作为TIMx时钟频率除数的预分频值
  212.         TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;  //时钟分割:TDTS = Tck_tim
  213.         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;        //TIM向上计数模式
  214.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
  215.         /* 定时器TIM2 Ch1 PWM模式初始化 */
  216.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //选择定时器模式:TIM PWM1
  217.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;        //比较输出使能
  218.         //TIM_OCInitStructure.TIM_Pulse = (arr+1)/2;          //占空比 50%
  219.         TIM_OCInitStructure.TIM_Pulse = (arr+1)/3;          //占空比1:3
  220.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        //输出极性:TIM输出比较极性高
  221.         TIM_OC1Init(TIM2, &TIM_OCInitStructure);

  222.         /* 使能TIM2在CCR1上的预装载寄存器 */
  223.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
  224.         /* 使能定时器 */
  225. //        TIM_Cmd(TIM2,ENABLE);
  226. }

  227. #endif

  228.       

  229. /**
  230. *  @name
  231. *        @description
  232. *        @param                       
  233. *        @return               
  234. *  @notice
  235. */






  236. #ifdef  DEBUG
  237. /*******************************************************************************
  238. * Function Name  : assert_failed
  239. * Description    : Reports the name of the source file and the source line number
  240. *                  where the assert_param error has occurred.
  241. * Input          : - file: pointer to the source file name
  242. *                  - line: assert_param error line source number
  243. * Output         : None
  244. * Return         : None
  245. *******************************************************************************/
  246. void assert_failed(u8* file, u32 line)
  247. {
  248.           /* User can add his own implementation to report the file name and line number,
  249.              ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  250.         
  251.           while (1)
  252.           {}
  253. }
  254. #endif
复制代码


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

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-23 17:22

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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