標(biāo)題:
51單片機(jī)38k紅外解碼程序與制作
[打印本頁]
作者:
1091212269
時(shí)間:
2019-6-8 20:49
標(biāo)題:
51單片機(jī)38k紅外解碼程序與制作
上次大神指點(diǎn)后做了一些改進(jìn)顯示16位16進(jìn)制的數(shù)據(jù),二進(jìn)制就是64位。頻率是38k的?照{(diào),電視,風(fēng)扇,只要是家電的紅外95%以上都可以解碼,如果解碼空調(diào),建議每次使用前復(fù)位一次,清空數(shù)組的程序一直寫失敗,大神可以來改一下。另外發(fā)現(xiàn)部分手機(jī)(測(cè)試榮耀9)打開相機(jī)的時(shí)候會(huì)觸發(fā)中斷,讓數(shù)據(jù)變得不正常。
制作出來的實(shí)物圖如下:
微信圖片_20190608204008.jpg
(130.52 KB, 下載次數(shù): 47)
下載附件
2019-6-8 20:40 上傳
單片機(jī)源程序如下:
/*********************************************************************************************
程序名: DHT11-1602
編寫人: fby
硬件支持: STC89C52RC DHT11 LCD1602
接口說明: DHT11:VCC DATA NC GND
*********************************************************************************************
說明:1、單片機(jī)是STC89C52RC,晶振頻率11.0592MHz,實(shí)驗(yàn)成功。
2、好東西要共享,大家隨意折騰~~
*********************************************************************************************/
#include<reg51.h>
#include<intrins.h>
#include<stdio.h>
#define uchar unsigned char //無符號(hào)字符型類型數(shù)據(jù)
#define uint unsigned int //無符號(hào)整型數(shù)據(jù)
#define ulong unsigned long //無符號(hào)整型數(shù)據(jù)
#define xiao float //xiaoshu
#define IODATA P0
unsigned char IrValue[24]; //接收收據(jù)
unsigned char Time;
sbit RS=P2^6; //定義rs端口
sbit RW=P2^5; //定義rw端口
sbit E=P2^7;
sbit IRIN=P3^2;//紅外數(shù)據(jù)io
/*******************************************************************************
* 函數(shù)名 : DelayMs()
* 函數(shù)功能 : 延時(shí)
* 輸入 : x
* 輸出 : 無
*******************************************************************************/
void DelayMs(unsigned int x) //0.14ms誤差 0us
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++)
{}
}
}
/*******************************************************************************
* 函數(shù)名 : IrInit()
* 函數(shù)功能 : 初始化紅外線接收
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿觸發(fā)
EX0=1;//打開中斷0允許
EA=1; //打開總中斷
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函數(shù)名 : ReadIr()
* 函數(shù)功能 : 讀取紅外數(shù)值的中斷函數(shù)
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
//數(shù)據(jù)處理
void sjcl()
{
IrValue[8]=IrValue[0]>>4; //高位 用戶碼
IrValue[9]=IrValue[0]&0x0f; //低位
IrValue[10]=IrValue[1]>>4; //高位 用戶反碼
IrValue[11]=IrValue[1]&0x0f; //低位
IrValue[12]=IrValue[2]>>4; //高位 數(shù)據(jù)碼
IrValue[13]=IrValue[2]&0x0f; //低位
IrValue[14]=IrValue[3]>>4; //高位 數(shù)據(jù)反碼
IrValue[15]=IrValue[3]&0x0f; //低位
IrValue[16]=IrValue[4]>>4; //高位 數(shù)據(jù)反碼
IrValue[17]=IrValue[4]&0x0f; //低位
IrValue[18]=IrValue[5]>>4; //高位 數(shù)據(jù)反碼
IrValue[19]=IrValue[5]&0x0f; //低位
IrValue[20]=IrValue[6]>>4; //高位 數(shù)據(jù)反碼
IrValue[21]=IrValue[6]&0x0f; //低位
IrValue[22]=IrValue[7]>>4; //高位 數(shù)據(jù)反碼
IrValue[23]=IrValue[7]&0x0f; //低位
}
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;
DelayMs(70);
if(IRIN==0) //確認(rèn)是否真的接收到正確的信號(hào)
{
err=1000; //1000*10us=10ms,超過說明接收到錯(cuò)誤的信號(hào)
/*當(dāng)兩個(gè)條件都為真是循環(huán),如果有一個(gè)條件為假的時(shí)候跳出循環(huán),免得程序出錯(cuò)的時(shí)
侯,程序死在這里*/
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<8;k++) //共有8組數(shù)據(jù)
{
for(j=0;j<8;j++) //接收一組數(shù)據(jù)
{
err=60;
while((IRIN==0)&&(err>0))//等待信號(hào)前面的560us低電平過去
// while (!IRIN)
{
DelayMs(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //計(jì)算高電平的時(shí)間長(zhǎng)度。
{
DelayMs(1);//0.14ms
Time++;
err--;
if(Time>30)
{
EX0=1;
return;
}
}
IrValue[k]>>=1; //k表示第幾組數(shù)據(jù)
if(Time>=8) //如果高電平出現(xiàn)大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完時(shí)間要重新賦值
}
}
}
return;
}
sjcl(); //數(shù)據(jù)處理
}
/*********************************************************************************************
函數(shù)名:延時(shí)函數(shù)
調(diào) 用:Delay30us();/Delay20ms();/Delay1s();
參 數(shù):無
返回值:無
結(jié) 果:延時(shí)相應(yīng)時(shí)間
備 注:振蕩晶體為11.0592MHz(所有延時(shí)函數(shù)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)
* 功能 : 這個(gè)是一個(gè)讀狀態(tài)函數(shù),讀出函數(shù)是否處在忙狀態(tài)
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
void Busy(void)
{
bit busy_flag = 1;
IODATA = 0xff;
RS = 0; //指令關(guān)
Delay30us();
RW = 1; //讀狀態(tài)
Delay30us();
E = 1; //使能高電平
while(1)
{
busy_flag = (bit)(IODATA & 0x80); //強(qiáng)制取最高位
if(busy_flag == 0)
{
break;
}
}
E = 0; //E 1->0,rs=0,rw=1,
//將數(shù)據(jù)寄存器內(nèi)的數(shù)據(jù)讀到DB0~DB7,分別將狀態(tài)標(biāo)志BF和地址計(jì)數(shù)器(AC)內(nèi)容讀到DB7和DB6~DB0。
}
/********************************************************************
* 名稱 : lcd1602_write_cmd(uchar del)
* 功能 : 1602命令函數(shù)
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
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寫數(shù)據(jù)函數(shù)
* 輸入 : 需要寫入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
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, 數(shù)據(jù)寫入數(shù)據(jù)寄存器中
}
/********************************************************************
* 名稱 : lcd1602_init()
* 功能 : 1602初始化,請(qǐng)參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void lcd1602_init(void)
{
Delay20ms();
lcd1602_write_cmd(0x38); //8位數(shù)據(jù),雙列,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);//顯示地址遞增,即寫一個(gè)數(shù)據(jù)后,顯示位置右移一位
Busy();
lcd1602_write_cmd(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍
}
/********************************************************************
* 名稱 : lcd1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符顯示"b" ,調(diào)用該函數(shù)如下
L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
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); //置數(shù)據(jù)存貯器地址
Busy();
lcd1602_write_data(sign);
}
/********************************************************************
* 名稱 : lcd1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
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)) //字符結(jié)束或每行最后一個(gè)字符
{
break;
}
}
}
/*********************************************************************************************
函數(shù)名:主函數(shù)
調(diào) 用:無
參 數(shù):無
返回值:無
結(jié) 果:讀DHT11數(shù)據(jù)并送到1602顯示
備 注:
**********************************************************************************************/
void main (void)
{
unsigned char k;
Delay20ms();
lcd1602_init(); //LCD初始化
IrInit(); //紅外初始化
while(1)
{
//LcdWriteData(0x37+IrValue[4]); //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
//LcdWriteData(IrValue[4]+0x30); //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
lcd1602_string(1,1,"HWJM:");
for(k=0;k<16;k++)
{
if(IrValue[k+8]>9)
{
lcd1602_char(2,k+1,IrValue[k+8]+0x37);
}
else
{
lcd1602_char(2,k+1,IrValue[k+8]+0x30);
}
}
}
}
復(fù)制代碼
所有資料51hei提供下載:
紅外解碼.zip
(57.38 KB, 下載次數(shù): 55)
2019-6-8 20:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
1091212269
時(shí)間:
2019-6-8 20:50
后面為0的是沒有數(shù)據(jù),可以不用看
作者:
1025119291
時(shí)間:
2019-6-9 17:02
雖然看不懂,還是默默點(diǎn)個(gè)贊
作者:
玉萌業(yè)余發(fā)展
時(shí)間:
2023-3-2 15:16
我試了我只風(fēng)扇遙控器,按同樣的鍵,每次顯示的碼都不一樣
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1