stc8a8k64s4a12紅外解碼LCD1602顯示
在原來解碼數碼管的程序上修復了8位LED燈初始顯示任意值bug,新增加了解碼顯示到LCD屏幕與pc串口端完全同步,可以通過三種有效解碼方式更加精確的對支持NEC協議的所有紅外遙控設備解碼,此外對于其他型號及平臺移植更為方便,希望有用到的 積極下載共享,有好的獨特想法的可以提出來共同討論,積極指正批評。
P90620-085340.jpg (2.38 MB, 下載次數: 71)
下載附件
2019-6-20 08:56 上傳
P90620-085349.jpg (3.29 MB, 下載次數: 80)
下載附件
2019-6-20 08:56 上傳
單片機源程序如下:
- ////////////////////////////////////////////////////////////
- // 紅外接收數據,查詢方式,并通過串口發送輸出
- // 晶振:22.1184MHz ,波特率:9600
- ////////////////////////////////////////////////////////////
- #include <STC8.H>
- #include "LCD1602.h"
- #define LED P0
- sbit Ir_Pin = P2^7; // 紅外接收頭信號輸出腳
- extern delay(uint time);
- uchar code lhc_table[16]="0123456789ABCDEF";
- uchar tempdata[16];
- uchar Ir_Buf[4]; // 用于保存解碼結果(Ir_Buf[0]--用戶碼L,Ir_Buf[3] --鍵反碼)
- // 獲取低電平時間 (其實是16位計數器的計數值,STC15系列定時器默認為16位自動重裝方式)
- uint Ir_Get_Low()
- {
- TL0 = 0; // 清空16位計數器0
- TH0 = 0; // 清空16位計數器0
- TR0 = 1; // 計數器0開始運行
- while (!Ir_Pin && (TH0<0x80)); // 信號引腳變成高或低電平時間>17ms退出(只要>12ms即可)
- // 0x8000=32768, 32768*0.54253uS=17777.62 uS
- TR0 = 0; // 這里 ! 優先級大于&&
- return (TH0 * 256 + TL0); // 返回16位計數器的計數值。
- }
- // 獲取高電平時間(其實是16位計數器的計數值,STC15系列定時器默認為16位自動重裝方式)
- uint Ir_Get_High()
- {
- TL0 = 0; // 清空16位計數器0
- TH0 = 0; // 清空16位計數器0
- TR0 = 1;
- while (Ir_Pin && (TH0<0x40)); // 信號引腳變成低電平或高電平時間>17ms退出
- TR0 = 0;
- return (TH0 * 256 + TL0);
- }
- void UART_init(void) // 9600@22.1184MHz
- {
- //下面代碼設置定時器1
- TMOD = 0x20; // 0010 0000 定時器1工作于方式2(8位自動重裝方式)
- TH1 = 0xFA; // 波特率:57600 /22.1184MHZ
- TL1 = 0xFA; // 波特率:57600 /22.1184MHZ
- TR1 = 1;
- //下面代碼設置定串口
- AUXR = 0x00; // 很關鍵,使用定時器1作為波特率發生器,S1ST2=0
- SCON = 0x50; // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允許接收)
- }
-
- // UART發送一字節
- void UART_Send_Byte(uchar dat)
- {
- SBUF = dat;
- while (TI == 0);
- TI = 0; // 此句可以不要,不影響后面數據的發送,只供代碼查詢數據是否發送完成
- }
- void IR_work() //紅外解碼程序
- {
- tempdata[0]=lhc_table[Ir_Buf[0]/16]; //處理客戶碼
- tempdata[1]=lhc_table[Ir_Buf[0]%16];
- tempdata[2]='-';
- tempdata[3]=lhc_table[Ir_Buf[1]/16]; //處理客戶碼
- tempdata[4]=lhc_table[Ir_Buf[1]%16];
- tempdata[5]='-';
- tempdata[6]=lhc_table[Ir_Buf[2]/16]; //處理數據碼
- tempdata[7]=lhc_table[Ir_Buf[2]%16];
- tempdata[8]='-';
- tempdata[9]=lhc_table[Ir_Buf[3]/16]; //處理數據反碼
- tempdata[10]=lhc_table[Ir_Buf[3]%16];
- LCD_write_string(5,1,tempdata);
- LED=~Ir_Buf[2];
- }
- void main()
- {
- uint time;
- uchar i,j;
- LED=0xff;
- UART_init();
- UART_Send_Byte(0X55); // 測試串口工作是否正常
- LCD_init();
- delay(20); //延時有助于穩定
- LCD_clear();
-
- LCD_write_string(0,0,"LHC-DIY-STC8");
- LCD_write_string(0,1,"code:");
- while (1)
- {
- start:
- ///////////// 接收同步信號 ///////////
- while (Ir_Pin); // 等待低電平出現
- time = Ir_Get_Low(); // 低電平區間16位計數器的計數值
- if ((time < 15667) || (time > 17510)) goto start;
- // 引導脈沖低電平8500~9500us,T=12/22.1184=0.54253uS
- // 8500/0.54253uS=15667.3 9500/0.54253uS=17510.5
- time = Ir_Get_High();
- if ((time < 7372) || (time > 9216)) goto start; // 引導脈沖高電平4000-5000us
- // 4000/0.54253uS=7372.8 5000/0.54253uS=9216
- ////////// 接收后續的4 字節數據 ////////
- for (i=0; i<4; i++) // 4個字節
- {
- for (j=0; j<8; j++) // 每個字節8位
- {
- time = Ir_Get_Low(); // 接收每位560us 低電平
- if ((time < 626) || (time > 1438)) goto start; // 340-780us
- // 340/0.54253uS=626.7 780/0.54253uS=1437.7
- time = Ir_Get_High(); // 接收每位560us或1690us高電平時間
- if ((time>626) && (time<1438)) // 時間范圍為340-780us(中心值560us),
- {
- Ir_Buf[i] >>= 1; // 因低位在先,所以數據右移,移入的最高位為0
- }
- else if ((time>2728) && (time<3502))
- { // 時間判定范圍為1480~1900us(中心值1690us)
- // 1480/0.54253uS=2727.9 1900/0.54253uS=3502.1
- Ir_Buf[i] >>= 1; // 因低位在先,所以數據右移,移入的最高位為0
- Ir_Buf[i] |= 0x80; // 最高位置1
- }
- else // 不在上述范圍內則說明為誤碼,直接退出
- {
- goto start;
- }
- }
- }
- UART_Send_Byte(Ir_Buf[0]); // 用戶碼低字節
- UART_Send_Byte(Ir_Buf[1]); // 用戶碼高字節
- UART_Send_Byte(Ir_Buf[2]); // 鍵碼
- UART_Send_Byte(Ir_Buf[3]); // 鍵反碼
- IR_work();
- }
- }
復制代碼
所有資料51hei提供下載:
03 LCD1602顯示.7z
(33.15 KB, 下載次數: 145)
2019-6-20 08:58 上傳
點擊文件名下載附件
主程序有效 下載積分: 黑幣 -5
|