找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1583|回复: 0
打印 上一主题 下一主题
收起左侧

52单片机红外发射与接收程序

[复制链接]
跳转到指定楼层
楼主
ID:880509 发表于 2021-2-22 13:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
利用proteus进行红外仿真
MCU采用的是51单片机
供参考和学习使用

单片机源程序如下:

  1. //作用 红外发射与接收一体 万能遥控解码
  2. #include"reg52.h"
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. //定时器寄存器设置
  6. #define THO_int0  0xfa
  7. #define TLO_int0  0x8d      

  8. #define TH1_int1  0xff
  9. #define TL1_int1  177
  10.       
  11. sbit         LED1=P2^1;
  12. sbit         LED2=P2^2;
  13. sbit         LED3=P2^3;
  14. sbit         LED4=P2^0;
  15. sbit         Beep=P3^7;

  16. sbit         KEY1=P1^4;
  17. sbit         KEY2=P1^5;
  18. sbit         KEY3=P1^6;
  19. sbit         KEY4=P1^7;
  20. sbit         infrared = P3^3;
  21. sbit        infr_send = P3^4;

  22. sbit        tiaoshi = P3^6;

  23. //表格存于ROM*************************************
  24. uchar code  dsp_tap[16]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28,0x30,0x25,0xe4,0x23,0x64,0x74};
  25. uchar code  dsp_cs[4]={0x70,0xd0,0xb0,0xe0};
  26. //uchar code        dat_tap[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  27. //uchar code        dat_tap2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
  28. //变量定义存于RAM**********************************
  29. uchar SimpleKeyState = 0;                   //简单按键的状态
  30. uchar SimpleKeyPressDelay = 7;              //简单按键按实的大概时间,单位:10毫秒
  31. uchar SimpleKeyCode = 0xFF;                //简单按键键码

  32. uchar        infr_key1_data[4] = {0};
  33. uint        infr_send_cont = 0;

  34. uchar        infrared_new_data[4] = {0};
  35. uchar        infrared_old_data[4] = {0x80,0xff,0xc8,0x37};
  36. uchar        infrared_byte = 0;
  37. uchar        infrared_byte_cont = 0;
  38. uchar        infrared_old_state = 0;
  39. uchar        infrared_new_state = 0;
  40. uint        infrared_cont = 0;
  41. uint        infrared_cont_now = 0;
  42. uchar        flg_infrared = 0;
  43. uchar        flg_infrared_ok = 0;

  44. uchar   seg_step = 0;
  45. uchar         dsp_step;
  46. uchar         cont_4ms;
  47. uint    cont_1s;
  48. uchar   cont_500ms;
  49. uchar   cont_10ms;
  50. uchar   sec;
  51. uchar   beef_delay;
  52. uchar   dis_play[4] = {0};
  53. uint           dis_num = 0;

  54. uchar        flg_display = 0;
  55. uchar        flg_change = 0;
  56. uchar        flg_send_start = 0;
  57. uchar        aaa[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  58. uchar        flg_key = 0;

  59. void writ_send(uint tin)
  60. {       
  61.         uchar        j;
  62.         uint        i;
  63.         for(i=0;i<tin;i++)
  64.         {
  65.                 for(j=0;j<4;j++);
  66.                 infr_send =~ infr_send;
  67.         }
  68.         infr_send = 1;
  69. }
  70. void delay(uint w)
  71. {
  72.         uint        i;
  73.         for(i = 0;i<w;i++);
  74. }
  75. void infr_send_ctrol(void)                                                            
  76. {       
  77.         uchar        cont;
  78.         EA=0;
  79.         infrared_byte_cont = 0;
  80.         infrared_byte = 0;
  81.         writ_send(660);   //头码9ms
  82.         delay(748);          //4500us 高电平延时
  83.         for(cont = 0;cont < 33; cont++)
  84.         {
  85.                 writ_send(38);          //560us低电平发射          42

  86.                 if(infrared_old_data[infrared_byte] & aaa[infrared_byte_cont])
  87.                 {
  88.                         delay(280);          //1690us 高电平延时 1            269
  89.                         infrared_byte_cont++;
  90.                 }else
  91.                 {
  92.                         delay(93);          //560us 高电平延时 0            89
  93.                         infrared_byte_cont++;
  94.                 }

  95.                 if(infrared_byte_cont == 8)
  96.                 {
  97.                         infrared_byte++;       
  98.                         infrared_byte_cont = 0;
  99.                 }     
  100.         }
  101.         EA=1;                          
  102. }   
  103. /*============
  104. 简单按键处理子函数
  105. ==============*/
  106. void SimpleKeyAction(void)
  107. {
  108.     if(SimpleKeyCode == 1)
  109.     {
  110.         LED1 =~ LED1;
  111.         infr_send_ctrol();
  112.     }
  113.     else if(SimpleKeyCode == 2)
  114.     {
  115.            
  116.         LED2 =~ LED2;
  117. //        infr_send =~ infr_send;
  118.     }
  119.     else if(SimpleKeyCode == 3)
  120.     {

  121.         //LED3 =~ LED3;
  122.     }else if(SimpleKeyCode == 4)
  123.     {

  124.         Beep = 0;
  125.         LED4 =~ LED4;
  126.     }
  127. }
  128. /*============
  129. 简单按键扫描子函数
  130. ==============*/
  131. void SimpleKeyScan(void)
  132. {
  133.     P1 =P1|0xf0;
  134.     if(SimpleKeyPressDelay > 0) SimpleKeyPressDelay--;
  135.         
  136.     if( (SimpleKeyState == 0) && ((KEY1 ==0) || (KEY2 ==0) || (KEY3 ==0) || (KEY4 ==0)) ) //某个按钮被按下
  137.     {
  138.         SimpleKeyState = 1;
  139.         SimpleKeyPressDelay = 7;  //从接触按键到把按键按下所需要的大概时间:70毫秒
  140.     }
  141.     if(SimpleKeyState == 1)
  142.     {
  143.         if(SimpleKeyPressDelay == 0) //按键按实
  144.         {
  145.                 //        Beep = 0;
  146.             SimpleKeyState = 2;
  147.             if(KEY1 ==0)
  148.             {
  149.                 SimpleKeyCode = 1;                                            
  150.             }
  151.             else if(KEY2 ==0)
  152.             {
  153.                 SimpleKeyCode = 2;
  154.             }
  155.                      else if(KEY3 ==0)
  156.             {
  157.                 SimpleKeyCode = 3;
  158.             }
  159.                         else if(KEY4 ==0)
  160.             {
  161.                 SimpleKeyCode = 4;
  162.             }
  163.             
  164.             SimpleKeyAction();//按键处理
  165.         }
  166.     }
  167.     if(SimpleKeyState == 2)
  168.     {
  169.         if( (KEY1 == 1) && (KEY2 == 1) && (KEY3 == 1) && (KEY4 == 1) ) //所有的按键松开
  170.         {
  171.             SimpleKeyPressDelay = 7;  //松开按键所需要的大概时间:70毫秒
  172.             SimpleKeyState = 3;
  173.         }
  174.     }
  175.     if(SimpleKeyState == 3)
  176.     {
  177.         if(SimpleKeyPressDelay == 0) //已松开按键
  178.         {
  179.             SimpleKeyState = 0;
  180.             SimpleKeyCode = 0xFF;
  181.         }
  182.     }
  183. }

  184. //******************************************************************
  185. void T0_int(void)
  186. {
  187. //定时器0初始化设置
  188.         TR0 = 1;
  189.         TH0=THO_int0;
  190.         TL0=TLO_int0;
  191.         ET0=1;
  192.         EA=1;
  193. }   
  194. //*********************************************************************
  195. void MCU_init(void)
  196. {          
  197.         P1=0xff;
  198.         P2=0xff;
  199.         P3=0xff;
  200.         T0_int();
  201. //        Beep = 0;
  202. }


  203.                   

  204. //*******************************************************************

  205. void timer0_(void)interrupt 1                                    //  定时器溢出周期为100us
  206. {         
  207.         TR0=0;
  208.         TH0=THO_int0;
  209.         TL0=TLO_int0;
  210.         TR0=1;
  211. //        tiaoshi =~ tiaoshi;
  212.         if(flg_send_start == 0)
  213.         {
  214.                 //红外接收代码
  215.                 P3=(P3|0x08);                         //把红外管脚的电平设为1
  216.                 infrared_old_state = infrared_new_state;              //保留上一次的电平
  217.                 infrared_new_state = (P3&0x08);                             //读取现在的管脚电平值
  218.                 if(infrared_new_state == infrared_old_state) infrared_cont++; //如果两次的电平相同 变量infrared_cont 自加1
  219.                 else if((P3&0x08) == 0x00)                                      //如果两次的电平不相同 且 该管脚的电平为低电平
  220.                 {       
  221.                         infrared_cont_now = infrared_cont;                     //保留infrared_cont的值
  222.                         infrared_cont = 0;                                                            //变量清零
  223.                         if(flg_infrared == 1)
  224.                         {       
  225.                                 if((infrared_cont_now >= 6)&&(infrared_cont_now <= 25))                    //如果变量值在6到15这个范围之内
  226.                                 {       
  227.                                         if(infrared_cont_now <= 14)                  //小于的话 设置为0
  228.                                         {
  229.                                                 infrared_new_data[infrared_byte] = infrared_new_data[infrared_byte]<<1;
  230.                                                 infrared_new_data[infrared_byte] = (infrared_new_data[infrared_byte]&0xfe);
  231.                                                 infrared_byte_cont++;   
  232.                                         }
  233.                                         else                                          //大于的话 设置为1
  234.                                         {
  235.                                                 infrared_new_data[infrared_byte] = infrared_new_data[infrared_byte]<<1;
  236.                                                 infrared_new_data[infrared_byte] = (infrared_new_data[infrared_byte]|0x01);
  237.                                                 infrared_byte_cont++;  
  238.                                         }
  239.                                         if(infrared_byte_cont == 8)                  //当存储玩8位数据infrared_new_data[0]之后,再存储infrared_new_data[1]
  240.                                         {
  241.                                                
  242.                                                 infrared_byte++;
  243.                                                 infrared_byte_cont = 0;
  244.                                                 if(infrared_byte == 4)                  //当存储完32位数据之后
  245.                                                 {
  246.                                                         infrared_byte = 0;
  247.                                                         flg_infrared = 0;                                //标志位清零
  248.                                                         infrared_old_data[0] = infrared_new_data[0];        //保留数据
  249.                                                         infrared_old_data[1] = infrared_new_data[1];
  250.                                                         infrared_old_data[2] = infrared_new_data[2];
  251.                                                         infrared_old_data[3] = infrared_new_data[3];
  252.                                                         flg_infrared_ok = 1;                                                               
  253.                                                 }
  254.        
  255.                                         }
  256.                                 }else flg_infrared = 0;
  257.                         }else
  258.                         {
  259.                                 if((infrared_cont_now >= 80)&&(infrared_cont_now <= 150))           //头吗解读
  260.                                 {
  261.                                         flg_infrared = 1;                                           //标志位置1
  262.                                         infrared_byte = 0;                                           //变量清零
  263.                                         infrared_byte_cont = 0;
  264.                                 }else flg_infrared = 0;
  265.                         }               
  266.                 }               
  267.         }
  268.         cont_4ms++;       
  269.         if(cont_4ms >= 40)
  270.         {               
  271.                 cont_4ms=0;
  272.                 flg_display = 1;
  273.                 //蜂鸣器控制****************************
  274.                 if(Beep == 0)
  275.                 {
  276.                         beef_delay++;
  277.                          if(beef_delay > 10) Beep = 1;
  278.                 }else beef_delay = 0;
  279.                 //**************************************                    
  280.         }          
  281.         cont_1s++;
  282.         if(cont_1s>=10000)
  283.         {       
  284.                 cont_1s=0;
  285.         //        dis_num++;
  286.                 flg_change =~ flg_change;
  287.         }               
  288. }          


  289. void main(void)
  290. {  
  291.         MCU_init();
  292.         tiaoshi = 0;
  293.         for(;;)
  294.         {           
  295.                 SimpleKeyScan();
  296.                 if(flg_infrared_ok == 1)
  297.                 {
  298.                         flg_infrared_ok = 0;
  299.                         LED4 =~ LED4;       
  300.                         Beep = 0;
  301.                 }   
  302.                
  303.                 if(flg_display)
  304.                 {
  305.                         flg_display = 0;
  306.                         P2 = (P2&0x0f);
  307.                         if(flg_change)
  308.                         {
  309.                                 dis_play[3] = dsp_tap[infrared_old_data[2]%256/16];
  310.                                 dis_play[2] = dsp_tap[infrared_old_data[2]%16];
  311.                                 dis_play[1] = dsp_tap[infrared_old_data[3]%256/16];
  312.                                 dis_play[0] = dsp_tap[infrared_old_data[3]%16];          
  313.                         }else
  314.                         {
  315.                                 dis_play[3] = dsp_tap[infrared_old_data[0]%256/16];
  316.                                 dis_play[2] = dsp_tap[infrared_old_data[0]%16];
  317.                                 dis_play[1] = dsp_tap[infrared_old_data[1]%256/16];
  318.                                 dis_play[0] = dsp_tap[infrared_old_data[1]%16];       
  319.                         }
  320.                         P0 = dis_play[seg_step];
  321.                         P2 = (P2|dsp_cs[seg_step]);
  322.                         seg_step++;
  323.                         if(seg_step>=4)seg_step = 0;
  324.                 }     
  325.         }  
  326. }


  327. void EXT0_INT(void) interrupt 0                {;}
  328. void EXT1_INT(void) interrupt 2                {;}
  329. void timer1_(void)  interrupt 3                {;}
  330. void serial_(void)  interrupt 4                {;}
复制代码





评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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