當前位置:首頁 » 編程語言 » 紅外解碼c語言
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

紅外解碼c語言

發布時間: 2022-07-28 10:29:55

1. 高分請教高人,紅外遙控解碼程序C語言,要求每一行都解釋為什麼什麼作用。非常感謝!!先給100分,好再加

#include <reg52.h> //特殊寄存器頭文件

#define c(x) (x*110592/120000) //是晶振值,為計數器計一下所需要的微秒數,120000為12M,110592為11.0592M

sbit Ir_Pin=P3^3; //位聲明,把P3.3/外部中斷1的狀態讀到Ir_Pin中

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共陽極數碼顯示碼0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7}; //位選編碼

unsigned char Led_Buf[4]; //顯示緩沖區
char Led_Index; //位選信號定義

unsigned char Ir_Buf[4]; //用於保存解碼結果

//==============================================================
//數碼管掃描
timer0() interrupt 1 using 1 //定時器中斷零程序
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256; //定時器0設定約1000us中斷一次,用於數碼管掃描
P0=0xff; //數碼管初始顯示零
P2=Led_Sel[Led_Index]; //位選
P0=Led_Tab[Led_Buf[Led_Index]]; //段選

if(++Led_Index>3) Led_Index=0; //四個掃描完了,到第一個數碼管
}
//==============================================================
unsigned int Ir_Get_Low() //脈沖為低電平的時間
{
TL1=0;
TH1=0; //為定時器1賦初值
TR1=1; //開啟定時器1
while(!Ir_Pin && (TH1&0x80)==0); //判斷,如果P3.3口為低電平則執行TR1=0
TR1=0; //關閉定時器1
return TH1*256+TL1; //返回TH1*256+TL1的值
}
//=============================================================
unsigned int Ir_Get_High() //脈沖高電平時間
{
TL1=0;
TH1=0; //為定時器1賦初值
TR1=1; //開啟定時器1
while(Ir_Pin && (TH1&0x80)==0); //判斷,如果P3.3口為低電平則執行TR1=0
TR1=0; //關閉定時器1
return TH1*256+TL1; //返回TH1*256+TL1的值
}
//==============================================================
main()
{
unsigned int temp;
char i,j;
Led_Index=1;

TMOD=0x11;
TL0=(65536-1000)%256;
TH0=(65536-1000)/256; //定時器0設定約1000us中斷一次,用於數碼管掃描
EA=1; //開總中斷
ET0=1; //定時計數器0的開放控制位
TR0=1; //定時器0的運行控制位

Led_Buf[0]=0;
Led_Buf[1]=0;
Led_Buf[2]=0;
Led_Buf[3]=0; //顯示區設成0

do{
restart:
while(Ir_Pin); //判斷P3.3口
temp=Ir_Get_Low(); //取脈沖為低電平的時間
if(temp<c(8500) || temp>c(9500)) continue; //引導脈沖低電平9000
temp=Ir_Get_High(); //取脈沖高電平時間
if(temp<c(4000) || temp>c(5000)) continue; //引導脈沖高電平4500
for(i=0;i<4;i++) //4個位元組
for(j=0;j<8;j++) //每個位元組8位
{
temp=Ir_Get_Low();
if(temp<c(200) || temp>c(800)) goto restart; //根據編碼格式,低電平小於0.2ms大於0.8ms視為無效電平,重新檢測
temp=Ir_Get_High();
if(temp<c(200) || temp>c(2000)) goto restart; //根據編碼格式,低電平小於0.2ms大於2ms視為無效電平,重新檢測
Ir_Buf[i]>>=1; //把Ir_Buf[i]右移一位,然後賦值給Ir_Buf[i]
if(temp>c(1120)) Ir_Buf[i]|=0x80; //根據編碼格式,如果電平大於1.12ms,則把0x80賦值給Ir_Buf[i]
}
Led_Buf[0]=Ir_Buf[2]&0xf;
Led_Buf[1]=(Ir_Buf[2]/16)&0xf;
Led_Buf[2]=Ir_Buf[3]&0xf;
Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //顯示結果
}while(1);
}

2. 紅外解碼

這個看是用的什麼編碼,一般都是用NEC協議編的,建議你去文庫查查NEC協議內容,這里我可以給你個紅外解碼樣板。這是別人寫的,我驗證過,程序是可行的,如果想利用解碼做其他方面的控制,改改程序就行,看下面
/*-----------------------------------------------
名稱:遙控器紅外解碼數碼管顯示
論壇:www.doflye.net
編寫:shifang
日期:2009.5
修改:無
內容:按配套遙控器上1-9會在數碼管上對應顯示
------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit IR=P3^2; //紅外介面標志
#define DataPort P0 //定義數據埠 程序中遇到DataPort 則用P0 替換
sbit LATCH1=P2^2;//定義鎖存使能埠 段鎖存
sbit LATCH2=P2^3;// 位鎖存
/*------------------------------------------------
全局變數聲明
------------------------------------------------*/
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 顯示段碼值0~9
unsigned char irtime;//紅外用全局變數
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/*------------------------------------------------
函數聲明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
/*------------------------------------------------
定時器0中斷處理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用於計數2個下降沿之間的時間
}
/*------------------------------------------------
外部中斷0中斷處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
{
static unsigned char i; //接收紅外信號處理
static bit startflag; //是否開始處理標志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
i=0;
irdata[i]=irtime;//存儲每個電平的持續時間,用於以後判斷是0還是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
/*------------------------------------------------
定時器0初始化
------------------------------------------------*/
void TIM0init(void)//定時器0初始化
{
TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
TH0=0x00; //重載值
TL0=0x00; //初始化值
ET0=1; //開中斷
TR0=1;
}
/*------------------------------------------------
外部中斷0初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1; //指定外部中斷0下降沿觸發,INT0 (P3.2)
EX0 = 1; //使能外部中斷
EA = 1; //開總中斷
}
/*------------------------------------------------
鍵值處理
------------------------------------------------*/
void Ir_work(void)//紅外鍵值散轉程序
{
switch(IRcord[2])//判斷第三個數碼值
{
case 0x0c:DataPort=dofly_DuanMa[1];break;//1 顯示相應的按鍵值
case 0x18:DataPort=dofly_DuanMa[2];break;//2
case 0x5e:DataPort=dofly_DuanMa[3];break;//3
case 0x08:DataPort=dofly_DuanMa[4];break;//4
case 0x1c:DataPort=dofly_DuanMa[5];break;//5
case 0x5a:DataPort=dofly_DuanMa[6];break;//6
case 0x42:DataPort=dofly_DuanMa[7];break;//7
case 0x52:DataPort=dofly_DuanMa[8];break;//8
case 0x4a:DataPort=dofly_DuanMa[9];break;//9
default:break;
}
irpro_ok=0;//處理完成標志
}
/*------------------------------------------------
紅外碼值處理
------------------------------------------------*/
void Ircordpro(void)//紅外碼值處理函數
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //處理4個位元組
{
for(j=1;j<=8;j++) //處理1個位元組8位
{
cord=irdata[k];
if(cord>7)//大於某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//處理完畢標志位置1
}
/*------------------------------------------------
主函數
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中斷
TIM0init();//初始化定時器
DataPort=0xfe; //取位碼 第一位數碼管選通,即二進制1111 1110
LATCH2=1; //位鎖存
LATCH2=0;
while(1)//主循環
{
if(irok) //如果接收好了進行紅外處理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果處理好後進行工作處理,如按對應的按鍵後顯示對應的數字等
{
Ir_work();
}
}
}

3. 急求紅外發射與解碼的c程序

(1)發送程序
#include <reg52.h>

static bit OP; //紅外發射管的亮滅
static unsigned int count; //延時計數器
static unsigned int endcount; //終止延時計數
static unsigned int temp; //按鍵
static unsigned char flag; //紅外發送標志
static unsigned char num;
sbit ir_in=P3^4;
char iraddr1; //十六位地址的第一個位元組
char iraddr2; //十六位地址的第二個位元組
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 2009-8-11 <br>4 <br>紅外數據傳輸 <br>0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共陽數碼管 0~~f
void SendIRdata(char p_irdata);
void delay(unsigned int);
void keyscan();

/******************主函數**************************/
void main(void)
{
num=0;
P2=0x3f;
count = 0;
flag = 0;
OP = 0;
ir_in= 0;

EA = 1; //允許CPU中斷
TMOD = 0x11; //設定時器0和1為16位模式1
ET0 = 1; //定時器0中斷允許

TH0 = 0xFF;
TL0 = 0xE6; //設定時值0為38K 也就是每隔26us中斷一次
TR0 = 1;//開始計數

iraddr1=3;//00000011
iraddr2=252;//11111100

do{keyscan(); <br>}while(1);
}

/***********************定時器0中斷處理 **********************/
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE6; //設定時值為38K 也就是每隔26us中斷一次
count++;

if (flag==1)
{
OP=~OP;
}
else
{
OP = 0;
}
ir_in= OP;
}

void SendIRdata(char p_irdata)
{ 2009-8-11
5
紅外數據傳輸
int i;
char irdata=p_irdata;

//發送9ms的起始碼
endcount=223;
flag=1;
count=0;
do{}while(count<endcount);

/**********************發送4.5ms的結果碼***********************/
endcount=117;
flag=0;
count=0;
do{}while(count<endcount);

/********************發送十六位地址的前八位*******************/
irdata=iraddr1;
for(i=0;i<8;i++)
{

/*****先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的低電平)*****/
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);

/***********停止發送紅外信號(即編碼中的高電平)*************/
if(irdata-(irdata/2)*2) //判斷二進制數個位為1還是0
{
endcount=41; //1為寬的高電平
}
else
{
endcount=15; //0為窄的高電平
}
flag=0;
count=0;
do{}while(count<endcount);

irdata=irdata>>1;
}

/**********************發送十六位地址的後八位******************/
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{ 2009-8-11
6
紅外數據傳輸
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);

irdata=irdata>>1;
}

/******************發送八位數據********************************/
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);

irdata=irdata>>1;
}

/***********************發送八位數據的反碼**********************/
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);

irdata=irdata>>1;
}
2009-8-11
7
紅外數據傳輸
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
flag=0;
}

void delay(unsigned int z)
{
unsigned char x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

/*********************4×4鍵盤掃描按下按鍵發射數據************************/
void keyscan()
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
P2=table[num-1];
SendIRdata(table[num-1]);
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8; 2009-8-11
8
紅外數據傳輸
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
P2=table[num-1];
SendIRdata(table[num-1]);
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
P2=table[num-1];
SendIRdata(table[num-1]);
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
break;
case 0x77:num=16;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
} 2009-8-11
9
紅外數據傳輸
P2=table[num-1];
SendIRdata(table[num-1]);
}
}
(2)接收程序
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int

uchar dis_num,num,num1,num2,num3;
sbit led=P1^0;

unsigned char code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e}; //共陽數碼管 0~~f

sbit prem =P3^2; //定義遙控頭的接收腳

uchar ram[4]={0,0,0,0};//存放接受到的4個數據 地址碼16位+按鍵碼8位+按鍵碼取反的8位

void delaytime(uint time) //延遲90uS
{
uchar a,b;
for(a=time;a>0;a--)
{
for(b=40;b>0;b--);
}
}

void rem()interrupt 0 //中斷函數
{
uchar ramc=0; //定義接收了4個位元組的變數
uchar count=0; //定義現在接收第幾位變數
uint i=0; //此處變數用來在下面配合連續監測9MS 內是否有高電平
prem=1;

for(i=0;i<1100;i++) //以下FOR語句執行時間為8MS左右
{
if(prem) //進入遙控接收程序首先進入引導碼的前半部判斷,即:是否有9MS左右的低電平
return; //引導碼錯誤則退出
}

while(prem!=1); //等待引導碼的後半部 4.5 MS 高電平開始的到來。
delaytime(50); //延時大於4.5MS時間,跨過引導碼的後半部分,來到真正遙控數據32位中
//第一位數據的0.56MS開始脈沖

for(ramc=0;ramc<4;ramc++)//循環4次接收4個位元組
{ for(count=0;count<8;count++) //循環8次接收8位(一個位元組)
{
while(prem!=1); //開始判斷現在接收到的數據是0或者1 ,首先在這行本句話時,
//保已經進入數據的0.56MS 低電平階段
//等待本次接受數據的高電平的到來。
delaytime(9);//高電平到來後,數據0 高電平最多延續0.56MS,而數據1,高電平可 2009-8-11
10
紅外數據傳輸
//延續1.66MS大於0.8MS 後我們可以再判斷遙控接收腳的電平,
if(prem) //如果這時高電平仍然在繼續那麼接收到的數據是1的編碼
{
ram[ramc]=(ram[ramc]<<1)+1;//將目前接收到的數據位1放到對應的位元組中
delaytime(11); //如果本次接受到的數據是1,那麼要繼續延遲1MS,這樣才能跨入
//下個位編碼的低電平中(即是開始的0.56MS中)
}
else //否則目前接收到的是數據0的編碼
ram[ramc]=ram[ramc]<<1; //將目前接收到的數據位0放到對應的位元組中
} //本次接收結束,進行下次位接收,此接收動作進行32次,正好完成4個位元組的接收
}

if(ram[2]!=(~(ram[3]&0x7f))) //本次接收碼的判斷
{
for(i=0;i<4;i++) //沒有此對應關系則表明接收失敗,清除接受到的數據
ram[i]=0;
return ;
}

dis_num=ram[2]; //將接收到的按鍵數據賦給顯示變數
}

main()
{
IT0=1; //設定INT0為邊沿觸發
EX0=1; //打開外部中斷0
EA=1; //全局中斷開關打開
while(1)
{
switch(dis_num)
{
case 0x81: num=0; break;
case 0xcf: num=1; break;
case 0x92: num=2; break;
case 0x86: num=3; break;
case 0xcc: num=4; break;
case 0xa4: num=5; break;
case 0xa0: num=6; break;
case 0x8f: num=7; break;
case 0x80: num=8; break;
case 0x84: num=9; break;
case 0x88: num=10;break;
case 0xe0: num=11;break;
case 0xb1: num=12;break;
case 0xc2: num=13;break;
case 0xb0: num=14;break;
case 0xb8: num=15;break;
}
P2=table[num];
P1=0x01;
delaytime(5);
}
}

4. 紅外線遙控器解碼C語言程序代碼 SM0038接受頭

//////////////////////////////////////
//晶振頻率為6MHz 一個機器周期2us //
//實現按鍵地址碼、指令碼的數碼管顯示//
//2010-06-01 //
//////////////////////////////////////
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit la=P2^6;
sbit wela=P2^7;
bit overflag,dataover;//開始接收數據,數據處理完畢

uchar timedata;//定時器0溢出次數
uchar chubus[33];//33Byte數據 timedata組成的數組
uchar jieguos[4];//地址碼,地址反碼,數據碼,數據反碼;

void initial()//初始化
{
IT0=1;EX0=1;//負邊沿觸發

TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定時器
TH0=0xff;TL0=0x06;//0.5ms溢出

EA=1; //開總中斷
}

void time0() interrupt 1//定時器0中斷
{TH0=0xff;TL0=0x06;
timedata++;
}

void ex0() interrupt 0//外部中斷0,接收數據
{
static bit startflag;//開始接收
static uchar i;

if(startflag)
{
if(timedata<32&&timedata>=16) i=0;
chubus[i]=timedata;
timedata=0;
i++;
if(i==33){overflag=1;i=0;}

}
else
{
startflag=1;
timedata=0;
}
}

void chulidata()
{
uchar chubu;//初步數據
uchar jieguo;//結果數據
uchar x,y,z=1;
for(x=0;x<4;x++)//處理四組數據
{
for(y=1;y<=8;y++)//處理一組數據8Byte
{
chubu=chubus[z];
jieguo=jieguo>>1;
if(chubu>3) jieguo=jieguo|0x80;//大於1.5mS為1
z++;
}
jieguos[x]=jieguo;
jieguo=0;
}
dataover=1;

}

void delay(uint z)
{
uint x ,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void display()
{
uchar gao,gao1;
uchar di,di1;

uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
gao1=table[jieguos[0]/16];
di1=table[jieguos[0]%16];
gao=table[jieguos[2]/16];
di=table[jieguos[2]%16];

la=1;
P0=gao1;
la=0;
P0=0xff;
wela=1;
P0=0x7e;
wela=0;
delay(2);

la=1;
P0=di1;
la=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(2);//地址碼

la=1;
P0=gao;
la=0;
P0=0xff;
wela=1;
P0=0x77;
wela=0;
delay(2);

la=1;
P0=di;
la=0;
P0=0xff;
wela=1;
P0=0x6f;
wela=0;
delay(2);//指令碼

}

void main()
{
initial();//初始化
while(1)
{

if(overflag)//數據接收完畢
{
chulidata();//處理數據,完成標志dataover
overflag=0;
}
if(dataover)
{
display();//數碼管顯示
}
}
}

5. 基於51單片機紅外遙控代碼(C語言)

以下文件是51單片機實現遙控解碼,通過數碼管顯示鍵碼的程序,P0口驅動數碼管段選,p2.6和p2.7為數碼管位選,接收頭連到P3.2口。此程序以通過驗證,可以直接編譯使用,另外還有一個繼電器和蜂鳴器的控制,不用可以屏蔽掉。

;********************************************************************************
;* 描述: *
;* 遙控鍵值讀取器 *
;* 數碼管顯示, P0口為數碼管的數據口 *
;* *
;********************************************************************************
;遙控鍵值解碼-數碼管顯示 *
;********************************************************************************/

#include <reg51.h>
#include <intrins.h>

void IR_SHOW();
void delay(unsigned char x);//x*0.14MS
void delay1(unsigned char ms);
void beep();

sbit IRIN = P3^2;
sbit BEEP = P3^7;
sbit RELAY= P1^3;
sbit GEWEI= P2^7;
sbit SHIWEI= P2^6;

unsigned char IRCOM[8];
unsigned char code table[16] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
main()
{
IE = 0x81; //允許總中斷中斷,使能 INT0 外部中斷
TCON = 0x1; //觸發方式為脈沖負邊沿觸發
delay(1);

IRIN=1;
BEEP=1;
RELAY=1;
for(;;)
{
IR_SHOW();
}

} //end main

void IR_IN() interrupt 0 using 0
{
unsigned char i,j,k,N=0;
EA = 0;
I1:
for (i=0;i<4;i++)
{
if (IRIN==0) break;
if (i==3) {EA =1;return;}
}
delay(20);
if (IRIN==1) goto I1; //確認IR信號出現
while (!IRIN) //等 IR 變為高電平
{delay(1);}

for (j=0;j<4;j++)
{
for (k=0;k<8;k++)
{
while (IRIN) //等 IR 變為低電平
{delay(1);}
while (!IRIN) //等 IR 變為高電平
{delay(1);}
while (IRIN) //計算IR高電平時長
{
delay(1);
N++;
if (N>=30) {EA=1;return;}
}
IRCOM[j]=IRCOM[j] >> 1;
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}
N=0;
}//end for k
}//end for j

if (IRCOM[2]!=~IRCOM[3]) {EA=1;return;}
IRCOM[5]=IRCOM[2] & 0x0F;
IRCOM[6]=IRCOM[2] & 0xF0;
IRCOM[6]=IRCOM[6] >> 4;
beep();
EA = 1;

}

void IR_SHOW()
{
P0 = table[IRCOM[5]];
GEWEI = 0;
SHIWEI = 1;
delay1(4);
P0 = table[IRCOM[6]];
SHIWEI = 0;
GEWEI = 1;
delay1(4);
}

void beep()
{
unsigned char i;
for (i=0;i<100;i++)
{
delay(5);
BEEP=!BEEP;
}
BEEP=1;
}

void delay(unsigned char x)//x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}

void delay1(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i<120; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}

6. 51單片機的紅外解碼程序

實際上如果ir_code[2]是8位二進制數的話 ir_code[2]/16,結果就只剩低4 位有效了
再進行&0x0f;還是取低4位沒意義了 如 0XA8/16=0X0A 0X0A &0x0f=0X0A
ir_code[2]&0x0f有意義 是 將高4位清0隻取低4位
估計你的表格里只有16個七段碼 因此查表時只能對高4位和低4位(都不大於15)分別處理和顯示
/16和數學的除法相似,不過只取整數部分,不理會余數 如 15/16=0 17/16=1 18/16=1
32/16=2 35/16=2
0x0f化成二進制是 0000 1111 另一個二進制數xxxx xxxx和它相「與」 則高4位全為0
低4位不變,即(xxxx xxxx)&(0000 1111 )=0000 xxxx
另外,/2相當於把這個二進制數向右移1 位(高位補0)
/4相當於把這個二進制數向右移2 位
/16相當於把這個二進制數向右移4 位,原來的高4位就跑到了現在的低4 位上,現在高4 位就全成了0
所以C 語言中常見>>4 >>8 和/16 /256是等價的

7. 誰有msp430紅外遙控解碼程序 C語言,最好有詳細講解。。謝了

我只有51單片機的,給你參考下吧,只需稍作修改(定時器時間設定)就可以的:

//注意,雖然紅外編碼只有32位,但卻有33個編碼脈沖,需好好理解
#include<at89x52.h>
unsigned char irtime;
unsigned char count;
unsigned char receivedat[32];
unsigned char decodeddat;
unsigned char receiveok;
unsigned char decodingok;
//定時器初始化
void timer0init()
{
TMOD=0x02;//自動重裝的方式
TH0=6;
TL0=6;//初始化為6,定時器每次溢出的間隔為0.25ms
ET0=1;
TR0=1;
}
//外部中斷初始化
void ext0init()
{
IT0=1;//下降沿觸發
EX0=1;
EA=1;
}
//定時器中斷服務程序
void timer0() interrupt 1 using 1
{
irtime++;
}
//外部中斷服務程序
void ext0() interrupt 0 using 0
{
if(irtime>=20)//這是4.5ms+0.56ms一段
{
count=0;
irtime=0;
}
else
{
receivedat[count]=irtime;//將紅外遙控的32位編碼存儲起來
irtime=0;
count++;
if(count==32)//有32位以後就可以解碼了
receiveok=1;//置位接收完成標志位
}
}
//紅外解碼函數
void decoding()
{
unsigned char i;
unsigned char temp;
temp=0x00;
for(i=0;i<8;i++)
{
if(receivedat[i+16]>=7 && receivedat[i+16]<=11)//只提取8位數據碼
temp=temp|0x80;
if(i<7)
temp=temp>>1;//必須移位,因為發送時是低位在前高位在後
}
decodeddat=temp;
decodingok=1;//置位解碼完成標志位
}
//主函數
void main()
{
P3_2=1;
P2=0x00;
P0=0xbf;//數碼管顯示一橫
irtime=0;
receiveok=0;
decodingok=0;
//初始化定時器中斷和外部中斷。
timer0init();
ext0init();
//主循環
while(1)
{
if(receiveok==1)//如果接收完畢
{
decoding();
receiveok=0;
}
if(decodingok==1)//如果解碼完畢
{
switch(decodeddat)
{
case 0:P0=0xf9;P1=0xfe;break;//1 顯示相應的按鍵值
case 1:P0=0xa4;P1=0xfd;break;//2
case 2:P0=0xb0;P1=0xfb;break;//3
case 3:P0=0x99;P1=0xf7;break;//4
case 4:P0=0x92;P1=0xef;break;//5
case 5:P0=0x82;P1=0xdf;break;//6
case 6:P0=0xf8;P1=0xbf;break;//7
case 7:P0=0x80;P1=0x7f;break;//8
case 8:P0=0x90;P1=0x00;break;//9
}
decodingok=0;
}
}
}

8. 51單片機紅外解碼C程序

單片機採用外部中斷P3.3管腳和紅外接收頭的信號線相連,中斷方式為邊沿觸發方式。並用定時器0計算中斷的間隔時間,來區分前導碼、二進制的「1」、「0」碼。並將8位操作碼提取出來在數碼管上顯示。
// 解碼值在Im[2]中,當IrOK=1時解碼有效。 
/* 51單片機紅外遙控解碼程序 */
//用遙控器對准紅外接收頭,按下遙控器按鍵,在數碼管前兩位上就會顯示對應按鍵的編碼
#include <reg52.h>
#define uchar unsigned char 
sbit la=P2^6;
sbit wela=P2^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar f;
#define Imax 14000    //此處為晶振為11.0592時的取值, 
#define Imin 8000    //如用其它頻率的晶振時,
#define Inum1 1450    //要改變相應的取值。
#define Inum2 700 
#define Inum3 3000
unsigned char Im[4]={0x00,0x00,0x00,0x00};
uchar show[2]={0,0};
unsigned long m,Tc;
unsigned char IrOK;
void delay(uchar i)
{
  uchar j,k; 
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}
void display()
{
   la=0;
   P0=table[show[0]];
   la=1;
   la=0;
   wela=0;
   P0=0xfe;
   wela=1;
   wela=0;
   delay(5);
   P0=table[show[1]];
   la=1;
   la=0;
   P0=0xfd;
   wela=1;
   wela=0;
   delay(5);
} //外部中斷解碼程序
void intersvr1(void) interrupt 2 using 1
{
 Tc=TH0*256+TL0;                                               //提取中斷時間間隔時長
 TH0=0; 
    TL0=0;              //定時中斷重新置零
 if((Tc>Imin)&&(Tc<Imax))
      { 
  m=0;
        f=1;
  return;
      }       //找到啟始碼
   if(f==1)
      {
        if(Tc>Inum1&&Tc<Inum3) 
    {
   Im[m/8]=Im[m/8]>>1|0x80; m++; 
       }
      if(Tc>Inum2&&Tc<Inum1) 
        {
         Im[m/8]=Im[m/8]>>1; m++; //取碼
  }
  if(m==32) 
   {
         m=0;  
         f=0;
         if(Im[2]==~Im[3]) 
      {
           IrOK=1; 
   }
        else IrOK=0;   //取碼完成後判斷讀碼是否正確
     }
               //准備讀下一碼
   }
}
/*演示主程序*/
void main(void)
{
    unsigned int  a;
 m=0;
    f=0;
 EA=1;
 IT1=1;EX1=1;
 TMOD=0x11;  
 TH0=0;TL0=0;
 TR0=1;//ET0=1;
 while(1)
 {
       if(IrOK==1) 
  {
      show[1]=Im[2] & 0x0F;     //取鍵碼的低四位
           show[0]=Im[2] >> 4;  
           IrOK=0;
  }
           for(a=100;a>0;a--)
          {
    display();
   }
 }
}
解碼程序這個就能實現

9. 急求紅外線解碼編程(C語言)有電路圖,求大神指點!!

//////////////////////////////////////
//晶振頻率為6MHz 一個機器周期2us //
//實現按鍵地址碼、指令碼的數碼管顯示//
//2010-06-01 //
//////////////////////////////////////
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit la=P2^6;
sbit wela=P2^7;
bit overflag,dataover;//開始接收數據,數據處理完畢

uchar timedata;//定時器0溢出次數
uchar chubus[33];//33Byte數據 timedata組成的數組
uchar jieguos[4];//地址碼,地址反碼,數據碼,數據反碼;

void initial()//初始化
{
IT0=1;EX0=1;//負邊沿觸發

TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定時器
TH0=0xff;TL0=0x06;//0.5ms溢出

EA=1; //開總中斷
}

void time0() interrupt 1//定時器0中斷
{TH0=0xff;TL0=0x06;
timedata++;
}

void ex0() interrupt 0//外部中斷0,接收數據
{
static bit startflag;//開始接收
static uchar i;

if(startflag)
{
if(timedata<32&&timedata>=16) i=0;
chubus[i]=timedata;
timedata=0;
i++;
if(i==33){overflag=1;i=0;}

}
else
{
startflag=1;
timedata=0;
}
}

void chulidata()
{
uchar chubu;//初步數據
uchar jieguo;//結果數據
uchar x,y,z=1;
for(x=0;x<4;x++)//處理四組數據
{
for(y=1;y<=8;y++)//處理一組數據8Byte
{
chubu=chubus[z];
jieguo=jieguo>>1;
if(chubu>3) jieguo=jieguo|0x80;//大於1.5mS為1
z++;
}
jieguos[x]=jieguo;
jieguo=0;
}
dataover=1;

}

void delay(uint z)
{
uint x ,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void display()
{
uchar gao,gao1;
uchar di,di1;

uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
gao1=table[jieguos[0]/16];
di1=table[jieguos[0]%16];
gao=table[jieguos[2]/16];
di=table[jieguos[2]%16];

la=1;
P0=gao1;
la=0;
P0=0xff;
wela=1;
P0=0x7e;
wela=0;
delay(2);

la=1;
P0=di1;
la=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(2);//地址碼

la=1;
P0=gao;
la=0;
P0=0xff;
wela=1;
P0=0x77;
wela=0;
delay(2);

la=1;
P0=di;
la=0;
P0=0xff;
wela=1;
P0=0x6f;
wela=0;
delay(2);//指令碼

}

void main()
{
initial();//初始化
while(1)
{

if(overflag)//數據接收完畢
{
chulidata();//處理數據,完成標志dataover
overflag=0;
}
if(dataover)
{
display();//數碼管顯示
}
}
}