找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6528|回复: 2
收起左侧

单片机红外发射程序

[复制链接]
ID:137504 发表于 2016-9-11 22:20 | 显示全部楼层 |阅读模式
0.png

本例程可以实现用stc的51单片机来控制进行红外线的发射,
完整keil工程文件下载:
http://www.51hei.com/bbs/dpj-55490-1.html
下面是部分程序代码的预览:
主程序:
  1. #include "IR_SendCode.h"
  2. #include "IR_SendDisp.h"
  3. #include "IR_Receive.h"
  4. #include "ChannelShortcutDef.h"
  5. #include "Nokia5110.h"
  6. #include "delay.h"

  7. ChannelKey_TypeDef Channel_ShortKey;//定义通道&快捷键结构体
  8. uint8_t IRSendOrRemote_Flag = Function_IRsend;//定义需要实现的是红外发射还是红外接收

  9. void main(void)
  10. {
  11.         IRsend_Init();
  12.         IRreceiver_Init();
  13.         Nokia5110_Init();
  14.         ReadE2P_ChannelShortKey();//读取设置的通道和快捷键
  15.         Nokia5110_DispChannelKey();//显示设置的通道和快捷键
  16.        
  17.         while(1)
  18.         {
  19.                 Funtion_KeyScan();
  20.                 if(IRSendOrRemote_Flag == Function_IRsend)  //红外发送功能实现
  21.                 {
  22.                         Set_ChannelShortKey();
  23.                   ShortKeyScan_IRSendCode();                       
  24.                  }
  25.                 if(IRSendOrRemote_Flag == Function_IRremote)//红外接收功能实现
  26.                 {
  27.                         IRcode_Disp();
  28.                  }
  29.          }
  30. }
复制代码

STC89Cx_it.c
  1. #include "STC89Cx_it.h"
  2. #include "IR_Receive.h"

  3. //红外解码原理:把红外中的载波解调成低电平,把红外中的低电平解调成高电平输出
  4. //识别原理:识别一个完整周期的高低电平总时间来识别头码和"0"或"1"的值

  5. #define Rev_Header      0x00          //数据接收状态:接收头码0xAA或oxAB
  6. #define Rev_Length      0x01          //数据接收状态:接收头码数据包长度
  7. #define Rev_DataPackage 0x02         //数据接收状态:接收数据包

  8. extern uint8_t IRcode_Type;                          //声明收到的红外数据类型
  9. extern uint8_t IRdataReceive_Flag;//声明接收红外数据状态,等待or接收中or接收完毕
  10. extern uint32_t IRcode_Buffer;                //红外数据缓存
  11. uint8_t CycleTime = 0;                                 //存储完整周期时间(高电平+低电平)
  12. /**********************************************
  13. 函数:void INT0_Handler(void);
  14. 功能:外部中断0中断处理函数;
  15. ***********************************************/
  16. void INT0_Handler(void) interrupt 0
  17. {
  18. }

  19. /**********************************************
  20. 函数:void TIME0_Handler(void);
  21. 功能:定时器0中断处理函数;
  22. ***********************************************/
  23. void TIME0_Handler(void) interrupt 1
  24. {
  25.         CycleTime++;
  26.         if(CycleTime==255)CycleTime=0;         
  27. }

  28. /**********************************************
  29. 函数:void INT1_Handler(void);
  30. 功能:外部中断1中断处理函数;
  31. ***********************************************/
  32. void INT1_Handler(void) interrupt 2
  33. {
  34.         static uint8_t EnterINT0_CNT = 0;//存储进入外部中断次数
  35.         static uint8_t Rev_State = Rev_Header;//定义接收状态
  36.         uint8_t CycleTime_Buffer=0;                         //周期时间缓冲变量
  37.        
  38.         EnterINT0_CNT++;                                                                 //每进入中断一次加1
  39.         //第一次进入中断周期清零,打开定时器0准备计时
  40.         if(EnterINT0_CNT==1)
  41.         {
  42.                 CycleTime=0;
  43.                 IRcode_Buffer=0;
  44.                 TR0=1;
  45.          }
  46.         else//之后先读时间,再进行清零
  47.         {
  48.                 CycleTime_Buffer=CycleTime;
  49.                 CycleTime = 0;
  50.          }
  51.          
  52.          //开始识别头码
  53.         if((Rev_State==Rev_Header)&&(EnterINT0_CNT==2))         
  54.         {
  55.                 Rev_State = Rev_DataPackage;
  56.                 if((CycleTime_Buffer>60)&&(CycleTime_Buffer<100))                         //头码时间位于6.0ms~10ms则为RCA码(标准8ms)
  57.                 {
  58.                         IRcode_Type = IRcode_TypeRCA;
  59.                  }
  60.                 else if((CycleTime_Buffer>110)&&(CycleTime_Buffer<160))//头码时间位于11ms~16ms(必须是大于11ms)则为NEC码(标准13.5ms)
  61.                 {
  62.                         IRcode_Type = IRcode_TypeNEC8;
  63.                  }
  64.                 else//如果都不是,则认为没有收到头码
  65.                 {
  66.                         TR0=0;
  67.                         IRcode_Buffer = 0;
  68.                         EnterINT0_CNT = 0;
  69.                         Rev_State = Rev_Header;
  70.                  }
  71.          }
  72.          
  73.         if((Rev_State==Rev_DataPackage)&&(EnterINT0_CNT>2))//开始解码
  74.         {
  75.                 IRcode_Buffer <<= 1;
  76.                 switch(IRcode_Type)
  77.                 {
  78.                         case IRcode_TypeRCA:
  79.                         {
  80.                                 if((CycleTime_Buffer>10)&&(CycleTime_Buffer<20))//码值时间位于1.0ms~2.0ms则为RCA'1'(标准1.5ms)
  81.                                 {
  82.                                         IRcode_Buffer |= (uint32_t)0x01;
  83.                                  }
  84.                                 else if((CycleTime_Buffer>20)&&(CycleTime_Buffer<30))//码值时间位于1.0ms~2.0ms则为RCA'0'(标准2.5ms)
  85.                                 {
  86.                                         IRcode_Buffer |= (uint32_t)0x00;
  87.                                  }
  88.                                 else
  89.                                 {
  90.                                         TR0=0;
  91.                                         IRcode_Buffer = 0;
  92.                                         EnterINT0_CNT = 0;
  93.                                         Rev_State = Rev_Header;
  94.                                  }
  95.                                 break;
  96.                          }
  97.                         case IRcode_TypeNEC8:
  98.                         {
  99.                                 if((CycleTime_Buffer>6)&&(CycleTime_Buffer<16))//码值时间位于0.6ms~1.6ms则为NEC'0'(标准1.124ms)
  100.                                 {
  101.                                         IRcode_Buffer |= (uint32_t)0x00;
  102.                                  }
  103.                                 else if((CycleTime_Buffer>16)&&(CycleTime_Buffer<28))//码值时间位于1.6ms~2.8ms则为NEC'1'(标准2.25ms)
  104.                                 {
  105.                                         IRcode_Buffer |= (uint32_t)0x01;
  106.                                  }
  107.                                 else
  108.                                 {
  109.                                         TR0=0;
  110.                                         IRcode_Buffer = 0;
  111.                                         EnterINT0_CNT = 0;
  112.                                         Rev_State = Rev_Header;
  113.                            }
  114.                                 break;
  115.                          }
  116.                  }
  117.                  
  118.                 if(((EnterINT0_CNT==26)&&((IRcode_Type==IRcode_TypeRCA)))||((EnterINT0_CNT==34)&&((IRcode_Type==IRcode_TypeNEC8))))//RCA码加头码25,NEC码加头码33位,解码进入中断次数分别为26和34
  119.                 {
  120.                         TR0=0;//解码完毕关闭定时器
  121.                         EnterINT0_CNT=0;
  122.                         IRdataReceive_Flag=IRdataReceive_Success;
  123.                         Rev_State = Rev_Header;//准备下一次接收
  124.                  }
  125.          }
  126. }

  127. /**********************************************
  128. 函数:void TIME1_Handler(void);
  129. 功能:定时器1中断处理函数;
  130. ***********************************************/
  131. void TIME1_Handler(void) interrupt 3
  132. {
  133. }

  134. /**********************************************
  135. 函数:void USART_Handler(void);
  136. 功能:串口中断处理函数;
  137. ***********************************************/
  138. void USART_Handler(void) interrupt 4
  139. {

  140. }
  141. /**********************************************
  142. 函数:void TIME2_Handler(void);
  143. 功能:定时器2中断处理函数;
  144. ***********************************************/
  145. void TIME2_Handler(void) interrupt 5
  146. {
  147.          
  148. }
复制代码
  1. #include "IR_SendCode.h"

  2. /***********************************************************************************************
  3. 函数void IRsend_Init(void)
  4. 功能:定时器1初始化
  5. **********************************************************************************************/
  6. void IRsend_Init(void)
  7. {
  8.   TMOD |= 0x10;                //工作于方式1,16位定时器                               
  9.         TH1   = 0x00;
  10.         TL1   = 0x00;
  11.         TF1   = 0;                        //清楚定时器标志位
  12.         TR1   = 0;                        //关闭定时器
  13. }
  14. /***********************************************************************************************
  15. 函数void Carrier_38KHz(void)
  16. 功能:产生38KHz载波,1/2占空比,12M晶振
  17. **********************************************************************************************/
  18. void Carrier_38KHz(void)
  19. {
  20.         IR = 1;
  21.         _nop_();_nop_();_nop_();_nop_();
  22.         _nop_();_nop_();_nop_();_nop_();
  23.         _nop_();_nop_();_nop_();_nop_();
  24.        
  25.         IR = 0;
  26.         _nop_();_nop_();_nop_();_nop_();
  27.         _nop_();_nop_();_nop_();_nop_();
  28.         _nop_();_nop_();_nop_();_nop_();
  29. }


  30. /******************************************RCA编码**********************************************/

  31. /***********************************************************************************************
  32. 函数void RCA_LeadCode(void)
  33. 功能:产生RCA引导码
  34. **********************************************************************************************/
  35. void RCA_LeadCode(void)
  36. {
  37.         TH1 = (65536-TCarrier_RCALeadCode)/256;//定时载波时间
  38.         TL1 = (65536-TCarrier_RCALeadCode)%256;
  39.         TR1 = 1;//打开定时器0
  40.         IR_ON();
  41.         while(!TF1)
  42.         {
  43.                 Carrier_38KHz();
  44.          }
  45.         TF1 = 0;TR1 = 0;
  46.        
  47.         IR_OFF();
  48.         TH1 = (65536-TLowLevel_RCALeadCode)/256;//定时低电平时间
  49.         TL1 = (65536-TLowLevel_RCALeadCode)%256;
  50.         TR1 = 1;//打开定时器0
  51.         while(!TF1)IR_OFF();
  52.         TF1 = 0;TR1 = 0;
  53. }
  54. /***********************************************************************************************
  55. 函数void RCA_1(void)
  56. 功能:产生RCA"1"码
  57. **********************************************************************************************/
  58. void RCA_1(void)
  59. {
  60.         TH1 = (65536-TCarrier_RCA_1)/256;//定时载波时间
  61.         TL1 = (65536-TCarrier_RCA_1)%256;
  62.         TR1 = 1;//打开定时器0
  63.         IR_ON();
  64.         while(!TF1)
  65.         {
  66.                 Carrier_38KHz();
  67.          }
  68.         TF1 = 0;TR1 = 0;
  69.        
  70.         IR_OFF();
  71.         TH1 = (65536-TLowLevel_RCA_1)/256;//定时低电平时间
  72.         TL1 = (65536-TLowLevel_RCA_1)%256;
  73.         TR1 = 1;//打开定时器0
  74.         while(!TF1)IR_OFF();
  75.         TF1 = 0;TR1 = 0;       
  76. }
  77. /***********************************************************************************************
  78. 函数void RCA_0(void)
  79. 功能:产生RCA"0"码
  80. **********************************************************************************************/
  81. void RCA_0(void)
  82. {
  83.         TH1 = (65536-TCarrier_RCA_0)/256;//定时载波时间
  84.         TL1 = (65536-TCarrier_RCA_0)%256;
  85.         TR1 = 1;//打开定时器0
  86.         IR_ON();
  87.         while(!TF1)
  88.         {
  89.                 Carrier_38KHz();
  90.          }
  91.         TF1 = 0;TR1 = 0;
  92.        
  93.         IR_OFF();
  94.         TH1 = (65536-TLowLevel_RCA_0)/256;//定时低电平时间
  95.         TL1 = (65536-TLowLevel_RCA_0)%256;
  96.         TR1 = 1;//打开定时器0
  97.         while(!TF1)IR_OFF();
  98.         TF1 = 0;TR1 = 0;       
  99. }
  100. /***********************************************************************************************
  101. 函数void RCA_EndCode(void)
  102. 功能:结束码
  103. **********************************************************************************************/
  104. void RCA_EndCode(void)
  105. {
  106.         RCA_1();
  107. }

  108. /***********************************************************************************************
  109. 函数void IR_RCACode(uint8_t *pHex_RCA)
  110. 功能:RCA发码(系统码+用户码),高位在前发射,传入的参数为RCA系统码+用户码两字节数组
  111. **********************************************************************************************/
  112. void IR_RCACode(uint8_t *pHex_RCA)
  113. {
  114.         uint16_t i;
  115.         uint8_t SystemCode = pHex_RCA[0];//RCA系统码
  116.         uint8_t UserCode   = pHex_RCA[1];//RCA用户码
  117.        
  118.         RCA_LeadCode();//RCA引导码
  119.         for(i=0x0008;i!=0x0000;i=i>>1)//发送RCA系统码
  120.         {
  121.                 if(SystemCode&i)
  122.                 {
  123.                         RCA_1();
  124.                 }
  125.                 else
  126.                 {
  127.                         RCA_0();
  128.                 }
  129.         }
  130.         for(i=0x0080;i!=0x0000;i=i>>1)//发送RCA用户码
  131.         {
  132.                 if(UserCode&i)
  133.                 {
  134.                         RCA_1();
  135.                 }
  136.                 else
  137.                 {
  138.                         RCA_0();
  139.                 }
  140.         }       
  141.         SystemCode=~SystemCode;
  142.         for(i=0x0008;i!=0x0000;i=i>>1)//发送RCA系统反码
  143.         {
  144.                 if(SystemCode&i)
  145.                 {
  146.                         RCA_1();
  147.                 }
  148.                 else
  149.                 {
  150.                         RCA_0();
  151.                 }
  152.         }
  153.         UserCode=~UserCode;
  154.         for(i=0x0080;i!=0x0000;i=i>>1)//发送RCA用户反码
  155.         {
  156.                 if(UserCode&i)
  157.                 {
  158.                         RCA_1();
  159.                 }
  160.                 else
  161.                 {
  162.                         RCA_0();
  163.                 }
  164.         }               
  165.         RCA_EndCode();//停止码       
  166. }


  167. /******************************************NEC编码**********************************************/

  168. /***********************************************************************************************
  169. 函数void NEC_LeadCode(void)
  170. 功能:产生NEC引导码
  171. **********************************************************************************************/
  172. void NEC_LeadCode(void)
  173. {
  174.         TH1 = (65536-TCarrier_NECLeadCode)/256;//定时载波时间
  175.         TL1 = (65536-TCarrier_NECLeadCode)%256;
  176.         TR1 = 1;//打开定时器0
  177.         IR_ON();
  178.         while(!TF1)
  179.         {
  180.                 Carrier_38KHz();
  181.          }
  182.         TF1 = 0;TR1 = 0;
  183.        
  184.         IR_OFF();
  185.         TH1 = (65536-TLowLevel_NECLeadCode)/256;//定时低电平时间
  186.         TL1 = (65536-TLowLevel_NECLeadCode)%256;
  187.         TR1 = 1;//打开定时器0
  188.         while(!TF1)IR_OFF();
  189.         TF1 = 0;TR1 = 0;
  190. }
  191. /***********************************************************************************************
  192. 函数void NEC_1(void)
  193. 功能:产生NEC"1"码
  194. **********************************************************************************************/
  195. void NEC_1(void)
  196. {
  197.         TH1 = (65536-TCarrier_NEC_1)/256;//定时载波时间
  198.         TL1 = (65536-TCarrier_NEC_1)%256;
  199.         TR1 = 1;//打开定时器0
  200.         IR_ON();
  201.         while(!TF1)
  202.         {
  203.                 Carrier_38KHz();
  204.          }
  205.         TF1 = 0;TR1 = 0;
  206.        
  207.         IR_OFF();
  208.         TH1 = (65536-TLowLevel_NEC_1)/256;//定时低电平时间
  209.         TL1 = (65536-TLowLevel_NEC_1)%256;
  210.         TR1 = 1;//打开定时器0
  211.         while(!TF1)IR_OFF();
  212.         TF1 = 0;TR1 = 0;       
  213. }
  214. /***********************************************************************************************
  215. 函数void NEC_0(void)
  216. 功能:产生NEC"0"码
  217. **********************************************************************************************/
  218. void NEC_0(void)
  219. {
  220.         TH1 = (65536-TCarrier_NEC_0)/256;//定时载波时间
  221.         TL1 = (65536-TCarrier_NEC_0)%256;
  222.         TR1 = 1;//打开定时器0
  223.         IR_ON();
  224.         while(!TF1)
  225.         {
  226.                 Carrier_38KHz();
  227.          }
  228.         TF1 = 0;TR1 = 0;
  229.        
  230.         IR_OFF();
  231.         TH1 = (65536-TLowLevel_NEC_0)/256;//定时低电平时间
  232.         TL1 = (65536-TLowLevel_NEC_0)%256;
  233.         TR1 = 1;//打开定时器0
  234.         while(!TF1)IR_OFF();
  235.         TF1 = 0;TR1 = 0;       
  236. }
  237. /***********************************************************************************************
  238. 函数void NEC_EndCode(void)
  239. 功能:结束码
  240. **********************************************************************************************/
  241. void NEC_EndCode(void)
  242. {
  243.         NEC_1();
  244. }

  245. /******************************************NEC8编码*******************************************/

  246. /***********************************************************************************************
  247. 函数void IR_NEC8Code(uint8_t *pHex_NEC8)
  248. 功能:NEC8发码(系统码+用户码),低位在前发射,传入参数为NEC8系统码+用户码两字节数组
  249. **********************************************************************************************/
  250. void IR_NEC8Code(uint8_t *pHex_NEC8)
  251. {
  252.         uint16_t i;
  253.         uint8_t SystemCode = pHex_NEC8[0];//NEC8系统码
  254.         uint8_t UserCode   = pHex_NEC8[1];//NEC8用户码
  255.        
  256.         NEC_LeadCode();//NEC8引导码
  257.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码
  258.         {
  259.                 if(SystemCode&i)
  260.                 {
  261.                         NEC_1();
  262.                 }
  263.                 else
  264.                 {
  265.                         NEC_0();
  266.                 }
  267.         }
  268.         SystemCode=~SystemCode;
  269.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统反码
  270.         {
  271.                 if(SystemCode&i)
  272.                 {
  273.                         NEC_1();
  274.                 }
  275.                 else
  276.                 {
  277.                         NEC_0();
  278.                 }
  279.         }
  280.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户码
  281.         {
  282.                 if(UserCode&i)
  283.                 {
  284.                         NEC_1();
  285.                 }
  286.                 else
  287.                 {
  288.                         NEC_0();
  289.                 }
  290.         }       
  291.         UserCode=~UserCode;
  292.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户反码
  293.         {
  294.                 if(UserCode&i)
  295.                 {
  296.                         NEC_1();
  297.                 }
  298.                 else
  299.                 {
  300.                         NEC_0();
  301.                 }
  302.         }               
  303.         NEC_EndCode();//停止码       
  304. }

  305. /******************************************NEC16编码********************************************/

  306. /***********************************************************************************************
  307. 函数void IR_NEC16Code(uint16_t *pHex_NEC16)
  308. 功能:NEC16发码(系统码+用户码),低位在前发射
  309. **********************************************************************************************/
  310. void IR_NEC16Code(uint16_t *pHex_NEC16)
  311. {
  312.         uint16_t i;
  313.        
  314.         uint16_t SystemCode = pHex_NEC16[0];//NEC16系统码;
  315.         uint16_t UserCode   = pHex_NEC16[1];//NEC16用户码;
  316.        
  317.         uint16_t SystemCode_High=SystemCode/256;
  318.         uint16_t SystemCode_Low =SystemCode%256;
  319.                
  320.         NEC_LeadCode();//NEC8引导码
  321.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码高八位
  322.         {
  323.                 if(SystemCode_High&i)
  324.                 {
  325.                         NEC_1();
  326.                 }
  327.                 else
  328.                 {
  329.                         NEC_0();
  330.                 }
  331.         }
  332.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码低八位
  333.         {
  334.                 if(SystemCode_Low&i)
  335.                 {
  336.                         NEC_1();
  337.                 }
  338.                 else
  339.                 {
  340.                         NEC_0();
  341.                 }
  342.         }
  343.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户码
  344.         {
  345.                 if(UserCode&i)
  346.                 {
  347.                         NEC_1();
  348.                 }
  349.                 else
  350.                 {
  351.                         NEC_0();
  352.                 }
  353.         }       
  354.         UserCode=~UserCode;
  355.         for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户反码
  356.         {
  357.                 if(UserCode&i)
  358.                 {
  359.                         NEC_1();
  360.                 }
  361.                 else
  362.                 {
  363.                         NEC_0();
  364.                 }
  365.         }               
  366.         NEC_EndCode();//停止码       
  367. }
复制代码




回复

使用道具 举报

ID:85743 发表于 2018-4-18 21:00 | 显示全部楼层
不错,下载学习,谢谢楼主!
回复

使用道具 举报

ID:262504 发表于 2018-8-10 16:27 | 显示全部楼层
刚好需要,谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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