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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

只用一個單片機定時器的紅外接收解碼程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:110653 發表于 2016-3-28 23:29 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 hubaba 于 2016-3-28 23:31 編輯

1電路圖

1號單片機與紅外接收頭連接電路如圖所示,紅外接收頭一般都可互換使用。



電路和介紹詳見:http://www.zg4o1577.cn/bbs/dpj-47282-1.html (在這貼附件中可下載完整的4個紅外解碼的源碼壓縮包)
程序預覽:
  1. /****************《51單片機輕松入門-基于STC15W4K系列》配套例程 *************
  2. ★★★★★★★★★★★★★★★★★★★★★★★★
  3. 《51單片機輕松入門-基于STC15W4K系列》 一書已經由北航出版社正式出版發行。
  4.   作者親手創作的與教材配套的51雙核實驗板(2個MCU)對程序下載、調試、仿真方便,不需要外部
  5.   仿真器與編程器,這種設計方式徹底解決了系統中多個最高優先級誰也不能讓誰的中斷競爭問題。
  6.   QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
  7.         驗證信息:STC15單片機
  8.   郵箱:xgliyouquan@126.com
  9.   ★★★★★★★★★★★★★★★★★★★★★★★★*/

  10. ///*************        功能說明        **************        
  11. //紅外接收程序。適用于市場上用量最大的HT6121/6122及其兼容IC的編碼。
  12. //當遙控器用戶碼與程序定義的用戶碼不同時,程序會將遙控器的用戶碼一起從串口輸出。
  13. //使用模擬串口發送用戶碼與鍵碼,波特率9600,接收端要求使用字符格式顯示。        
  14. /******************************************/        
  15. #include        "STC15W4K.H"
  16. #define MAIN_Fosc                22.1184        // 定義主時鐘, 紅外接收會自動適應,5~36MHZ,但模擬串口輸出部分不能自動適應。

  17. #define        User_code                0xFD02                // 定義紅外接收用戶碼  
  18. sbit        Ir_Pin = P3^6;                        // 定義紅外接收輸入端口
  19. sbit        TXD1 = P3^1;                          // 定義模擬串口發送腳
  20. /*************        用戶系統配置        **************/
  21. #define TIME                125                              // 選擇定時器時間125us, 紅外接收要求在60us~250us之間
  22. /*************        以下宏定義用戶請勿修改        **************/
  23. #define Timer0_Reload (unsigned int)(65536 - (TIME * MAIN_Fosc /12.0))  // 定時器初值
  24.                                    
  25. /*************        本地變量聲明        **************/
  26. unsigned char        IR_SampleCnt;                // 采樣次數計數器,通用定時器對紅外口檢測次數累加記錄
  27. unsigned char        IR_BitCnt;                        // 記錄位數
  28. unsigned char        IR_UserH;                        // 用戶碼(地址)高字節
  29. unsigned char        IR_UserL;                        // 用戶碼(地址)低字節
  30. unsigned char        IR_data;                        // 鍵原碼
  31. unsigned char        IR_DataShit;                // 鍵反碼
  32. unsigned char        IR_code;                        // 紅外鍵碼                 
  33. bit                Ir_Pin_temp;                        // 記錄紅外引腳電平的臨時變量
  34. bit                IR_Sync;                                // 同步標志(1——已收到同步信號,0——沒收到)
  35. bit                IrUserErr;                            // 用戶碼錯誤標志
  36. bit                IR_OK;                        // 完成一幀紅外數據接收的標志(0,未收到,1,收到一幀完整數據)

  37. /******************** 紅外采樣時間宏定義, 用戶不要隨意修改        *******************/
  38. //數據格式: Synchro,AddressH,AddressL,data,/data, (total 32 bit).
  39. #if ((TIME <= 250) && (TIME >= 60))                        // TIME決定測量誤差,TIME太大防錯能力降低,TIME太小會干擾其它中斷函數執行。
  40.         #define        IR_sample                        TIME                // 定義采樣時間,在60us~250us之間,
  41. #endif

  42. #define IR_SYNC_MAX                (15000/IR_sample)        // 同步信號SYNC 最大時間 15ms(標準值9+4.5=13.5ms)
  43. #define IR_SYNC_MIN                (9700 /IR_sample)        // 同步信號SYNC 最小時間 9.5ms,(連發信號標準值9+2.25=11.25ms)
  44. #define IR_SYNC_DIVIDE        (12375/IR_sample)        // 區分13.5ms同步信號與11.25ms連發信號,11.25+(13.5-11.25)/2=12.375ms
  45. #define IR_DATA_MAX                (3000 /IR_sample)        // 數據最大時間3ms    (標準值2.25 ms)
  46. #define IR_DATA_MIN                (600  /IR_sample)        // 數據最小時,0.6ms   (標準值1.12 ms)
  47. #define IR_DATA_DIVIDE        (1687 /IR_sample)        // 區分數據 0與1,1.12+ (2.25-1.12)/2 =1.685ms
  48. #define IR_BIT_NUMBER                32                                // 32位數據

  49. //****************************  紅外接收模塊  ********************************************
  50. // 信號第1個下降沿時刻清零計數器并讓計數器從0開始計數,第2個下降沿時刻計算計數器運行時間
  51. // 因此檢測的是每個信號從低電平開始到高電平結束這段時間,也就是脈沖周期。
  52. void IR_RX_HT6121(void)
  53. {
  54.         unsigned char        SampleTime;                                // 信號周期
  55.         IR_SampleCnt++;                                                        // 定時器對紅外口檢測次數

  56.         F0 = Ir_Pin_temp;                                                // 保存前一次此程序掃描到的紅外端口電平         
  57.         Ir_Pin_temp = Ir_Pin;                                        // 讀取當前紅外接收輸入端口電平
  58.         if(F0 && !Ir_Pin_temp)                                        // 前一次采樣高電平并且當前采樣低電平,說明出現了下降沿
  59.         {
  60.                 SampleTime = IR_SampleCnt;                        // 脈沖周期
  61.                 IR_SampleCnt = 0;                                        // 出現了下降沿則清零計數器
  62.                 //******************* 接收同步信號 **********************************
  63.                 if(SampleTime > IR_SYNC_MAX)                IR_Sync = 0;        // 超出最大同步時間, 錯誤信息。
  64.                 else if(SampleTime >= IR_SYNC_MIN)                // SYNC
  65.                 {
  66.                         if(SampleTime >= IR_SYNC_DIVIDE)    // 區分13.5ms同步信號與11.25ms連發信號
  67.                         {
  68.                                 IR_Sync = 1;                                    // 收到同步信號 SYNC
  69.                                 IR_BitCnt = IR_BIT_NUMBER;          // 賦值32(32位有用信號)
  70.                         }
  71.                 }
  72.                 //********************************************************************
  73.                 else if(IR_Sync)                                                // 已收到同步信號 SYNC
  74.                 {
  75.                         if((SampleTime < IR_DATA_MIN)|(SampleTime > IR_DATA_MAX)) IR_Sync=0;        // 數據周期過短或過長,錯誤
  76.                         else
  77.                         {
  78.                                 IR_DataShit >>= 1;                                        // 鍵反碼右移1位(發送端是低位在前,高位在后的格式)
  79.                                 if(SampleTime >= IR_DATA_DIVIDE)        IR_DataShit |= 0x80;        // 區別是數據 0還是1

  80.                                 //***********************  32位數據接收完畢 ****************************************
  81.                                 if(--IR_BitCnt == 0)                                 
  82.                                 {
  83.                                         IR_Sync = 0;                                        // 清除同步信號標志
  84.                                         if(~IR_DataShit == IR_data)                // 判斷數據正反碼
  85.                                         {
  86.                                                 if((IR_UserH == (User_code / 256)) && IR_UserL == (User_code % 256))
  87.                                                 {
  88.                                                                 IrUserErr = 0;            // 用戶碼正確
  89.                                                 }
  90.                                                 else        IrUserErr = 1;            // 用戶碼錯誤
  91.                                                         
  92.                                                 IR_code      = IR_data;                // 鍵碼值
  93.                                                 IR_OK   = 1;                            // 數據有效
  94.                                         }
  95.                                 }
  96.                                 // 格式:  用戶碼L —— 用戶碼H —— 鍵碼 —— 鍵反碼
  97.                                 // 功能:  將 “用戶碼L —— 用戶碼H —— 鍵碼”通過3次接收交換后存入對應字節,
  98.                                 //         這樣寫代碼可以節省內存RAM占用,但是不如用數組保存好理解。        
  99.                                 //         鍵反碼前面部分代碼已保存好了        :IR_DataShit |= 0x80;                  
  100.                                 //**************************** 將接收的************************************************
  101.                                 else if((IR_BitCnt & 7)== 0)                // 1個字節接收完成
  102.                                 {
  103.                                         IR_UserL = IR_UserH;                        // 保存用戶碼高字節
  104.                                         IR_UserH = IR_data;                                // 保存用戶碼低字節
  105.                                         IR_data  = IR_DataShit;                        // 保存當前紅外字節
  106.                                 }
  107.                         }
  108.                 }  
  109.         }
  110. }

  111. /**************** Timer0初始化函數 ******************************/
  112. void InitTimer0(void)
  113. {
  114.         TMOD = 0x01;                         // 16位計數方式.
  115.         TH0 = Timer0_Reload / 256;         
  116.         TL0 = Timer0_Reload % 256;
  117.         ET0 = 1;                                         
  118.         TR0 = 1;
  119.         EA  = 1;
  120. }  

  121. /********************** Timer0中斷函數************************/
  122. void timer0 (void) interrupt 1
  123. {
  124.         IR_RX_HT6121();
  125.         TH0 = Timer0_Reload / 256;           // 重裝定時器初值   
  126.         TL0 = Timer0_Reload % 256;           // 重裝定時器初值   
  127. }

  128. /********************** 模擬串口相關函數************************/
  129. void delay104us(void)
  130. {
  131.    unsigned char i,j,k;
  132.    for(i=1;i>0;i--)       // 注意后面沒分號
  133.    for(j=3;j>0;j--)       // 注意后面沒分號
  134.    for(k=189;k>0;k--);    // 注意后面有分號        101
  135. }

  136. //模擬串口發送
  137. void Tx1Send(unsigned char dat)                //9600,N,8,1                發送一個字節
  138. {
  139.         unsigned char        i;
  140.         EA = 0;
  141.         TXD1 = 0;
  142.         delay104us();
  143.         for(i=0; i<8; i++)
  144.         {
  145.                 if(dat & 1)                TXD1 = 1;
  146.                 else                        TXD1 = 0;
  147.                 dat >>= 1;
  148.                 delay104us();
  149.         }
  150.         TXD1 = 1;
  151.         EA = 1;
  152.         delay104us();
  153.         delay104us();
  154. }

  155. void PrintString(unsigned char code *puts)                    // 發送一串字符串
  156. {
  157.     for (; *puts != 0;        puts++)  Tx1Send(*puts);         // 遇到停止符0結束
  158. }

  159. /********************* 十六進制轉ASCII函數 *************************/
  160. unsigned char        HEX2ASCII(unsigned char dat)
  161. {
  162.         dat &= 0x0f;
  163.         if(dat <= 9)        return (dat + '0');        //數字0~9
  164.         return (dat - 10 + 'A');                        //字母A~F
  165. }

  166. /********************* 主函數 *************************/
  167. void main(void)
  168. {
  169.         InitTimer0();                                    // 初始化Timer0        
  170.         PrintString("定時器0初始化完畢\r\n");        // 上電后串口發送一條提示信息

  171.         while(1)
  172.         {
  173.                 if(IR_OK)                                     // 接收到一幀完整的紅外數據
  174.                 {
  175.                         PrintString("紅外鍵碼: 0x");                // 提示紅外鍵碼
  176.                         Tx1Send(HEX2ASCII(IR_code >> 4));        // 鍵碼高半字節
  177.                         Tx1Send(HEX2ASCII(IR_code));                // 鍵碼低半字節
  178.                         if(IrUserErr)                                                // 用戶碼錯誤,則發送用戶碼
  179.                         {
  180.                                 Tx1Send(' ');                                        // 發空格
  181.                                 Tx1Send(' ');                                        // 發空格
  182.                                 PrintString("用戶碼: 0x");                // 提示用戶碼
  183.                                 Tx1Send(HEX2ASCII(IR_UserH >> 4));        // 用戶碼高字節的高半字節
  184.                                 Tx1Send(HEX2ASCII(IR_UserH));                // 用戶碼高字節的低半字節
  185.                                 Tx1Send(HEX2ASCII(IR_UserL >> 4));        // 用戶碼低字節的高半字節
  186.                                 Tx1Send(HEX2ASCII(IR_UserL));                // 用戶碼低字節的低半字節
  187.                         }
  188.                         Tx1Send(0x0d);                          // 發回車
  189.                         Tx1Send(0x0a);                          // 發回車
  190.                         IR_OK = 0;                              // 清除IR鍵按下標志
  191.                 }
  192.         }
  193. }
復制代碼


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

使用道具 舉報

沙發
ID:154878 發表于 2016-12-14 23:38 | 只看該作者
請問一下,移值到C51 只要修改一下引腳和晶振就可以了么?
回復

使用道具 舉報

板凳
ID:365500 發表于 2018-8-10 17:27 | 只看該作者
好厲害,,,,不知道什么時候才有這個水平啊!
回復

使用道具 舉報

地板
ID:60263 發表于 2019-4-6 00:11 | 只看該作者
STC官方網站上有這個例程,一樣的,可以下載,我用的STC15F104實測可用。
回復

使用道具 舉報

5#
ID:363812 發表于 2019-10-17 18:25 | 只看該作者
大哥  我用兩個新唐的8位單片機做紅外對射去解碼   套用這個怎么弄?   謝謝大哥回下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一区二 | 一区二区视频在线 | 男女羞羞视频免费 | 国产在线高清 | 在线看av网址 | 一级毛片在线播放 | 欧美不卡在线 | 欧美www在线观看 | 久久精品一区二 | 国产一区二区三区四区hd | 久久小视频 | 你懂的在线视频播放 | 91精品在线看 | 精品伦精品一区二区三区视频 | 99精品视频网 | 精品三级在线观看 | 一二区电影 | 精品一区二区三区四区外站 | 天天天操| 欧美激情视频一区二区三区在线播放 | 午夜精品一区二区三区在线视 | 亚洲精品美女在线观看 | 精品99在线 | 日韩精品免费看 | 国产精品2 | 久久久中文 | 毛片a级 | 欧美天堂| 欧美日本亚洲 | 午夜精品一区二区三区在线观看 | 中文字幕 在线观看 | 国产视频一区二区 | 成av在线| 欧美在线视频网站 | 国产丝袜一区二区三区免费视频 | 国产精品毛片久久久久久久 | 日韩亚洲视频在线 | 成人在线观 | 久久久婷婷 | 欧美日韩国产高清 | 国产主播第一页 |