找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4643|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

51單片機如何實現(xiàn)紅外輸入數(shù)字

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:232530 發(fā)表于 2017-9-12 18:19 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
我有一個想法,用51單片機做個密碼鎖,用紅外來開鎖,,,
奈何寫不出解碼紅外后的數(shù)組判斷,,,,求大神賜教
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:82765 發(fā)表于 2017-9-12 19:23 | 只看該作者
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
回復(fù)

使用道具 舉報

板凳
ID:229064 發(fā)表于 2017-9-12 20:00 | 只看該作者
你的意思是,讓單片機,檢測到紅外之后,自己開鎖嗎?
回復(fù)

使用道具 舉報

地板
ID:228987 發(fā)表于 2017-9-12 20:36 | 只看該作者
AAAAAA666666 發(fā)表于 2017-9-12 20:00
你的意思是,讓單片機,檢測到紅外之后,自己開鎖嗎?

他的意思應(yīng)該是門自己鎖,然后用紅外密碼解鎖
回復(fù)

使用道具 舉報

5#
ID:60379 發(fā)表于 2017-9-12 21:00 | 只看該作者
《51單片機輕松入門 基于STC15W4K系列》有配套例程可以直接使用,占用一個定時器,使用任意一個IO口即可接收遙控器的發(fā)出的各個字節(jié),按遙控器不同按鍵,會接收到不同的字節(jié),接收到的字節(jié)自動發(fā)送到計算機串口助手顯示,程序代碼只需根據(jù)自己的硬件連接更改紅外接收引腳定義,其余代碼無需修改。
完整工程見附件 4—只用一個定時器的紅外接收程序.rar (24.12 KB, 下載次數(shù): 11)

  1. /****************《51單片機輕松入門-基于STC15W4K系列》配套例程 *************
  2. ★★★★★★★★★★★★★★★★★★★★★★★★
  3. 《51單片機輕松入門-基于STC15W4K系列》 一書已經(jīng)由北航出版社正式出版發(fā)行。
  4.   作者親手創(chuàng)作的與教材配套的51雙核實驗板(2個MCU)對程序下載、調(diào)試、仿真方便,不需要外部
  5.   仿真器與編程器,這種設(shè)計方式徹底解決了系統(tǒng)中多個最高優(yōu)先級誰也不能讓誰的中斷競爭問題。
  6.   淘寶店地址:shop117387413點taobao點com
  7.   QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
  8.         驗證信息:STC15單片機
  9.   郵箱:xgliyouquan@126.com
  10.   ★★★★★★★★★★★★★★★★★★★★★★★★*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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








回復(fù)

使用道具 舉報

6#
ID:232280 發(fā)表于 2017-9-12 21:02 來自手機 | 只看該作者
我也是遇到了同樣的問題,不過是紅外控制繼電器,也是寫不出紅外接收數(shù)組的判斷
回復(fù)

使用道具 舉報

7#
ID:200395 發(fā)表于 2017-9-13 10:39 | 只看該作者
首先要有紅外編解碼器,在發(fā)射紅外線的一端有紅外編碼器,將要發(fā)送的數(shù)字調(diào)制到紅外線上,在接收端,使用紅外解碼器將數(shù)字解調(diào)出來,然后單片機根據(jù)數(shù)字對密碼鎖進行控制。
回復(fù)

使用道具 舉報

8#
ID:72333 發(fā)表于 2017-9-13 13:52 | 只看該作者
51單片機:038紅外接收頭 使用外部中斷,再結(jié)合定時器中斷就能實現(xiàn)
回復(fù)

使用道具 舉報

9#
ID:232875 發(fā)表于 2017-9-13 15:01 | 只看該作者
使用外部中斷,再結(jié)合定時器中斷就能實現(xiàn)
回復(fù)

使用道具 舉報

10#
ID:232530 發(fā)表于 2017-9-13 19:54 | 只看該作者
AAAAAA666666 發(fā)表于 2017-9-12 20:00
你的意思是,讓單片機,檢測到紅外之后,自己開鎖嗎?

不是,是類似一個密碼鎖,檢查的對的紅外就開鎖
回復(fù)

使用道具 舉報

11#
ID:232530 發(fā)表于 2017-9-13 19:55 | 只看該作者
cjjcjj1 發(fā)表于 2017-9-12 19:23
你好!那你用按鍵控制的密碼鎖完成了嗎?
可以在按鍵的基礎(chǔ)之上,修改成紅外控制的;
把你完成的打包發(fā)一 ...

還沒完成,遲點
回復(fù)

使用道具 舉報

12#
ID:232530 發(fā)表于 2017-9-13 19:58 | 只看該作者
無量壽經(jīng) 發(fā)表于 2017-9-12 21:00
《51單片機輕松入門 基于STC15W4K系列》有配套例程可以直接使用,占用一個定時器,使用任意一個IO口即可接 ...

我的是89c52的芯片
回復(fù)

使用道具 舉報

13#
ID:226263 發(fā)表于 2017-9-17 21:02 | 只看該作者
第一種靠中斷的方法可以實現(xiàn)簡單的紅外控制,不能用紅外控制PWM。第二種只用一個IO口的方法,51單片可以接受到信號,不過效果不好,不是每次都有用。但是同樣的方法,其他單片機卻可以很靈敏。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表