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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5646|回復(fù): 10
收起左側(cè)

基于51單片機(jī)的空調(diào)紅外解碼程序

  [復(fù)制鏈接]
ID:499469 發(fā)表于 2019-6-4 20:43 | 顯示全部樓層 |閱讀模式
基于51單片機(jī)的紅外解碼程序   1602顯示屏  可以顯示8位16進(jìn)制 38k的遙控都可以,制作萬能遙控器的話這個程序可以起到作用

制作出來的實(shí)物圖如下:
1.jpg

單片機(jī)源程序如下:
  1. /*********************************************************************************************
  2. 程序名:    DHT11-1602
  3. 編寫人:    fby
  4. 編寫時間:  2019年3月21日
  5. 硬件支持:  STC89C52RC  DHT11  LCD1602
  6. 接口說明:  DHT11:VCC DATA NC GND
  7. *********************************************************************************************
  8. 說明:1、單片機(jī)是STC89C52RC,晶振頻率11.0592MHz,實(shí)驗(yàn)成功。
  9.           2、好東西要共享,大家隨意折騰~~
  10. *********************************************************************************************/
  11. #include<reg51.h>
  12. #include<intrins.h>
  13. #include<stdio.h>

  14. #define uchar unsigned char        //無符號字符型類型數(shù)據(jù)
  15. #define uint unsigned int //無符號整型數(shù)據(jù)
  16.         #define ulong unsigned long //無符號整型數(shù)據(jù)
  17.         #define xiao float //xiaoshu
  18. #define IODATA  P0
  19. unsigned char IrValue[12]; //接收收據(jù)
  20. unsigned char Time;

  21. sbit RS=P2^6; //定義rs端口
  22. sbit RW=P2^5; //定義rw端口
  23. sbit E=P2^7;
  24.         
  25. sbit IRIN=P3^2;//紅外數(shù)據(jù)io

  26.               
  27. /*******************************************************************************
  28. * 函數(shù)名         : DelayMs()
  29. * 函數(shù)功能                   : 延時
  30. * 輸入           : x
  31. * 輸出                  : 無
  32. *******************************************************************************/

  33. void DelayMs(unsigned int x)   //0.14ms誤差 0us
  34. {
  35. unsigned char i;
  36.   while(x--)
  37. {
  38.   for (i = 0; i<13; i++)
  39. {}
  40. }
  41. }
  42. /*******************************************************************************
  43. * 函數(shù)名         : IrInit()
  44. * 函數(shù)功能                   : 初始化紅外線接收
  45. * 輸入           : 無
  46. * 輸出                  : 無
  47. *******************************************************************************/

  48. void IrInit()
  49. {
  50.         IT0=1;//下降沿觸發(fā)
  51.         EX0=1;//打開中斷0允許
  52.         EA=1;        //打開總中斷

  53.         IRIN=1;//初始化端口
  54. }
  55. /*******************************************************************************
  56. * 函數(shù)名         : ReadIr()
  57. * 函數(shù)功能                   : 讀取紅外數(shù)值的中斷函數(shù)
  58. * 輸入           : 無
  59. * 輸出                  : 無
  60. *******************************************************************************/

  61. void ReadIr() interrupt 0
  62. {
  63.         unsigned char j,k;
  64.         unsigned int err;
  65.         Time=0;                                         
  66.         DelayMs(70);

  67.         if(IRIN==0)                //確認(rèn)是否真的接收到正確的信號
  68.         {         
  69.                
  70.                 err=1000;                                //1000*10us=10ms,超過說明接收到錯誤的信號
  71.                 /*當(dāng)兩個條件都為真是循環(huán),如果有一個條件為假的時候跳出循環(huán),免得程序出錯的時
  72.                 侯,程序死在這里*/        
  73.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低電平過去                  
  74.                 {                        
  75.                         DelayMs(1);
  76.                         err--;
  77.                 }
  78.                 if(IRIN==1)                        //如果正確等到9ms低電平
  79.                 {
  80.                         err=500;
  81.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高電平過去
  82.                         {
  83.                                 DelayMs(1);
  84.                                 err--;
  85.                         }
  86.                         for(k=0;k<4;k++)                //共有4組數(shù)據(jù)
  87.                         {                                
  88.                                 for(j=0;j<8;j++)        //接收一組數(shù)據(jù)
  89.                                 {

  90.                                         err=60;               
  91.                                         while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
  92. //                                        while (!IRIN)
  93.                                         {
  94.                                                 DelayMs(1);
  95.                                                 err--;
  96.                                         }
  97.                                         err=500;
  98.                                         while((IRIN==1)&&(err>0))         //計(jì)算高電平的時間長度。
  99.                                         {
  100.                                                 DelayMs(1);//0.14ms
  101.                                                 Time++;
  102.                                                 err--;
  103.                                                 if(Time>30)
  104.                                                 {
  105.                                                         EX0=1;
  106.                                                         return;
  107.                                                 }
  108.                                         }
  109.                                         IrValue[k]>>=1;         //k表示第幾組數(shù)據(jù)
  110.                                         if(Time>=8)                        //如果高電平出現(xiàn)大于565us,那么是1
  111.                                         {
  112.                                                 IrValue[k]|=0x80;
  113.                                         }
  114.                                         Time=0;                //用完時間要重新賦值                                                        
  115.                                 }
  116.                         }
  117.                 }
  118.                 if(IrValue[2]!=~IrValue[3])
  119.                 {
  120.                         return;
  121.                 }
  122.         }                        
  123. }


  124.    

  125. void sjcl()
  126. {
  127.                 IrValue[4]=IrValue[0]>>4;                          //高位  用戶碼
  128.                 IrValue[5]=IrValue[0]&0x0f;                //低位        

  129.     IrValue[6]=IrValue[1]>>4;                          //高位   用戶反碼
  130.                 IrValue[7]=IrValue[1]&0x0f;                //低位        

  131.     IrValue[8]=IrValue[2]>>4;                          //高位   數(shù)據(jù)碼
  132.                 IrValue[9]=IrValue[2]&0x0f;                //低位

  133.     IrValue[10]=IrValue[3]>>4;                          //高位  數(shù)據(jù)反碼
  134.                 IrValue[11]=IrValue[3]&0x0f;                //低位        

  135. }

  136.         

  137. /*********************************************************************************************
  138. 函數(shù)名:延時函數(shù)
  139. 調(diào)  用:Delay30us();/Delay20ms();/Delay1s();
  140. 參  數(shù):無
  141. 返回值:無
  142. 結(jié)  果:延時相應(yīng)時間
  143. 備  注:振蕩晶體為11.0592MHz(所有延時函數(shù)Copy自STC-ISP(v6.85).exe)
  144. **********************************************************************************************/
  145. void Delay30us()                //@11.0592MHz-40
  146. {
  147.         unsigned char i;

  148.         i = 11;
  149.         while (--i);
  150. }


  151. void Delay20ms()                //@11.0592MHz
  152. {
  153.         unsigned char i, j;

  154.         i = 36;
  155.         j = 217;
  156.         do
  157.         {
  158.                 while (--j);
  159.         } while (--i);
  160. }


  161. void Delay1s()                //@11.0592MHz
  162. {
  163.         unsigned char i, j, k;

  164.         _nop_();
  165.         i = 8;
  166.         j = 1;
  167.         k = 243;
  168.         do
  169.         {
  170.                 do
  171.                 {
  172.                         while (--k);
  173.                 } while (--j);
  174.         } while (--i);
  175. }





  176. /********************************************************************
  177. * 名稱 : bit Busy(void)
  178. * 功能 : 這個是一個讀狀態(tài)函數(shù),讀出函數(shù)是否處在忙狀態(tài)
  179. * 輸入 : 輸入的命令值
  180. * 輸出 : 無
  181. ***********************************************************************/
  182. void Busy(void)
  183. {
  184. bit busy_flag = 1;
  185. IODATA  = 0xff;
  186. RS = 0;          //指令關(guān)
  187. Delay30us();
  188. RW = 1;          //讀狀態(tài)
  189. Delay30us();
  190. E = 1;        //使能高電平
  191. while(1)
  192. {
  193. busy_flag = (bit)(IODATA  & 0x80); //強(qiáng)制取最高位
  194. if(busy_flag == 0)
  195. {
  196. break;
  197. }
  198. }
  199. E = 0;           //E 1->0,rs=0,rw=1,
  200.            //將數(shù)據(jù)寄存器內(nèi)的數(shù)據(jù)讀到DB0~DB7,分別將狀態(tài)標(biāo)志BF和地址計(jì)數(shù)器(AC)內(nèi)容讀到DB7和DB6~DB0。

  201. }

  202. /********************************************************************
  203. * 名稱 : lcd1602_write_cmd(uchar del)
  204. * 功能 : 1602命令函數(shù)
  205. * 輸入 : 輸入的命令值
  206. * 輸出 : 無
  207. ***********************************************************************/
  208. void lcd1602_write_cmd(uchar del)
  209. {
  210. RS = 0;
  211. Delay30us();
  212. RW = 0;
  213. Delay30us();
  214. E = 0;
  215. Delay30us();
  216. IODATA  = del;
  217. Delay30us();
  218. E = 1;
  219. Delay30us();
  220. E = 0;                        //E 1->0,rs=0,rw=0, 將指令代碼寫入指令寄存器中
  221. }

  222. /********************************************************************
  223. * 名稱 : lcd1602_write_data(uchar del)
  224. * 功能 : 1602寫數(shù)據(jù)函數(shù)
  225. * 輸入 : 需要寫入1602的數(shù)據(jù)
  226. * 輸出 : 無
  227. ***********************************************************************/

  228. void lcd1602_write_data(uchar del)
  229. {
  230. Busy();      
  231. Delay30us();
  232. RS = 1;
  233. Delay30us();
  234. RW = 0;
  235. Delay30us();
  236. E = 0;
  237. Delay30us();
  238. IODATA  = del;
  239. Delay30us();
  240. E = 1;
  241. Delay30us();
  242. E = 0;                          //E 1->0,rs=1,rw=0, 數(shù)據(jù)寫入數(shù)據(jù)寄存器中
  243. }

  244. /********************************************************************
  245. * 名稱 : lcd1602_init()
  246. * 功能 : 1602初始化,請參考1602的資料
  247. * 輸入 : 無
  248. * 輸出 : 無
  249. ***********************************************************************/
  250. void lcd1602_init(void)
  251. {
  252. Delay20ms();
  253. lcd1602_write_cmd(0x38);         //8位數(shù)據(jù),雙列,5*7字形
  254. Delay20ms();
  255. lcd1602_write_cmd(0x38);
  256. Delay20ms();
  257. lcd1602_write_cmd(0x38);
  258. Busy();
  259. lcd1602_write_cmd(0x08);// 只開顯示
  260. Busy();   
  261. lcd1602_write_cmd(0x01);        //清屏
  262. Busy();
  263. lcd1602_write_cmd(0x06);//顯示地址遞增,即寫一個數(shù)據(jù)后,顯示位置右移一位
  264. Busy();
  265. lcd1602_write_cmd(0x0c);        //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍
  266. }

  267. /********************************************************************
  268. * 名稱 : lcd1602_char(uchar hang,uchar lie,char sign)
  269. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調(diào)用該函數(shù)如下
  270. L1602_char(1,5,'b')
  271. * 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
  272. * 輸出 : 無
  273. ***********************************************************************/
  274. void lcd1602_char(uchar hang,uchar lie,char sign)
  275. {
  276. uchar a;
  277. if(hang == 1)
  278. {
  279. a = 0x80;
  280. }
  281. if(hang == 2)
  282. {
  283. a = 0xc0;
  284. }
  285. a = a + lie - 1;
  286. Busy();
  287. lcd1602_write_cmd(a);  //置數(shù)據(jù)存貯器地址
  288. Busy();
  289. lcd1602_write_data(sign);
  290. }




  291. /********************************************************************
  292. * 名稱 : lcd1602_string(uchar hang,uchar lie,uchar *p)
  293. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
  294. L1602_string(1,5,"ab cd ef;")
  295. * 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
  296. * 輸出 : 無
  297. ***********************************************************************/

  298. void lcd1602_string(uchar hang,uchar lie,uchar *p)
  299. {
  300. uchar a;
  301. if(hang == 1)
  302. {
  303. a = 0x80;
  304. }
  305. if(hang == 2)
  306. {
  307. a = 0xc0;
  308. }
  309. a = a + lie - 1;
  310. while(1)
  311. {
  312. Busy();
  313. lcd1602_write_cmd(a);
  314. Busy();
  315. lcd1602_write_data(*p);
  316. a++;
  317. p++;   
  318. if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符結(jié)束或每行最后一個字符
  319. {
  320. break;
  321. }
  322. }
  323. }




  324. /*********************************************************************************************
  325. 函數(shù)名:主函數(shù)
  326. 調(diào)  用:無
  327. 參  數(shù):無
  328. 返回值:無
  329. 結(jié)  果:讀DHT11數(shù)據(jù)并送到1602顯示
  330. 備  注:
  331. **********************************************************************************************/
  332. void main (void)
  333. {
  334.     unsigned char k;
  335.        Delay20ms();
  336.         lcd1602_init();         //LCD初始化
  337.               IrInit();        
  338.         while(1)
  339.         {
  340.         sjcl();
  341.                         //LcdWriteData(0x37+IrValue[4]);        //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  342.                         //LcdWriteData(IrValue[4]+0x30);        //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  343.      
  344.       lcd1602_string(1,1,"HW:");
  345.         for(k=0;k<8;k++)
  346.                         {
  347.                 if(IrValue[k+4]>9)
  348.                                                                 {
  349.                 lcd1602_char(1,k+4,IrValue[k+4]+0x37);
  350.                 }
  351.                                  else
  352.                            {
  353.                                  lcd1602_char(1,k+4,IrValue[k+4]+0x30);
  354.                                   }



  355. }
  356. }
  357. }
  358.                                 
  359.                                 
復(fù)制代碼

所有資料51hei提供下載:
紅外解碼.zip (56.82 KB, 下載次數(shù): 53)


評分

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

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:499469 發(fā)表于 2019-6-4 20:46 | 顯示全部樓層
按照 順序顯示 用戶碼 用戶反碼  數(shù)據(jù)碼 和數(shù)據(jù)反碼  ,空調(diào)遙控比較特殊,
回復(fù)

使用道具 舉報(bào)

ID:277550 發(fā)表于 2019-6-4 23:02 | 顯示全部樓層
還有一些是長度不同。


像格力的空調(diào)遙控器,是40位,各功能不同的拼合,每次都發(fā)送這40位。但起始碼相似的


音響的也不同。
回復(fù)

使用道具 舉報(bào)

ID:277550 發(fā)表于 2019-6-4 23:05 | 顯示全部樓層
這有一篇空調(diào)編碼的,可以參考 https://my.oschina.net/u/1242247/blog/3052004
回復(fù)

使用道具 舉報(bào)

ID:398534 發(fā)表于 2019-6-5 12:40 | 顯示全部樓層
本帖最后由 51_User 于 2019-6-5 14:20 編輯

我是新手,正好在學(xué)習(xí)紅外解碼,遇到困難,望指教。
我采用P32口中斷和定時器方式接收解碼紅外信號,想法是中斷為低電平跳邊沿方式,紅外遙控器按下一個按鍵后,發(fā)出的一幀數(shù)據(jù)里的每個脈沖都能引起中斷響應(yīng),在中斷響應(yīng)程序里保存通過定時器計(jì)算出的前后兩個低電平脈沖之間的時間,用于解碼。
實(shí)際上運(yùn)行程序,無法解碼。
經(jīng)過多次測試后,發(fā)現(xiàn)好像單片機(jī)的中斷無法對紅外遙控器發(fā)出的一幀數(shù)據(jù)里的每個脈沖都響應(yīng),實(shí)際上似乎只響應(yīng)數(shù)次(原本以為33個脈沖,應(yīng)該會有33次中斷響應(yīng))。
請問我對紅外信號的中斷響應(yīng)的理解是不是錯了。
附上中斷程序和定時器源碼,請幫忙分析指教。

void Infraredrevive() interrupt 0
{
        if (timercounter>31 && timercounter<50)//判斷是否為NEC編碼引導(dǎo)碼

        {
        //計(jì)算引導(dǎo)碼接收次數(shù)13500x11.592/12/256=48,識別引導(dǎo)碼的定時器計(jì)數(shù)為48次
       //識別引導(dǎo)碼丟掉,不保存
                count_i=0;//數(shù)組下標(biāo)清零,準(zhǔn)備保存脈沖時間
        }

        
                if(newpulse_flag==1)          //下一個pulse來臨,保存兩個跳低電平pulse之間的計(jì)時器時間倍數(shù)
                {
                         timerArray[count_i]=timercounter;
                        count_i=count_i+1;
        
                }else
                {
                         newpulse_flag=1;//下一個pulse來臨標(biāo)志,也是為了識別第一個pulse的開始

                }        
        
                if (count_i==32)//33個脈沖信號,丟掉引導(dǎo)碼,共32個信號
                {
                  decode_pulse();//33個脈沖信號接收結(jié)束,調(diào)用解碼函數(shù)
                        count_i=0;

                }
                 timercounter=0;//timer時間倍數(shù)清零,用于下一個計(jì)數(shù)


}

void timer0() interrupt 1//定時器中斷一次256x12/1105920秒
{
     timercounter++;

}


void IRinitial()//中斷設(shè)定初始化
{               ///*中斷設(shè)定開始
    EA=1;//中斷總開關(guān)
//    IE0=0;//
    EX0=1;//外部中斷0
    ET0=1;//定時器T0
    TR0=1;//啟動T0定時器,后面需要放在中斷程序里嵌套使用定時器 ,清零
//    TF0=0;//為timer溢出標(biāo)志位,用于判斷
    TMOD=0x02;//設(shè)置定時器t0為8位模式,自動裝入
    TH0=0;//196;//重裝數(shù)據(jù),為了精確時間,每次跳12/11059200秒
    TL0=0;//196;//初始值
    IT0=1;//下降沿觸發(fā)
//中斷設(shè)定結(jié)束*/
}

回復(fù)

使用道具 舉報(bào)

ID:398534 發(fā)表于 2019-6-5 12:49 | 顯示全部樓層
我是新手,正好在學(xué)習(xí)紅外信號解碼,遇到困難,望高手指教。
我想通過中斷響應(yīng)一次紅外遙控器發(fā)出的一幀數(shù)據(jù)(有33個脈沖)的每個脈沖信號來啟動定時器計(jì)算并保存脈沖信號的寬度來解碼紅外信號。
但是實(shí)際上一直不成功。
通過多次檢查中間變量的值,發(fā)現(xiàn)一幀紅外數(shù)據(jù)雖然有33個脈沖,但是實(shí)際上只會引起幾次中斷,并不是33此。
請問我原本希望一幀數(shù)據(jù)的33個脈沖都能引起中斷響應(yīng)的想法是錯誤的嗎?實(shí)際上一幀數(shù)據(jù)會引起幾次中斷響應(yīng)?
回復(fù)

使用道具 舉報(bào)

ID:499469 發(fā)表于 2019-6-5 12:53 | 顯示全部樓層
devcang 發(fā)表于 2019-6-4 23:02
還有一些是長度不同。

受教了 我是業(yè)余玩玩,40位還真鬧不明白了 哈哈
回復(fù)

使用道具 舉報(bào)

ID:73182 發(fā)表于 2019-6-5 14:01 | 顯示全部樓層
感謝分享
回復(fù)

使用道具 舉報(bào)

ID:425846 發(fā)表于 2019-6-7 16:40 來自觸屏版 | 顯示全部樓層
肯定會有33個下降沿啊
回復(fù)

使用道具 舉報(bào)

ID:398534 發(fā)表于 2019-6-20 20:13 | 顯示全部樓層
感謝回復(fù)。
那我可能抓錯了。
自己再研究一下。
回復(fù)

使用道具 舉報(bào)

ID:479579 發(fā)表于 2020-3-15 17:37 | 顯示全部樓層
51_User 發(fā)表于 2019-6-20 20:13
感謝回復(fù)。
那我可能抓錯了。
自己再研究一下。

中斷程序如果執(zhí)行周期過長,同時你進(jìn)入中斷后應(yīng)該是關(guān)閉中斷的。所以肯定會漏掉部分下降沿的。所以你那個方法在51單片機(jī)中無法實(shí)現(xiàn)。除非是有時鐘頻率更高的單片機(jī)來實(shí)現(xiàn)你的方法。
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 免费视频中文字幕 | 中文字幕亚洲一区二区va在线 | 国产精品美女一区二区三区 | 欧美aⅴ在线观看 | 日韩1区| 午夜电影网| 成人影院在线观看 | 日本精品裸体写真集在线观看 | 久久99精品国产麻豆婷婷 | 99视频免费在线 | 国产欧美精品一区二区 | 高清18麻豆 | 色免费视频 | www.亚洲精品| 欧美理论片在线 | 国产精品久久一区 | 久久久成人网 | 日韩一级 | 国产成人久久精品一区二区三区 | 97色在线视频 | 欧美一区二区三区 | 97久久精品午夜一区二区 | 一区二区中文 | 做a视频 | 欧洲免费视频 | 国产乱码精品一品二品 | 欧美日韩精选 | 久久99精品久久久 | 看特级黄色片 | 欧美国产精品一区二区三区 | www.99久久.com | 亚洲精品福利视频 | 国产1区2区在线观看 | 午夜精品网站 | 亚洲一区二区三区四区五区午夜 | 孕妇一级毛片 | 中文字幕一区在线 | 国产精品日日做人人爱 | 中文字幕视频三区 | 免费a国产 | 蜜桃视频在线观看免费视频网站www |