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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 29371|回復: 37
收起左側

單片機紅外通信(紅外編碼發射和紅外接收解碼代碼)

  [復制鏈接]
ID:427492 發表于 2019-7-8 20:50 | 顯示全部樓層 |閱讀模式
關于紅外通信,網上有很多關于解碼的單片機代碼和視頻,發射編碼部分并不好找。寫發射部分代碼花費了不少時間,拿出來與大家分享一下。下面是我在網上找到的資料:

一、NEC 協議特征:
1.  8 位地址和 8 位命令長度
2. 每次傳輸兩遍地址(用戶碼)和命令(按鍵值)
3. 通過脈沖串之間的時間間隔來實現信號的調制(PPM
4.  38Khz 載波
5. 每位的周期為 1.12ms(低電平)或者 2.25ms(高電平)

NEC協議.jpg

NEC協議.jpg

0和1的判斷.jpg

0和1的判斷.jpg


二、NEC  協議的典型脈沖鏈:

用戶碼和數據碼中的‘0’‘1’是利用脈沖的時間間隔來區分,這種編碼方式稱為脈沖 位置調制方式(PPM)。
其中位 0 首先為 0.56ms 的高電平,然后是 0.565ms 的低電平;位 1 首先是 0.56ms的高電平,然后是 1.69ms 的低電平。


五、編程注意事項
1.紅外接收頭引腳信號是相反的電平 以上電平是從發射頭角度來看,紅外接收頭引腳輸出的是相反的電平。 如圖,即沒有數據傳輸時,P3.2 引腳保持為高電平,當接收到數據時,首先是引導 碼,9ms 的低電平和 4.5ms 的高電平,然后是 32 位數據和 1 位停止位。一般來說, P3.2     與單片機的某中斷引腳相連,當接收數據時,低電平會觸發中斷。

2.數據從 LSB(低位)開始發送,所以選擇右移方式接收數據。 四個字節的數據都是先發送 D0,最后發送 D7。所以接收到 1 位數據后,給變量的 最高位賦值,右移。或者先右移,再給變量的最高位賦值。

3.可以用一個數組保存 32 個數據的持續時間,用于后面判斷高低電平。 用定時器對兩個數據(中斷)之間的時間計時,并保存這個持續時間用于以后判斷 是位 1 還是位 0

4.可以用 2 字節,4 字節變量存儲 32 個數據,以節省代碼空間

可以用兩個 16 位的 int 型變量存儲數據,第一個 int 變量存儲用戶碼,第二個存儲數 據碼和數據反碼。也可以用一個 32 long 型的變量存儲所有數據。

5.判斷停止位 接收到停止位后可以屏蔽紅外引腳的中斷,防止后面數據的干擾,解碼成功后在開 啟中斷。

發射編碼部分核心代碼:
  1. #include <stc8.h>
  2. typedef unsigned char uchar;
  3. typedef unsigned int  uint;
  4. sbit irsend = P7^5;              // 紅外發送
  5. sbit K = P0^7;                   // 按鍵總開關
  6. sbit key1 = P0^0;                // 按鍵1
  7. sbit key2 = P0^1;                // 按鍵2
  8. uint hwcount, count;             // 要進中斷的總次數、用于記錄進入中斷次數
  9. uchar irsys[2]= {0x00,0xff};     // 16位用戶碼
  10. bit hsflag = 0;                  // 發送38KHz載波標志位
  11. uchar ircode;                          // 發送的紅外數據

  12. void Timer1Init(void)                     // 13微秒@12.000MHz
  13. {
  14.         AUXR &= 0xBF;                         // 定時器時鐘12T模式
  15.         TMOD &= 0x0F;                         // 設置定時器模式
  16.         TMOD |= 0x20;                         // 設置定時器模式
  17.         TL1 = 0xF3;                             // 設置定時初值
  18.         TH1 = 0xF3;                             // 設置定時重載值
  19.         TF1 = 0;                             // 清除TF1標志
  20.         TR1 = 0;                             // 定時器1關閉計時
  21.         ET1 = 1;                     // 開定時器1中斷
  22.         EA  = 1;                     // 開總中斷
  23. }

  24. void Timer1_isr() interrupt 3
  25. {
  26.         count++;
  27.         if(hsflag)                   // 有發射標志,則發射38khz
  28.         {
  29.                 irsend = ~irsend;
  30.         }
  31.         else                         // 否則不發射,即相當于發射編碼中的低電平
  32.                 irsend = 1;
  33.                
  34. }

  35. void ir_SendByte()               // 紅外發送一字節數據
  36. {
  37.         uchar i;
  38.         for(i=0;i<8;i++)             // 一字節八位,循環八次
  39.         {
  40.                 hwcount = 43;            // 0.56ms高電平,需要進43次定時器1中斷(560/13=43)
  41.                 hsflag = 1;              // 發射38KHz載波標志
  42.                 count = 0;               // count置0,從這時起記錄進入定時器1中斷的次數
  43.                 TR1 = 1;                 // 定時器1開啟計時
  44.                 while(count < hwcount);  // 在此等待,直到進入中斷次數達到43次
  45.                 TR1 = 0;                 // 定時器1關閉計時
  46.                 if(ircode&0x01)          // 數據是從最低位開始發送的,最低位是1則要進130次中斷
  47.                 {
  48.                         hwcount = 130;       // 1.69ms低電平,進中斷總次數130(1690/13=130)
  49.                 }
  50.                 else                     // 最低位是0,則要進43次定時器1中斷
  51.                 {
  52.                         hwcount = 43;        // 0.565ms低電平,進中斷總次數43(565/13=43)
  53.                 }
  54.                 hsflag = 0;              // 低電平,不需要38kHz載波
  55.                 count = 0;
  56.                 TR1 = 1;
  57.                 while(count < hwcount);
  58.                 TR1 = 0;
  59.                 ircode = ircode >> 1;    // 將數據右移一位,即從低位到高位發送
  60.         }
  61. }
  62. void ir_Send(uchar date)
  63. {
  64.         hwcount = 692;               // (引導碼中的)9ms高電平,9000/13=692
  65.         hsflag = 1;                  // 高電平需要38kHz載波
  66.         count = 0;               
  67.         TR1 = 1;
  68.         while(count < hwcount);
  69.         TR1 = 0;
  70.         hwcount = 346;               // (引導碼中)4.5ms低電平,4500/13=346
  71.         hsflag = 0;                  // 低電平不需要38kHz載波
  72.         count = 0;
  73.         TR1 = 1;
  74.         while(count < hwcount);
  75.         TR1 = 0;
  76.         ircode = irsys[0];           // 發送用戶碼的前8位
  77.         ir_SendByte();
  78.         ircode = irsys[1];           // 發送用戶碼的后8位
  79.         ir_SendByte();
  80.         ircode = date;               // 發送鍵值
  81.         ir_SendByte();
  82.         ircode = ~date;              // 發送鍵值反碼
  83.         ir_SendByte();
  84.         hwcount = 43;                // 0.56ms高電平,560/13=43
  85.         hsflag = 1;                  // 高電平需要38kHz載波
  86.         count = 0;
  87.         TR1 = 1;                     // 定時器1開啟計時
  88.         while(count < hwcount);
  89.         TR1 = 0;                     // 定時器1關閉計時
  90.         hwcount = 43;                // (NEC協議中的停止碼)0.56ms低電平
  91.         hsflag = 0;
  92.         count = 0;
  93.         TR1 = 1;
  94.         while(count < hwcount);
  95.         TR1 = 0;
  96.         irsend = 1;                  // 關閉紅外發射
  97. }
  98. void main()
  99. {
  100.         K = 0;                       // 按鍵總開關拉低
  101.         Timer1Init();                // 定時器1初始化
  102.         while(1)
  103.         {
  104.                 if(key1 == 0)            // 按鍵1         
  105.                 {               
  106.                         ir_Send(0x8a);       // 發送鍵值8aH
  107.                 }
  108.                 if(key2 == 0)            // 按鍵2
  109.                 {
  110.                         ir_Send(0xa6);       // 發送鍵值a6H
  111.                 }
  112.         }
  113. }
復制代碼


  1. #include "key.h"
  2. #define GPIO_KEY P0
  3. bit flag = 0;
  4. /**********************************************
  5. * 函數名:Check_key
  6. * 描述  :矩陣按鍵掃描(缺陷:不能通過按一次按鍵,給變量只加一)
  7. * 參數  :無
  8. * 返回值:鍵值
  9. * 調用  :外部調用
  10. **********************************************/
  11. //unsigned char Check_key(void)
  12. //{
  13. //        unsigned char row,col,temp1,temp2,keyvalue;
  14. //        temp1 = 0x01;
  15. //        for(row=0;row<4;row++)                // 行掃
  16. //        {
  17. //                P0 = 0xF0;                        // 先將P0.4~P0.7置高
  18. //                P0 = ~temp1;                      // 使P0.1~P0.3中有一位為0
  19. //                temp1 *= 2;                       // temp1左移一位
  20. //                if((P0 & 0xF0) < 0xF0)            // 當按鍵按下時,(P0 & 0xF0) 高四位不在是F,可能為7或B或D或E。
  21. //                {                                    // 這時可以確定按下的是(row+1)行
  22. //                        temp2 = 0x80;
  23. //                        for(col=0;col<4;col++)        // 列掃
  24. //                        {
  25. //                                if((P0 & temp2)==0x00)    // 當(P0 & temp2)等于0x00時,可以確定按下的位置是(col+1)列
  26. //                                {
  27. //                                        keyvalue = row*4+col; // 得到所按下按鍵的鍵值
  28. //                                        return keyvalue;      // 把得到的鍵值作為返回值
  29. //                                }
  30. //                                temp2 /= 2;               // temp2右移一位
  31. //                        }
  32. //                }
  33. //        }
  34. //        return 16;  // 因為定義數碼管段選表中,16對應的是全滅,故無按鍵按下時返回16
  35. //}


  36. /*************************************************
  37. * 函數名:delay_ms
  38. * 描述  :延時函數
  39. * 參數  :xms  , xms是幾延時幾毫秒
  40. * 返回值:無
  41. * 調用  :內部調用
  42. *************************************************/
  43. void delay_ms(unsigned int xms)
  44. {
  45.         unsigned char i, j;
  46.         unsigned int x;
  47.         for(x=xms;x>0;x--)
  48.         {
  49.                 i = 16;
  50.                 j = 147;
  51.                 do
  52.                 {
  53.                         while (--j);
  54.                 } while (--i);
  55.         }
  56. }
  57. /*************************************************
  58. * 函數名:key_scan
  59. * 描述  :把按下的矩陣按鍵的鍵值返回
  60. * 參數  :無
  61. * 返回值:按下的鍵值
  62. * 調用  :外部調用
  63. *************************************************/
  64. unsigned char key_scan()
  65. {
  66.         unsigned char keyvalue1,keyvalue2,a=0;
  67.         if(flag==0)
  68.         {
  69.                 keyvalue2=16;
  70.                 flag=1;
  71.         }
  72.         GPIO_KEY = 0xf0;              // 高四位為1,低四位為0
  73.         if(GPIO_KEY != 0xf0)
  74.         {
  75.                 delay_ms(10);             // 延時消抖
  76.                 if(GPIO_KEY != 0xf0)
  77.                 {
  78.                         GPIO_KEY=0xf0;
  79.                         switch(GPIO_KEY)
  80.                         {
  81.                         case 0xe0: keyvalue1 = 3;break;     // 確定矩陣按鍵被按下的位置是第幾列
  82.                         case 0xd0: keyvalue1 = 2;break;     // 0、1、2、3
  83.                         case 0xb0: keyvalue1 = 1;break;
  84.                         case 0x70: keyvalue1 = 0;break;
  85.                         }
  86.                         GPIO_KEY=0x0f;        
  87.                         // 確定矩陣按鍵被按下位置的鍵值:列(或0或1或2或3) + 行(或0或4或8或12)
  88.                         if((GPIO_KEY != 0x0d)||(GPIO_KEY != 0x0b)||(GPIO_KEY != 0x07))
  89.                                 keyvalue2 = keyvalue1;
  90.                         if(GPIO_KEY == 0x0d)
  91.                                 keyvalue2 = keyvalue1+4;
  92.                         if(GPIO_KEY == 0x0b)
  93.                                 keyvalue2 = keyvalue1+8;
  94.                         if(GPIO_KEY == 0x07)
  95.                                 keyvalue2 = keyvalue1+12;
  96.                         while((a<50)&&(GPIO_KEY!=0x0f))
  97.                         {
  98.                                 delay_ms(10);
  99.                                 a++;
  100.                         }
  101.                 }                        
  102.         }
  103.         if(GPIO_KEY==0xF0)
  104.                 keyvalue2 = 16;
  105.         return keyvalue2;
  106. }
復制代碼

單片機紅外解碼源程序如下:
  1. #include <stc8.h>
  2. #include "hc595.h"
  3. typedef unsigned char uchar;
  4. typedef unsigned int  uint;
  5. sbit ir = P3^2;               // 紅外接收
  6. uchar irtime;                 // 記錄定時器0中斷次數
  7. uchar irdata[33];             // 存放接收到的33位紅外數據的每位進入中斷的次數
  8. uchar bitnum;                 // 數組下標,用于記錄是第幾位紅外數據
  9. uchar startflag;              // 開始接收標志
  10. uchar irok;                   // 33位數據收集完成標志
  11. uchar ircode[4];              // 用于存放16位用戶碼+8位鍵值+8位鍵值反碼
  12. uchar irprosok;               // 四個碼值轉化完成標志
  13. uchar disnum[8];              // 把四個碼值分割成8位,用于數碼管顯示

  14. void Int0Init(void)           // 外部中斷0初始化
  15. {
  16.         IT0 = 1;                  // 下降沿觸發
  17.         EX0 = 1;                  // 開啟外部中斷0
  18.         EA  = 1;                  // 開總中斷
  19.         ir  = 1;                  // 紅外接收置1
  20. }

  21. void Timer0Init(void)         // 定時器0初始化,模式:12T,晶振:12MHz
  22. {
  23.         TMOD = 0x02;              // 定時器0模式2,8位自動重裝載
  24.         TH0  = 0x00;              // 256*(1/12)*12 = 0.256ms
  25.         TL0  = 0x00;
  26.         ET0  = 1;                 // 開定時器0中斷
  27.         EA   = 1;                 // 開總中斷
  28.         TR0  = 1;                 // 定時器0開始計時
  29. }

  30. void irpros(void)             // 碼值轉換
  31. {
  32.         uchar num, k, i, j;
  33.         k = 1;
  34.         for(j=0;j<4;j++)          // 四個碼值,循環四次
  35.         {
  36.                 for(i=0;i<8;i++)      // 每個碼值八位,循環八次
  37.                 {
  38.                         num = num >> 1;   // 從最低位開始接收
  39.                         if(irdata[k]>6)   // 判斷這位數據是0還是1:(0:1.12/0.256=4.4)(1:2.25/0.256=8.8)
  40.                         {
  41.                                 num = num | 0x80;
  42.                         }
  43.                         k++;
  44.                 }
  45.                 ircode[j] = num;      // 存放碼值
  46.         }
  47.         irprosok = 1;             // 碼值轉換完成標志
  48. }

  49. void irwork(void)             // 碼值分割,用于數碼管顯示
  50. {
  51.         disnum[0] = ircode[0]/16;
  52.         disnum[1] = ircode[0]%16;
  53.         disnum[2] = ircode[1]/16;
  54.         disnum[3] = ircode[1]%16;
  55.         disnum[4] = ircode[2]/16;
  56.         disnum[5] = ircode[2]%16;
  57.         disnum[6] = ircode[3]/16;
  58.         disnum[7] = ircode[3]%16;
  59. }

  60. void Int0 () interrupt 0
  61. {
  62.         if(startflag)
  63.         {
  64.                 if(irtime>32 && irtime<63)    // 8~16ms
  65.                 {
  66.                         bitnum = 0;
  67.                 }
  68.                 irdata[bitnum] = irtime;      // 存放每位進中斷的次數
  69.                 irtime = 0;                   // 清零,為下次計數做準備
  70.                 bitnum++;                     // 下標加一
  71.                 if(bitnum==33)                // 判斷是否33位數據接收完
  72.                 {
  73.                         bitnum = 0;
  74.                         irok = 1;                 // 接收完成標志
  75.                 }
  76.         }
  77.         else
  78.         {
  79.                 irtime = 0;
  80.                 startflag = 1;
  81.         }
  82. }
  83. void Timer0() interrupt 1
  84. {
  85.         irtime++;
  86. }

  87. void main()
  88. {
  89.         Int0Init();
  90.         Timer0Init();
  91.         while(1)
  92.         {
  93.                 if(irok == 1)                 // 接收完成
  94.                 {
  95.                         irpros();
  96.                         irok = 0;
  97.                 }
  98.                 if(irprosok == 1)             // 碼值轉換完成
  99.                 {
  100.                         irwork();
  101.                         irprosok = 0;
  102.                 }
  103.                 display(0,disnum[4]);         // 顯示鍵值
  104.                 display(1,disnum[5]);
  105.                 display(2,20);                // 顯示"H"
  106.         }
  107. }
復制代碼


全部資料51hei下載地址:
里面的東西,上面都貼出來了。這個可以當資料收藏.docx (59.45 KB, 下載次數: 197)
紅外接收代碼.rar (44.14 KB, 下載次數: 283)
紅外發射代碼.rar (35.38 KB, 下載次數: 272)

評分

參與人數 3黑幣 +65 收起 理由
51heizlxz + 9
Jeff_BlindCat + 6 共享資料的黑幣獎勵!樓主耐心負責解答
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:282095 發表于 2019-7-9 10:50 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:116347 發表于 2019-7-12 19:27 | 顯示全部樓層
感謝樓主分享
回復

使用道具 舉報

ID:586051 發表于 2019-7-18 09:48 | 顯示全部樓層
謝謝樓主,請問用C52需要改哪些地方
回復

使用道具 舉報

ID:427492 發表于 2019-7-18 13:52 | 顯示全部樓層
zhu6711061 發表于 2019-7-18 09:48
謝謝樓主,請問用C52需要改哪些地方

你看看紅外接收、發射、按鍵這些端口跟你的一樣不一樣,不一樣就要修改;同時看看定時器的晶振和模式
回復

使用道具 舉報

ID:427492 發表于 2019-7-18 13:55 | 顯示全部樓層
zhu6711061 發表于 2019-7-18 09:48
謝謝樓主,請問用C52需要改哪些地方

數碼管中驅動74hc595引腳不一樣的話,也要修改
回復

使用道具 舉報

ID:586051 發表于 2019-7-23 09:59 | 顯示全部樓層
請問樓主可以貼一下 hc595.h  和 display(0,disnum[]); 函數的代碼嘛?感謝   
回復

使用道具 舉報

ID:427492 發表于 2019-7-23 12:05 | 顯示全部樓層
zhu6711061 發表于 2019-7-23 09:59
請問樓主可以貼一下 hc595.h  和 display(0,disnum[]); 函數的代碼嘛?感謝

/**************************************************************/
#ifndef __HC595_H__
#define __HC595_H__

#include <STC8.h>
#include <intrins.h>

#ifndef u8                            // 重命名
#define u8 unsigned char
#endif

#ifndef u16                           // 重命名
#define u16 unsigned int
#endif

sbit P_HC595_SRCLK = P3^5;            // 數據輸入時鐘線
sbit P_HC595_RCLK  = P3^4;            // 輸出存儲器鎖存時鐘線
sbit P_HC595_SER   = P3^7;            // 串行數據輸入

void SEG_HC595send(unsigned char x);  // hc595發送一個字節數據
void display(unsigned char pos,unsigned char dat); // pos位數碼管顯示數字dat


#endif
/****************************************************************/
#include "hc595.h"

// 段選:dp、g、f、e、d、c、b、a
unsigned char const LedData[]=
   {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xFF , 0x00, 0xbf,0x7f,0x89};
//  "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"   "9"  "A"  "B"  "C"  "D"  "E"  "F" "全滅" "全亮" "-"  "."  "H"

// 位選:CS1、CS2、CS3、CS4、CS5、CS6、CS7、CS8
unsigned char const LedPos[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay_ms(unsigned int xms)   // 延時xms毫秒
{
        unsigned char i, j;
        unsigned int x;
        for(x=xms;x>0;x--)
        {
                i = 16;
                j = 147;
                do
                {
                        while (--j);
                } while (--i);
        }
}
/*************************************************
* 函數名:Send_595
* 描述  :hc595發送一個字節數據
* 參數  :dat  (位選或段選)
* 返回值:無
* 調用  :內部調用
*************************************************/

void Send_595(unsigned char dat)
{       
        u8 i;
        for(i=0; i<8; i++)
        {
                dat <<= 1;
                P_HC595_SER   = CY;
                P_HC595_SRCLK = 0;
                _nop_();
                P_HC595_SRCLK = 1;               
        }
}

/*************************************************
* 函數名:display
* 描述  :pos位數碼管顯示數字dat
* 參數  :pos,dat
* 返回值:無
* 調用  :外部調用
*************************************************/

void display(unsigned char pos,unsigned char dat)
{
        Send_595(LedPos[pos]);          //
        Send_595(LedData[dat]);
        P_HC595_RCLK = 0;
        _nop_();
        P_HC595_RCLK = 1;         
        delay_ms(2);
}
/**********************************************************/
回復

使用道具 舉報

ID:591106 發表于 2019-8-5 11:06 | 顯示全部樓層
注釋十分詳細,感謝樓主
回復

使用道具 舉報

ID:370231 發表于 2019-9-4 16:22 | 顯示全部樓層
感謝樓主分享
回復

使用道具 舉報

ID:163623 發表于 2020-1-3 22:05 | 顯示全部樓層
大佬stc8寫的用51可以用嗎
回復

使用道具 舉報

ID:427492 發表于 2020-1-6 12:50 | 顯示全部樓層
cuibaigao 發表于 2020-1-3 22:05
大佬stc8寫的用51可以用嗎

可以,有定時器,有紅外發射和接收就行
回復

使用道具 舉報

ID:452928 發表于 2020-1-7 19:23 | 顯示全部樓層
大佬,強啊 ,解釋很到位。找這紅外發送接收好久了 阿里嘎多
回復

使用道具 舉報

ID:452928 發表于 2020-1-8 14:38 | 顯示全部樓層
接收程序大體我讀懂了,但是那個INT0中斷服務程序中,8~16ms,引導碼不是9ms+4.5ms=13.5ms么? 這樣子不會影響后面數據的接收么?
回復

使用道具 舉報

ID:427492 發表于 2020-1-9 18:43 | 顯示全部樓層
nls 發表于 2020-1-8 14:38
接收程序大體我讀懂了,但是那個INT0中斷服務程序中,8~16ms,引導碼不是9ms+4.5ms=13.5ms么? 這樣子不會 ...

這個if語句,判斷最新接收的波段是不是引導碼,不是就不解碼。是的話,開始解碼。對后面數據沒有影響(發射不特別頻繁的情況下)
回復

使用道具 舉報

ID:684413 發表于 2020-1-9 23:36 | 顯示全部樓層
感謝分享
回復

使用道具 舉報

ID:658393 發表于 2020-2-7 20:31 | 顯示全部樓層
沒有人跟你說有錯誤嗎?我新手找了半天錯誤,發射那塊應該9000/26才對吧。
回復

使用道具 舉報

ID:658393 發表于 2020-2-7 20:33 | 顯示全部樓層
沒人跟你說有小錯誤嗎?發射和接收解碼都不一樣。
回復

使用道具 舉報

ID:251029 發表于 2020-3-1 10:35 | 顯示全部樓層
很好的文章,信息量大,感謝樓主的辛勤努力!
回復

使用道具 舉報

ID:427492 發表于 2020-3-7 11:19 | 顯示全部樓層
HAN??? 發表于 2020-2-7 20:33
沒人跟你說有小錯誤嗎?發射和接收解碼都不一樣。

開發板不一樣的話,是需要改參數的。我同樣的兩片開發板,試的結果是正確的。你應該根據自己的晶振頻率去修改
回復

使用道具 舉報

ID:408608 發表于 2020-4-1 23:31 | 顯示全部樓層
兩片板子這樣寫沒啥問題,不知發射有沒有更好的辦法
如果一片板子同時收發,這樣好像會有問題
發碼里面有個死循環,好像會導致收不了碼,串口,數碼管都無法正常顯示了
回復

使用道具 舉報

ID:51443 發表于 2020-4-2 09:32 | 顯示全部樓層
用樓主這個程序發碼時,引導碼9+4.5有時正常,有時發成9+3.3,有時發成6.6+4.5,甚至有時發成6.6+3.3。用的是stc15w104,不知道是什么原因
回復

使用道具 舉報

ID:427492 發表于 2020-4-2 18:41 | 顯示全部樓層
職教電子 發表于 2020-4-2 09:32
用樓主這個程序發碼時,引導碼9+4.5有時正常,有時發成9+3.3,有時發成6.6+4.5,甚至有時發成6.6+3.3。用的 ...

這個要根據自己開發板使用的晶振頻率,去計算要計數的個數
回復

使用道具 舉報

ID:427492 發表于 2020-4-2 18:47 | 顯示全部樓層
fan233 發表于 2020-4-1 23:31
兩片板子這樣寫沒啥問題,不知發射有沒有更好的辦法
如果一片板子同時收發,這樣好像會有問題
發碼里面有 ...

我沒有深入去了解這個,不太清楚其他實現方式。一個板子實現收發應該是可以實現的
回復

使用道具 舉報

ID:707144 發表于 2020-5-4 11:46 | 顯示全部樓層
親,stc8.h是什么芯片
回復

使用道具 舉報

ID:707144 發表于 2020-5-4 12:45 | 顯示全部樓層
你好,請問發送完鍵值和鍵值反碼之后,又發送了0.56ms的高電平和低電平是什么意思
回復

使用道具 舉報

ID:427492 發表于 2020-5-9 10:50 | 顯示全部樓層
妖小白 發表于 2020-5-4 11:46
親,stc8.h是什么芯片

stc8a8k64s4a12
回復

使用道具 舉報

ID:427492 發表于 2020-5-9 10:50 | 顯示全部樓層
妖小白 發表于 2020-5-4 12:45
你好,請問發送完鍵值和鍵值反碼之后,又發送了0.56ms的高電平和低電平是什么意思

結束碼
回復

使用道具 舉報

ID:628542 發表于 2020-7-4 23:57 | 顯示全部樓層
非常感謝樓主分享,很詳細的代碼
回復

使用道具 舉報

ID:797981 發表于 2020-7-5 20:01 | 顯示全部樓層
首先感謝樓主的講解和代碼!收獲很多!  但我有個問題,就是比如在接收發射“1”,也就是接收時低電平時,應該是37kHz的調制信號,也就是37kHz的0-1跳變序列,那不會頻繁觸發中斷么?
回復

使用道具 舉報

ID:495287 發表于 2020-7-7 00:38 | 顯示全部樓層
樓主大愛,針對網友耐心講解。
代碼書寫工整簡潔,吾等萌新還要學習。
回復

使用道具 舉報

ID:510861 發表于 2020-7-23 11:51 來自觸屏版 | 顯示全部樓層
感謝分享   也下載來做遙控風扇
回復

使用道具 舉報

ID:497922 發表于 2020-8-7 15:15 | 顯示全部樓層
在做類似的紅外收發的案子,過來學習的哈
回復

使用道具 舉報

ID:284050 發表于 2020-10-26 22:18 | 顯示全部樓層
能補充一下發射部分的電路原理圖嗎
回復

使用道具 舉報

ID:210959 發表于 2021-6-27 16:36 | 顯示全部樓層
按照樓主的方法,使用STC8F1K08芯片紅外發射成功,使用定時器產生載波比使用STC硬件PWM還方便,附紅外收發部分原理圖。
紅外接收.JPG
紅外發送.JPG
回復

使用道具 舉報

ID:586073 發表于 2021-10-1 14:50 | 顯示全部樓層
如果用T0的gate模式,結合int0輸入,是不是可以直接測量脈寬時間,這樣解碼部分還可以再簡潔一點。
回復

使用道具 舉報

ID:965487 發表于 2021-10-5 19:36 | 顯示全部樓層
    今天無事,學習一下紅外接收解碼,也帖上自己仿寫的程序,認為比前例子精減,但不失性能。

/*-----------------------------------------------
【實驗平臺】: QX-MCS51 單片機開發板
* 【外部晶振】: 11.0592mhz      
* 【主控芯片】: STC89C52
* 【編譯環境】: Keil μVisio4         

名稱:遙控器紅外解碼數碼管顯示
  內容:按配套遙控器會在數碼管上對應顯示鍵碼值

                  NEC 標準下的編碼表示

                其中:引導碼高電平約9000us 左右,低電平約4500us 左右;
                接收端:引導碼低電平約9000us 左右,高電平約4500us 左右;
                用戶碼16 位,數據碼16 位,共32位;
        發送端:        數據0 是用“高電平約560us +低電平約560us”表示。
                                數據1 可用“高電平約560us+低電平約1680us”表示

        接收端反轉:數據0 是用“低電平約560us +高電平約560us”表示。
                                數據1 可用“低電平約560us+高電平約1680us”表示

------------------------------------------------*/
#include<reg52.h>            //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義

sbit IR=P3^2;                          //紅外接口
sbit beep = P2^3;//蜂鳴器接口
#define DataPort P0         //定義數據端口 程序中遇到DataPort 則用P0 替換
sbit LATCH1=P2^6;                //定義鎖存使能端口 段鎖存
sbit LATCH2=P2^7;                //                 位鎖存

unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
                                                //0-F的碼表
unsigned char  irtime;        //紅外用全局變量

unsigned char IRcord[4];

void delay(unsigned int i)
{
        unsigned int m,n;
        for(m=i;m>0;m--)
                for(n=114;n>0;n--);
}

void tim0_isr (void) interrupt 1 using 1  //STC89C52 11.0592M
{
  irtime++;  //用于計數2個下降沿之間的時間         每個溢出中斷時長256*1.085us=277.7us
}

void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
{
        static unsigned char  i;             //接收紅外信號處理

                if(irtime < 63 && irtime >= 33)//跳過引導碼 TC9012的頭碼,9ms+4.5ms
             {  
                        irtime=0;
                        i=0;
                }                  
                else{
                                IRcord[i/8] >>= 1;          //i/8每處理8位換下一個元素,總的處理4個字節共32位的數據
                                 if(irtime > 6) IRcord[i/8] |= 0x80;           //位0電平時長計數上限4,位1高電平計數上限8
                            irtime = 0;
                            i++;
                        }                                                                                   //這里取6為0/1 的識別分界
                if(i > 31){ i=0; beep = 0;        delay(100); beep = 1; }
}


void TIM0init(void)//定時器0初始化
{
        TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
        TH0=0x00; //重載值
        TL0=0x00; //初始化值
        ET0=1;    //開中斷
        TR0=1;   
}
void EX0init(void)
{
IT0 = 1;   //指定外部中斷0下降沿觸發,INT0 (P3.2)
EX0 = 1;   //使能外部中斷
EA = 1;    //開總中斷
}
void SMG_show(unsigned char num)
{
        P0=dofly_DuanMa[num/16];         
        LATCH1=1;
        LATCH1=0;

        P0=0xdf;           //選中第一個數碼管
        LATCH2=1;
        LATCH2=0;
        delay(2);

        P0=dofly_DuanMa[num%16];         
        LATCH1=1;
        LATCH1=0;

        P0=0xbf;           //選中第二個數碼管
        LATCH2=1;
        LATCH2=0;
        delay(2);
}
void main(void)
{
        EX0init(); //初始化外部中斷
        TIM0init();//初始化定時器

        while(1)//主循環
        {
                SMG_show(IRcord[2]);
        }
}
回復

使用道具 舉報

ID:960784 發表于 2024-7-16 11:19 | 顯示全部樓層
51heizlxz 發表于 2021-6-27 16:36
按照樓主的方法,使用STC8F1K08芯片紅外發射成功,使用定時器產生載波比使用STC硬件PWM還方便,附紅外收發 ...

接收也是同一個單片機嗎?可以分享一下接收的原理圖嗎?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久精品一区 | 欧美一区2区三区4区公司二百 | 日韩综合在线视频 | www国产亚洲精品久久网站 | 国产精品 亚洲一区 | 精品视频在线免费观看 | 国产三区在线观看视频 | 91久久精品一区二区二区 | 国产 日韩 欧美 制服 另类 | 亚洲精品视频在线看 | 欧美日韩在线观看一区 | 欧美色影院| 日韩毛片在线观看 | 欧美综合久久 | 久久91精品国产一区二区三区 | 综合久久网| 日韩中文一区二区三区 | 成人免费观看男女羞羞视频 | 一区在线播放 | 一级视频在线免费观看 | 黄网站免费在线观看 | 久久久久免费精品国产小说色大师 | 中文字幕日本一区二区 | 国产成人精品一区二区三区四区 | 国产中文 | 日韩在线中文 | 成人毛片网站 | 国产高清区 | 日韩在线视频免费观看 | 青青99| 国产在线一区二区 | 野狼在线社区2017入口 | 91在线网 | 中文字幕在线免费观看 | 国产精品九九视频 | 色姑娘综合网 | 国产亚洲第一页 | 国产精品久久久久久高潮 | 在线视频亚洲 | 免费午夜视频在线观看 | 中文字幕一区二区三区四区 |