基于51單片機的紅外解碼程序 1602顯示屏 可以顯示8位16進制 38k的遙控都可以,制作萬能遙控器的話這個程序可以起到作用
制作出來的實物圖如下:
1.jpg (104.1 KB, 下載次數: 42)
下載附件
2019-6-4 22:18 上傳
單片機源程序如下:
- /*********************************************************************************************
- 程序名: DHT11-1602
- 編寫人: fby
- 編寫時間: 2019年3月21日
- 硬件支持: STC89C52RC DHT11 LCD1602
- 接口說明: DHT11:VCC DATA NC GND
- *********************************************************************************************
- 說明:1、單片機是STC89C52RC,晶振頻率11.0592MHz,實驗成功。
- 2、好東西要共享,大家隨意折騰~~
- *********************************************************************************************/
- #include<reg51.h>
- #include<intrins.h>
- #include<stdio.h>
- #define uchar unsigned char //無符號字符型類型數據
- #define uint unsigned int //無符號整型數據
- #define ulong unsigned long //無符號整型數據
- #define xiao float //xiaoshu
- #define IODATA P0
- unsigned char IrValue[12]; //接收收據
- unsigned char Time;
- sbit RS=P2^6; //定義rs端口
- sbit RW=P2^5; //定義rw端口
- sbit E=P2^7;
-
- sbit IRIN=P3^2;//紅外數據io
-
- /*******************************************************************************
- * 函數名 : DelayMs()
- * 函數功能 : 延時
- * 輸入 : x
- * 輸出 : 無
- *******************************************************************************/
- void DelayMs(unsigned int x) //0.14ms誤差 0us
- {
- unsigned char i;
- while(x--)
- {
- for (i = 0; i<13; i++)
- {}
- }
- }
- /*******************************************************************************
- * 函數名 : IrInit()
- * 函數功能 : 初始化紅外線接收
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void IrInit()
- {
- IT0=1;//下降沿觸發
- EX0=1;//打開中斷0允許
- EA=1; //打開總中斷
- IRIN=1;//初始化端口
- }
- /*******************************************************************************
- * 函數名 : ReadIr()
- * 函數功能 : 讀取紅外數值的中斷函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void ReadIr() interrupt 0
- {
- unsigned char j,k;
- unsigned int err;
- Time=0;
- DelayMs(70);
- if(IRIN==0) //確認是否真的接收到正確的信號
- {
-
- err=1000; //1000*10us=10ms,超過說明接收到錯誤的信號
- /*當兩個條件都為真是循環,如果有一個條件為假的時候跳出循環,免得程序出錯的時
- 侯,程序死在這里*/
- while((IRIN==0)&&(err>0)) //等待前面9ms的低電平過去
- {
- DelayMs(1);
- err--;
- }
- if(IRIN==1) //如果正確等到9ms低電平
- {
- err=500;
- while((IRIN==1)&&(err>0)) //等待4.5ms的起始高電平過去
- {
- DelayMs(1);
- err--;
- }
- for(k=0;k<4;k++) //共有4組數據
- {
- for(j=0;j<8;j++) //接收一組數據
- {
- err=60;
- while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
- // while (!IRIN)
- {
- DelayMs(1);
- err--;
- }
- err=500;
- while((IRIN==1)&&(err>0)) //計算高電平的時間長度。
- {
- DelayMs(1);//0.14ms
- Time++;
- err--;
- if(Time>30)
- {
- EX0=1;
- return;
- }
- }
- IrValue[k]>>=1; //k表示第幾組數據
- if(Time>=8) //如果高電平出現大于565us,那么是1
- {
- IrValue[k]|=0x80;
- }
- Time=0; //用完時間要重新賦值
- }
- }
- }
- if(IrValue[2]!=~IrValue[3])
- {
- return;
- }
- }
- }
-
- void sjcl()
- {
- IrValue[4]=IrValue[0]>>4; //高位 用戶碼
- IrValue[5]=IrValue[0]&0x0f; //低位
- IrValue[6]=IrValue[1]>>4; //高位 用戶反碼
- IrValue[7]=IrValue[1]&0x0f; //低位
- IrValue[8]=IrValue[2]>>4; //高位 數據碼
- IrValue[9]=IrValue[2]&0x0f; //低位
- IrValue[10]=IrValue[3]>>4; //高位 數據反碼
- IrValue[11]=IrValue[3]&0x0f; //低位
- }
-
- /*********************************************************************************************
- 函數名:延時函數
- 調 用:Delay30us();/Delay20ms();/Delay1s();
- 參 數:無
- 返回值:無
- 結 果:延時相應時間
- 備 注:振蕩晶體為11.0592MHz(所有延時函數Copy自STC-ISP(v6.85).exe)
- **********************************************************************************************/
- void Delay30us() //@11.0592MHz-40
- {
- unsigned char i;
- i = 11;
- while (--i);
- }
- void Delay20ms() //@11.0592MHz
- {
- unsigned char i, j;
- i = 36;
- j = 217;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay1s() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /********************************************************************
- * 名稱 : bit Busy(void)
- * 功能 : 這個是一個讀狀態函數,讀出函數是否處在忙狀態
- * 輸入 : 輸入的命令值
- * 輸出 : 無
- ***********************************************************************/
- void Busy(void)
- {
- bit busy_flag = 1;
- IODATA = 0xff;
- RS = 0; //指令關
- Delay30us();
- RW = 1; //讀狀態
- Delay30us();
- E = 1; //使能高電平
- while(1)
- {
- busy_flag = (bit)(IODATA & 0x80); //強制取最高位
- if(busy_flag == 0)
- {
- break;
- }
- }
- E = 0; //E 1->0,rs=0,rw=1,
- //將數據寄存器內的數據讀到DB0~DB7,分別將狀態標志BF和地址計數器(AC)內容讀到DB7和DB6~DB0。
- }
- /********************************************************************
- * 名稱 : lcd1602_write_cmd(uchar del)
- * 功能 : 1602命令函數
- * 輸入 : 輸入的命令值
- * 輸出 : 無
- ***********************************************************************/
- void lcd1602_write_cmd(uchar del)
- {
- RS = 0;
- Delay30us();
- RW = 0;
- Delay30us();
- E = 0;
- Delay30us();
- IODATA = del;
- Delay30us();
- E = 1;
- Delay30us();
- E = 0; //E 1->0,rs=0,rw=0, 將指令代碼寫入指令寄存器中
- }
- /********************************************************************
- * 名稱 : lcd1602_write_data(uchar del)
- * 功能 : 1602寫數據函數
- * 輸入 : 需要寫入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void lcd1602_write_data(uchar del)
- {
- Busy();
- Delay30us();
- RS = 1;
- Delay30us();
- RW = 0;
- Delay30us();
- E = 0;
- Delay30us();
- IODATA = del;
- Delay30us();
- E = 1;
- Delay30us();
- E = 0; //E 1->0,rs=1,rw=0, 數據寫入數據寄存器中
- }
- /********************************************************************
- * 名稱 : lcd1602_init()
- * 功能 : 1602初始化,請參考1602的資料
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void lcd1602_init(void)
- {
- Delay20ms();
- lcd1602_write_cmd(0x38); //8位數據,雙列,5*7字形
- Delay20ms();
- lcd1602_write_cmd(0x38);
- Delay20ms();
- lcd1602_write_cmd(0x38);
- Busy();
- lcd1602_write_cmd(0x08);// 只開顯示
- Busy();
- lcd1602_write_cmd(0x01); //清屏
- Busy();
- lcd1602_write_cmd(0x06);//顯示地址遞增,即寫一個數據后,顯示位置右移一位
- Busy();
- lcd1602_write_cmd(0x0c); //開啟顯示屏,關光標,光標不閃爍
- }
- /********************************************************************
- * 名稱 : lcd1602_char(uchar hang,uchar lie,char sign)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
- L1602_char(1,5,'b')
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void lcd1602_char(uchar hang,uchar lie,char sign)
- {
- uchar a;
- if(hang == 1)
- {
- a = 0x80;
- }
- if(hang == 2)
- {
- a = 0xc0;
- }
- a = a + lie - 1;
- Busy();
- lcd1602_write_cmd(a); //置數據存貯器地址
- Busy();
- lcd1602_write_data(sign);
- }
- /********************************************************************
- * 名稱 : lcd1602_string(uchar hang,uchar lie,uchar *p)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
- L1602_string(1,5,"ab cd ef;")
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void lcd1602_string(uchar hang,uchar lie,uchar *p)
- {
- uchar a;
- if(hang == 1)
- {
- a = 0x80;
- }
- if(hang == 2)
- {
- a = 0xc0;
- }
- a = a + lie - 1;
- while(1)
- {
- Busy();
- lcd1602_write_cmd(a);
- Busy();
- lcd1602_write_data(*p);
- a++;
- p++;
- if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符結束或每行最后一個字符
- {
- break;
- }
- }
- }
- /*********************************************************************************************
- 函數名:主函數
- 調 用:無
- 參 數:無
- 返回值:無
- 結 果:讀DHT11數據并送到1602顯示
- 備 注:
- **********************************************************************************************/
- void main (void)
- {
- unsigned char k;
- Delay20ms();
- lcd1602_init(); //LCD初始化
- IrInit();
- while(1)
- {
- sjcl();
- //LcdWriteData(0x37+IrValue[4]); //將數值轉換為該顯示的ASCII碼
- //LcdWriteData(IrValue[4]+0x30); //將數值轉換為該顯示的ASCII碼
-
- lcd1602_string(1,1,"HW:");
- for(k=0;k<8;k++)
- {
- if(IrValue[k+4]>9)
- {
- lcd1602_char(1,k+4,IrValue[k+4]+0x37);
- }
- else
- {
- lcd1602_char(1,k+4,IrValue[k+4]+0x30);
- }
- }
- }
- }
-
-
復制代碼
所有資料51hei提供下載:
紅外解碼.zip
(56.82 KB, 下載次數: 53)
2019-6-4 20:40 上傳
點擊文件名下載附件
紅外解碼程序 下載積分: 黑幣 -5
|