Ⅰ 單片機控制紅外程序
給你一個PIC寫的接收紅外遙控器的程序。
//******************************************************
//mcu: PIC16F883
//author:
//data:
//ver: 1.0
//********************************************************
#include <pic.h>
#include <pic16f887.h>
#include "main.h"
// 函數聲明部份
void interrupt IRQ_TEST(void);
void fun_intset(void);
void set_port(void);
void fun_timerset(void);
void delay_10us(void);
void delay_130us(void);
void test_remote(void);
// 主函數
void main()
{
set_port();
fun_timerset();
fun_intset();
delay_10ms();
ram_ini();
GIE=1;
while(1)
{
asm("clrwd");
test_remote();
}
}
//埠I/O定義子程序
void set_port()
{
ANSEL =0X00; //porta io port
ANSELH=0X00; //portb io port
//TRISX BIT=1, PORTX AS INPUT
TRISA = 0x0F; //RA0-RA3 INPUT ,RA4-RA5 OUTPUT
TRISB = 0x07; //RB0 PASS0, RB1-RB2 INPUT ,RB3-RB6 OUTPUT
TRISC = 0x0F;
// TRISC = 0x03; //RC0-RC1 INPUT,RC5-RC6 OUTPUT , RC3 RC4 EEPROM SCL SDA
PORTC=0;
PORTA=0XFF;
// WPUB=0XFF;
PORTB=0X07;
}
//中斷子程序
void interrupt IRQ_TEST(void)
{
if(T0IF) //Timer0中斷服務子程序
{
TMR0=0xce;
T0IF=0;
timer_100us++; //100us
}
if(INTF==1)
{
INTF=0;
timer_rec=timer_100us;
timer_100us=0;
flag_rec_remote=1;
}
}
//定時器0初始化設置子程序
void fun_timerset()
{
//Timer0初始化設置
PSA=0;//Timer0 使用預分頻器
//Timer0選擇分頻率為1:2
PS0=0;PS1=0;PS2=0;
//內部時鍾定時方式,定時時間:200uS,誤差:0uS
T0CS=0;
// TMR0=0x9b;
TMR0=0xce; //100us
}
/*
//定時器2初始化設置子程序
void fun_timer2set()
{
//Timer2初始化設置
//timer2使用預分頻率1:1
T2CKPS0=0;T2CKPS1=0;
//timer2使用後分頻率1:1
TOUTPS0=0;
TOUTPS1=0;
TOUTPS2=0;
TOUTPS3=0;
//定時器2定時時間為:200uS,誤差:0uS
TMR2=0x38;
TMR2ON=1;
}
*/
//中斷允許設置子程序
void fun_intset()
{
T0IE=1;//Tiemr0中斷允許
INTEDG=0; //RB0 FALLAGE INTERRUPT
INTE=1;
INTF=0;
}
void ram_ini(void)
{
}
//------------------------------------------------------------
//*****************************************************************************
void delay_10us(void)
{
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
}
void delay_130us(void)
{
uchar i;
for(i=0;i<13;i++)
{
NOP;
NOP;
NOP;
}
}
void delay_10ms(void)
{
unsigned int i;
for(i=0;i<1000;i++)
{
NOP;
NOP;
NOP;
NOP;
NOP;
}
}
void test_remote(void)
{
uchar rec_ok,i;
if(flag_rec_remote==1)
{
flag_rec_remote=0;
// remote_buf[rec_byte]=timer_rec; //test use
// rec_byte++; //test use
// return; //test use
if(flag_rec_head==0)
{
if(timer_rec>=90&&timer_rec<=140) //135
{
flag_rec_head=1;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
}
else
{
if(timer_rec>=8&&timer_rec<=12) //11.2
{
rec_buf=(rec_buf>>1);
rec_buf=rec_buf&0x7f;
}
else if(timer_rec>=18&&timer_rec<=22) //22
{
rec_buf=(rec_buf>>1);
rec_buf=rec_buf|0x80;
}
else if(timer_rec>=90&&timer_rec<=140)
{
flag_rec_head=1;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
else
{
flag_rec_head=0;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
}
if(flag_rec_head==1)
{
rec_bit++;
if(rec_bit==8)
{
remote_buf[rec_byte]=rec_buf;
rec_byte++;
rec_bit=0;
if(rec_byte==4)
{
NOP;
NOP;
NOP;
NOP;
rec_byte=0;
rec_bit=0;
rec_buf=0;
flag_rec_head=0;
}
}
}
}
}
Ⅱ 求一個單片機紅外遙控器控制設計的源程序
程序太長,須仔細研究。
#definemain_GLOBALS
#include<reg51.h>
#include"main.h"
#include"SAA3010.h"
unsignedcharcounter;
unsignedchartemp;
sbitP2_0=0xA0;
sbitP2_1=0xA1;
sbitP2_2=0xA2;
sbitP2_3=0xA3;
voiddecode_init(void)
{
load_code_detected=0;
repeat_code_detected=0;
decode_error=0;
temp1=0;
temp2=0;
temp3=0;
temp4=0;
TH1=0;
TL1=0;
TR1=0;
}
voidmain(void)
{
EX0=1;
IT0=1;
TMOD=0x11;
ET0=1;
TH0=128;
TL0=0;
TR0=1;
P0=0;
TH1=0;
TL1=0;
decode_init();
EA=1;
counter=0;
data_available=0;
while(1)
{
if(data_available==1)
{
if(key_code==01)//display"1"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0xf9;
}
if(key_code==0x02)//display"2"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0xa4;
}
if(key_code==0x03)//display"3"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0xb0;
}
if(key_code==0x04)//display"4"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0x99;
}
if(key_code==0x05)//display"5"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0x92;
}
if(key_code==0x06)//display"6"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0x82;
}
if(key_code==0x07)//display"7"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0xf8;
}
if(key_code==0x08)//display"8"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0x80;
}
if(key_code==0x09)//display"9"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0x90;
}
if(key_code==0x00)//display"0"
{
P2_0=0;//選中四個數碼管
P2_1=0;
P2_2=0;
P2_3=0;
P0=0xc0;
}
data_available=0;
}
}
}
//**********************************************************************************************************************
voidkey_isr(void)interrupt0
{
EX0=0;//立即關閉外部中斷,轉為查詢方式解碼
led=0;//開LED表示收到紅外信號
temp=SAA3010_decode();//解碼
if(temp==1)gotokey_isr_exit;
counter=0;
key_isr_exit:
decode_init();
led=1;
EX0=1;
}
voidTimer0_isr(void)interrupt1
{
counter++;
if(counter>3)
{
if(led==0)led=1;
counter=0;
}
ET0=1;
}
#defineSAA3010_GLOBALS
#include<reg51.h>
#include"SAA3010.h"
#include"main.h"
//===========================================================================================================
//該函數的作用是每調用一次就在temp1-4組成的32bit長度的最低位上移入
//一個0或者1,數據由bitdata確定
voidSAA3010_cycle_data(unsignedcharbitdata)
{
temp4=temp4<<1;
if((temp3&0x80)==1)temp4=temp4|0x01;
elsetemp4=temp4&0xfe;
temp3=temp3<<1;
if((temp2&0x80)==1)temp3=temp3|0x01;
elsetemp3=temp3&0xfe;
temp2=temp2<<1;
if((temp1&0x80)==1)temp2=temp2|0x01;
elsetemp2=temp2&0xfe;
temp1=temp1<<1;
if(bitdata==1)temp1=temp1|0x01;
elsetemp1=temp1&0xfe;
}
//===========================================================================================================
//解碼出錯返回1,對則返回0
unsignedcharSAA3010_decode(void)
{
//-----------------------------------------------------------------------------------------------------------
unsignedcharcount=0;
TR1=1;//啟動計時
while(1)
{
while(ir_receive==0);//等待電平變高,不需要超時監測
TR1=0;//高電平(對發射電路而言)測試結束
high_level_time=TH1*256+TL1;//記錄高電平的數據
//-----------------------------------------------------------------------------------------------------------
TH1=0; TL1=0;TR1=1;//啟動對低電平的測試
//-----------------------------------------------------------------------------------------------------------
//處理低電平
if((high_level_time<750)||(high_level_time>1800))return1;//不是合格的電平
if((high_level_time>750)&&(high_level_time<1000)){SAA3010_cycle_data(0);count+=1;}//移入一個0
if((high_level_time>1500)&&(high_level_time<1800)){SAA3010_cycle_data(0);SAA3010_cycle_data(0);count+=2;}//移入兩個0
while(ir_receive==1)//等待電平變低
{
if(TH1>0x08)break;//高電平超時,正常情況下是測試結束,異常時則是出錯
}
TR1=0;//低電平(對發射電路而言)測試結束
if(TH1>0x08){break;}
low_level_time=TH1*256+TL1;//保存低電平的數據
TH1=0; TL1=0; TR1=1; //為增加計時的准確性,數據的處理都是在計時過程里
//-----------------------------------------------------------------------------------------------------------
//處理高電平
if((low_level_time<750)||(low_level_time>1800))return1;//不是合格的電平
if((low_level_time>750)&&(low_level_time<1000)){SAA3010_cycle_data(1);count+=1;}//移入一個0
if((low_level_time>1500)&&(low_level_time<1800)){SAA3010_cycle_data(1);SAA3010_cycle_data(1);count+=2;}//移入兩個0
}
if(count==26){SAA3010_cycle_data(1);count++;}
if(count!=27)return1;
led=0;
//提取按健信息
key_code=0;
if((temp1>>1)&0x01)key_code=key_code|0x01;
elsekey_code=key_code&0xfe;
if((temp1>>3)&0x01)key_code=key_code|0x02;
elsekey_code=key_code&0xfd;
if((temp1>>5)&0x01)key_code=key_code|0x04;
elsekey_code=key_code&0xfb;
if((temp1>>7)&0x01)key_code=key_code|0x08;
elsekey_code=key_code&0xf7;
if((temp2>>1)&0x01)key_code=key_code|0x10;
elsekey_code=key_code&0xef;
if((temp2>>3)&0x01)key_code=key_code|0x20;
elsekey_code=key_code&0xdf;
//提取系統信息
sys_code=0;
if((temp2>>5)&0x01)sys_code=sys_code|0x01;
elsesys_code=sys_code&0xfe;
if((temp2>>7)&0x01)sys_code=sys_code|0x02;
elsesys_code=sys_code&0xfd;
if((temp3>>1)&0x01)sys_code=sys_code|0x04;
elsesys_code=sys_code&0xfb;
if((temp3>>3)&0x01)sys_code=sys_code|0x08;
elsesys_code=sys_code&0xf7;
if((temp3>>5)&0x01)sys_code=sys_code|0x10;
elsesys_code=sys_code&0xef;
if((temp3>>7)&0x01)sys_code=sys_code|0x20;
elsesys_code=sys_code&0xdf;
data_available=1;
return0;
}
//===========================================================================================================
Ⅲ 紅外線遙控 單片機
這個程序我之前寫過一個,解碼用單片機接收NEC遙控器32編碼和電視遙控器42位編碼,程序裡面自動識別32和42位的編碼用數碼管進行顯示對應的數值,我還寫過紅外發射,模擬NEC協議發射紅外編碼和電視機、奧克斯空調、衛星接收機都能控制,需要的可以網路私信!
Ⅳ 單片機如何實現紅外遙控
以下文件是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_();
}
}
}
Ⅳ 51單片機紅外遙控程序是什麼
#include
Ⅵ 51單片機紅外線遙控LED程序,疑惑中!!!!!
紅外收發中,IRDATA[2]與IRDATA[3]是取反的關系。也就是說兩個數對應各位前者為1後者就為0
其餘的問題,都是根據紅外接收時序來編的程序,以下總結以下紅外收發時序供參考,你讀懂就可以理解了。
採用脈寬調制的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進制的"0";;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進制的"1「上述"0"和"1"組成的32位二進制碼經38kHz的載頻進行二次調制以提高發射效率,達到降低電源功耗的目的。然後再通過紅外發射二極體產生紅外線向空間發射遙控編碼是連續的32位二進制碼組,其中前16位為用戶識別碼,能區別不同的電器設備,防止不同機種遙控碼互相干擾。該晶元的用戶識別碼固定為十六進制01H後16位為8位操作碼(功能碼)及其反碼。
發射代碼由一個起始碼(9ms),一個結果碼(4.5ms),低8位地址碼(9ms~18ms),高8位地址碼(9ms~18ms),8位數據碼(9ms~18ms)和這8位數據的反碼(9ms~18ms)組成。
解碼的關鍵是如何識別"0"和"1",接收端而言,"0"是0.56ms的高+0.56ms的低。"1"是1.68ms的高+0.56ms的低。所以可以根據高電平的寬度區別"0"和"1"。當高電平出現時開始延時,0.56ms以後,若讀到的電平為低,說明該位為"0",反之則為"1",為了可靠起見,延時必須比0.56ms長些,但又不能超過1.12ms,否則如果該位為"0",讀到的已是下一位的高電平,因此取(1.12ms+0.56ms)/2=0.84ms最為可靠,一般取0.84ms左右均可。為了共用引導部分延時程序,一般用0.9ms延時。
由此可見,有效數據是4位元組(32位)。前兩個位元組可定義用戶編碼,後兩個位元組分別是真正的數據及其反碼。
Ⅶ 求51單片機紅外遙控程序
sbitIR_OUT=P3^2;
unsignedcharSigInfo[4];//存儲紅外按鍵編碼,SigInfo[2]為按鍵值
voidCmd_Require(void);
voidINT_Ext0()interrupt1//外部中斷0
{
u8i,j;
u16time=8000;
EA=0;
for(i=0;i<10;i++){
delay0_7ms();
if(IR_OUT){
EA=1;
return;
}
}
while(!IR_OUT);
delay2_5ms();
if(!IR_OUT){
EA=1;
return;
}
while(IR_OUT&&time){
time--;
}
time=8000;
for(i=0;i<4;i++){
for(j=0;j<8;j++){
SigInfo[i]>>=1;
while(!IR_OUT);
delay0_7ms();
if(IR_OUT){
SigInfo[i]|=0x80;
while(IR_OUT&&time){
time--;
}
time=8000;
}
}
}
Cmd_Require();
EA=1;
}
voidCmd_Require(void)
{
switch(SigInfo[2]){
case0x0c:
//此處代碼隨意
break;
case0x18:
//...
break;
//...
default:
break;
}
}
延時沒寫,因單片機而異的,要精確點才能解碼。
Ⅷ 單片機編程(紅外線遙控器)
這段程序的意思是將鍵值換算成ASCII碼字元表示;
0x30 表示ASCII碼的『0』,ASCII碼表裡面字元0的編號就是0x30;
0x37 的意思是當鍵值大於9時,鍵值用十六進制字元表示,0x37 實際上是『A』-10,『A』=0x41,『A』- 10 =0x37;比如鍵值是10,那麼輸出就是ASCII字元『A』;