久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4094|回復: 11
打印 上一主題 下一主題
收起左側

真正的萬能紅外學習與發射 單片機程序

  [復制鏈接]
跳轉到指定樓層
樓主
無需外圍38KHZ晶振,STC8H系列芯片按道理都能用,萬能接受,萬能發射,EEPROM存儲數據,暫時只能存一個碼,串口輸出信息,按下遙控器按鍵,發送02可顯示剛剛收到的信息并保存,發送10可發射剛剛保存的數據,本人新手,程序有些亂,但有注釋,因為剛剛做出來所以并不完善,還請大佬多多指教!
紅外發射接P11,接受接P20。
原始波形:


經過學以后發射的波形:


單片機源程序如下:
  1. #include "stc8H.h"
  2. #include "intrins.h"
  3. #include <stdio.h>
  4. #include "uart.h"
  5. #include "eeprom.h"
  6. #include "launch.h"


  7. extern  char ch;

  8. int ir1  = 0x0400;
  9. unsigned short xdata captures[VAL] = {0},eep_captures[VAL] = {0}; //緩存數組
  10. static unsigned int num = 0; //一共接受了幾個脈沖
  11. unsigned int two_num;
  12. static unsigned int Overflow = 0; //溢出次數
  13. static unsigned char val; //接收超時變量


  14. void Timer0_Init(void)        //1毫秒@24.000MHz,定時器0
  15. {
  16.     AUXR |= 0x80;
  17.     TMOD &= 0xF0;            //設置定時器模式
  18. //    TL0 = 0x90;                //設置定時初始值
  19. //    TH0 = 0xE8;                //設置定時初始值
  20.    
  21.         TL0 = 0x40;                //設置定時初始值
  22.     TH0 = 0xA2;                //設置定時初始值
  23.    
  24.     TF0 = 0;                //清除TF0標志
  25.     TR0 = 1;                //定時器0開始計時
  26.     ET0 = 1;
  27. }

  28. void IR() //初始化
  29. {
  30.     P1M0 = 0x00;
  31.     P1M1 = 0x00;
  32.     P3M0 = 0x00;
  33.     P3M1 = 0x00;
  34.     P5M0 = 0x00;
  35.     P5M1 = 0x00;
  36.     P_SW2 = 0x80;

  37.     PWM1_PS = 0x05;

  38.     //(CC1捕獲TI1上升沿,CC2捕獲TI1下降沿)
  39.     PWMA_CCER1 = 0x00;
  40.     PWMA_CCMR1 = 0x01;                          //CC1為輸入模式,且映射到TI1FP1上
  41.     PWMA_CCMR2 = 0x02;                          //CC2為輸入模式,且映射到TI1FP2上
  42.     PWMA_CCER1 = 0x11;                          //使能CC1/CC2上的捕獲功能
  43.     PWMA_CCER1 |= 0x00;                         //設置捕獲極性為CC1的上升沿
  44.     PWMA_CCER1 |= 0x20;                         //設置捕獲極性為CC2的下降沿
  45.    
  46.     PWMA_CR1 = 0x01;
  47.    
  48.         PWMA_PSCR = 0x09;
  49.         
  50.     PWMA_IER = 0x04;                            //使能CC2捕獲中斷
  51.         PWMA_IER |= 0x02;                            //使能CC1捕獲中斷
  52.     EA = 1;
  53. }




  54. void PWMA_ISR() interrupt 26 //PWM沿觸發中斷
  55. {
  56.     unsigned int cnt_l;
  57.         unsigned int cnt_h;
  58.    

  59.     if (PWMA_SR1 & 0x02)
  60.     {
  61.         PWMA_SR1 &= ~0x02;
  62.         cnt_l = (PWMA_CCR1 - PWMA_CCR2)/24;            //差值即為低電平寬度  cnt/時鐘頻率 = 脈寬(us)   
  63.                 captures[num++] = cnt_l;
  64.     }
  65.         
  66.          

  67.     if (PWMA_SR1 & 0x04)
  68.     {
  69.         PWMA_SR1 &= ~0x04;
  70.         cnt_h = (PWMA_CCR2 - PWMA_CCR1)/24;            //差值即為高電平寬度
  71.                 captures[num++] = cnt_h;
  72.     }
  73. }

  74. void TM0_Isr() interrupt 1 //定時器0中斷用來判斷脈沖接受是否超時,大于30ms為超時
  75. {   
  76.     if(P20 == 1)
  77.     {
  78.         val++;
  79.         if(val > 30)
  80.         {
  81.             Overflow = 1;
  82.             val = 0;
  83.         }
  84.     }else {val = 0;Overflow = 0;}
  85. }


  86. void UartReceiveHandler() interrupt 4 {
  87.     if (RI) {              // 接收中斷
  88.         RI = 0;            // 清除接收標志位
  89.         ch = SBUF;    // 讀取接收到的數據
  90.         //UartSend(ch);      // 原樣返回接收到的數據
  91.     }
  92. }

  93. void TM3_Isr() interrupt 19 //定時器3中斷發生38K載波
  94. {
  95.     P11 = !P11;                                 //紅外1端口
  96. }



  97. //---------------------------------------------------------------------------------------------
  98. void main()
  99. {
  100.     unsigned int i = 0,a = 0;
  101.    
  102.    
  103.    
  104.     Timer0_Init();
  105.     Timer3_Init();
  106.     UartInit();
  107.     IR();
  108.   
  109.   UartSendString("Starting\r\n");
  110.     lach1 = 1;
  111.     while(1)
  112.     {
  113.         //lach1 = 1;
  114.             if(Overflow == 1 && ch == 0x02)//如果超時溢出,并且接收到0x02
  115.             {
  116.                 EraseUIntFromEEPROM(0x0400);
  117.                 EraseUIntFromEEPROM(0x0600);
  118.                 delays(5);               
  119.                 EraseUIntFromEEPROM(0x0000);
  120.                 delays(5);
  121.                 for(i = 0; i <= num; i++)
  122.                 {
  123.                     SaveUIntToEEPROM(ir1+i*2, captures[i]); //寫入eeprom
  124.                     //SaveUIntToEEPROM(ir1+i*2, '3'); //寫入eeprom
  125.                     UartSendUint(captures[i]);//打印保存到數組里的數據
  126.                     captures[i] = 0;
  127.                     delays(1);
  128.                 }
  129.                 SaveUIntToEEPROM(0x0000, num); //將脈沖個數寫入eeprom
  130.                     UartSendString("End\r\n"); /*End結束*/
  131.                     UartSendUint(num);
  132.                     ir1 = 0x0400;
  133.                     ch = 0;
  134.                     num = 0;
  135.                     Overflow = 0;
  136.                     PWMA_IER = 0; //關閉PWM中斷使能
  137.                     ET0 = 0;    //關閉定時器0中斷
  138.             }else if(P20 == 0 && Overflow==0){
  139.                 PWMA_IER = 0x06; //打開PWM中斷使能
  140.                 ET0 = 1; //打開定時器0中斷
  141.             }
  142.             
  143.             
  144.             if(ch == 0x01)
  145.             {
  146.                 two_num = ReadUIntFromEEPROM(0x0000);
  147.                     for(a = 0;a<=two_num;a++) //讀取紅外接收數組
  148.                     {
  149.                         eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
  150.                         UartSendUint(eep_captures[a]);//打印保存到數組里的數據
  151.                         delays(1);
  152.                     }
  153.                     UartSendUint(two_num);
  154.                     ir1 = 0x0400;
  155.                     two_num = 0;
  156.                     ch = 0x00;
  157.             }
  158.             if(ch == 0x10)
  159.             {
  160.                 two_num = ReadUIntFromEEPROM(0x0000);
  161.                 for(a = 0;a<=two_num;a++) //讀取紅外接收數組
  162.                     {
  163.                         eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
  164.                         UartSendUint(eep_captures[a]);//打印保存到數組里的數據
  165.                         delays(1);
  166.                     }
  167.                 Launch_1(eep_captures,two_num);
  168.                 ch = 0;
  169.             }

  170.             
  171.     }
  172. }
  173. 單片機源程序如下:
  174. [code]#include "stc8H.h"
  175. #include "intrins.h"
  176. #include <stdio.h>
  177. #include "uart.h"
  178. #include "eeprom.h"
  179. #include "launch.h"


  180. extern  char ch;

  181. int ir1  = 0x0400;
  182. unsigned short xdata captures[VAL] = {0},eep_captures[VAL] = {0}; //緩存數組
  183. static unsigned int num = 0; //一共接受了幾個脈沖
  184. unsigned int two_num;
  185. static unsigned int Overflow = 0; //溢出次數
  186. static unsigned char val; //接收超時變量


  187. void Timer0_Init(void)                //1毫秒@24.000MHz,定時器0
  188. {
  189.         AUXR |= 0x80;
  190.         TMOD &= 0xF0;                        //設置定時器模式
  191. //        TL0 = 0x90;                                //設置定時初始值
  192. //        TH0 = 0xE8;                                //設置定時初始值
  193.         
  194.                 TL0 = 0x40;                                //設置定時初始值
  195.         TH0 = 0xA2;                                //設置定時初始值
  196.         
  197.         TF0 = 0;                                //清除TF0標志
  198.         TR0 = 1;                                //定時器0開始計時
  199.         ET0 = 1;
  200. }

  201. void IR() //初始化
  202. {
  203.     P1M0 = 0x00;
  204.     P1M1 = 0x00;
  205.     P3M0 = 0x00;
  206.     P3M1 = 0x00;
  207.     P5M0 = 0x00;
  208.     P5M1 = 0x00;
  209.     P_SW2 = 0x80;

  210.     PWM1_PS = 0x05;

  211.     //(CC1捕獲TI1上升沿,CC2捕獲TI1下降沿)
  212.     PWMA_CCER1 = 0x00;
  213.     PWMA_CCMR1 = 0x01;                          //CC1為輸入模式,且映射到TI1FP1上
  214.     PWMA_CCMR2 = 0x02;                          //CC2為輸入模式,且映射到TI1FP2上
  215.     PWMA_CCER1 = 0x11;                          //使能CC1/CC2上的捕獲功能
  216.     PWMA_CCER1 |= 0x00;                         //設置捕獲極性為CC1的上升沿
  217.     PWMA_CCER1 |= 0x20;                         //設置捕獲極性為CC2的下降沿
  218.         
  219.     PWMA_CR1 = 0x01;
  220.         
  221.                 PWMA_PSCR = 0x09;
  222.                
  223.     PWMA_IER = 0x04;                            //使能CC2捕獲中斷
  224.                 PWMA_IER |= 0x02;                            //使能CC1捕獲中斷
  225.     EA = 1;
  226. }




  227. void PWMA_ISR() interrupt 26 //PWM沿觸發中斷
  228. {
  229.     unsigned int cnt_l;
  230.                 unsigned int cnt_h;
  231.         

  232.     if (PWMA_SR1 & 0x02)
  233.     {
  234.         PWMA_SR1 &= ~0x02;
  235.         cnt_l = (PWMA_CCR1 - PWMA_CCR2)/24;            //差值即為低電平寬度  cnt/時鐘頻率 = 脈寬(us)        
  236.                                 captures[num++] = cnt_l;
  237.     }
  238.                
  239.                  

  240.     if (PWMA_SR1 & 0x04)
  241.     {
  242.         PWMA_SR1 &= ~0x04;
  243.         cnt_h = (PWMA_CCR2 - PWMA_CCR1)/24;            //差值即為高電平寬度
  244.                                 captures[num++] = cnt_h;
  245.     }
  246. }

  247. void TM0_Isr() interrupt 1 //定時器0中斷用來判斷脈沖接受是否超時,大于30ms為超時
  248. {        
  249.         if(P20 == 1)
  250.         {
  251.                 val++;
  252.                 if(val > 30)
  253.                 {
  254.                         Overflow = 1;
  255.                         val = 0;
  256.                 }
  257.         }else {val = 0;Overflow = 0;}
  258. }


  259. void UartReceiveHandler() interrupt 4 {
  260.     if (RI) {              // 接收中斷
  261.         RI = 0;            // 清除接收標志位
  262.         ch = SBUF;    // 讀取接收到的數據
  263.         //UartSend(ch);      // 原樣返回接收到的數據
  264.     }
  265. }

  266. void TM3_Isr() interrupt 19 //定時器3中斷發生38K載波
  267. {
  268.     P11 = !P11;                                 //紅外1端口
  269. }



  270. //---------------------------------------------------------------------------------------------
  271. void main()
  272. {
  273.         unsigned int i = 0,a = 0;
  274.         
  275.         
  276.         
  277.         Timer0_Init();
  278.         Timer3_Init();
  279.         UartInit();
  280.         IR();
  281.   
  282.   UartSendString("Starting\r\n");
  283.         lach1 = 1;
  284.         while(1)
  285.         {
  286.                 //lach1 = 1;
  287.                         if(Overflow == 1 && ch == 0x02)//如果超時溢出,并且接收到0x02
  288.                         {
  289.                                 EraseUIntFromEEPROM(0x0400);
  290.                                 EraseUIntFromEEPROM(0x0600);
  291.                                 delays(5);                                
  292.                                 EraseUIntFromEEPROM(0x0000);
  293.                                 delays(5);
  294.                                 for(i = 0; i <= num; i++)
  295.                                 {
  296.                                         SaveUIntToEEPROM(ir1+i*2, captures[i]); //寫入eeprom
  297.                                         //SaveUIntToEEPROM(ir1+i*2, '3'); //寫入eeprom
  298.                                         UartSendUint(captures[i]);//打印保存到數組里的數據
  299.                                         captures[i] = 0;
  300.                                         delays(1);
  301.                                 }
  302.                                 SaveUIntToEEPROM(0x0000, num); //將脈沖個數寫入eeprom
  303.                                         UartSendString("End\r\n"); /*End結束*/
  304.                                         UartSendUint(num);
  305.                                         ir1 = 0x0400;
  306.                                         ch = 0;
  307.                                         num = 0;
  308.                                         Overflow = 0;
  309.                                         PWMA_IER = 0; //關閉PWM中斷使能
  310.                                         ET0 = 0;    //關閉定時器0中斷
  311.                         }else if(P20 == 0 && Overflow==0){
  312.                                 PWMA_IER = 0x06; //打開PWM中斷使能
  313.                                 ET0 = 1; //打開定時器0中斷
  314.                         }
  315.                         
  316.                         
  317.                         if(ch == 0x01)
  318.                         {
  319.                                 two_num = ReadUIntFromEEPROM(0x0000);
  320.                                         for(a = 0;a<=two_num;a++) //讀取紅外接收數組
  321.                                         {
  322.                                                 eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
  323.                                                 UartSendUint(eep_captures[a]);//打印保存到數組里的數據
  324.                                                 delays(1);
  325.                                         }
  326.                                         UartSendUint(two_num);
  327.                                         ir1 = 0x0400;
  328.                                         two_num = 0;
  329.                                         ch = 0x00;
  330.                         }
  331.                         if(ch == 0x10)
  332.                         {
  333.                                 two_num = ReadUIntFromEEPROM(0x0000);
  334.                                 for(a = 0;a<=two_num;a++) //讀取紅外接收數組
  335.                                         {
  336.                                                 eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
  337.                                                 UartSendUint(eep_captures[a]);//打印保存到數組里的數據
  338.                                                 delays(1);
  339.                                         }
  340.                                 Launch_1(eep_captures,two_num);
  341.                                 ch = 0;
  342.                         }

  343.                         
  344.         }
  345. }
復制代碼


原理圖:無
仿真:無
程序: 8路紅外.zip (125.01 KB, 下載次數: 64)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏17 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:433219 發表于 2023-8-9 16:32 | 只看該作者
,發送02可顯  --->pc上,stc-isp軟件 向mcu串口發送???
回復

使用道具 舉報

板凳
ID:276663 發表于 2023-8-9 17:41 | 只看該作者
實物靚照呢
回復

使用道具 舉報

地板
ID:773929 發表于 2023-8-10 08:43 | 只看該作者
wkman 發表于 2023-8-9 16:32
,發送02可顯  --->pc上,stc-isp軟件 向mcu串口發送???

向mcu發
回復

使用道具 舉報

5#
ID:773929 發表于 2023-8-10 08:47 | 只看該作者

才剛調好一路,板子焊接的爛,沒好意思發

cab83b072fab2423c70208daf7d3588.jpg (91.58 KB, 下載次數: 100)

cab83b072fab2423c70208daf7d3588.jpg
回復

使用道具 舉報

6#
ID:276663 發表于 2023-8-10 11:06 | 只看該作者
范莉萍 發表于 2023-8-10 08:47
才剛調好一路,板子焊接的爛,沒好意思發

現在學習型遙控器只要一個發射燈就能實現學習了,有沒有搞清楚原理
回復

使用道具 舉報

7#
ID:773929 發表于 2023-8-10 11:50 | 只看該作者
IdeaMing 發表于 2023-8-10 11:06
現在學習型遙控器只要一個發射燈就能實現學習了,有沒有搞清楚原理

8路發射對應的是8個位置,比如八間屋子
回復

使用道具 舉報

8#
ID:256970 發表于 2023-8-10 14:45 | 只看該作者
IdeaMing 發表于 2023-8-10 11:06
現在學習型遙控器只要一個發射燈就能實現學習了,有沒有搞清楚原理

發射頭是可以接收的,只是接收到的信號較弱,只能近距離接收
回復

使用道具 舉報

9#
ID:773929 發表于 2023-8-10 15:36 | 只看該作者
藍色海陽 發表于 2023-8-10 14:45
發射頭是可以接收的,只是接收到的信號較弱,只能近距離接收

。窟@么吊
回復

使用道具 舉報

10#
ID:1099505 發表于 2024-3-12 07:24 | 只看該作者
真不錯,學習了。
回復

使用道具 舉報

11#
ID:235438 發表于 2024-3-20 00:21 | 只看該作者
我都用定時器來做,還不會用捕獲,代碼收了,回頭試試看
回復

使用道具 舉報

12#
ID:777254 發表于 2025-2-27 16:48 | 只看該作者
樓主做完萬能學習型紅外方案了嗎?可不可以指導一下,不白嫖
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美日韩电影 | 浴室洗澡偷拍一区二区 | 91黄色片免费看 | 91传媒在线观看 | 欧美精品一区二区三区在线播放 | 中文字幕在线精品 | 中文字幕福利视频 | 国产一级一级国产 | 日韩精品免费一区二区在线观看 | 久久九九影视 | 91在线| www.欧美 | 伊人免费网| 欧美精品一区三区 | 91精品无人区卡一卡二卡三 | 成人在线精品视频 | 久久小视频 | 欧美bondage紧缚视频 | 黄色大片在线免费观看 | 久久久免费毛片 | 久久精品国产亚洲 | 黄视频免费 | 国产成人免费视频网站视频社区 | 日本黄色大片免费 | 久久久久免费精品国产小说色大师 | 国产成人久久av免费高清密臂 | 综合五月 | 亚洲欧美激情精品一区二区 | 毛片一级网站 | 久久久久久国产精品免费免费 | 久久天堂网| 久久三区| 成人做爰www免费看 午夜精品久久久久久久久久久久 | 国产高清久久 | 久久精品免费观看 | 精品福利一区二区三区 | 久久爆操 | 久久久久久国产 | 中文字幕在线免费观看 | 欧美日韩精品在线一区 | 国产a区 |