单片机红外发射原理与设计程序.docx
《单片机红外发射原理与设计程序.docx》由会员分享,可在线阅读,更多相关《单片机红外发射原理与设计程序.docx(14页珍藏版)》请在冰豆网上搜索。
单片机红外发射原理与设计程序
用AT89S51单片机制作红外电视遥控器
一般红外电视遥控器的输出都是用编码后串行数据对38~40kHz的方波进行脉冲幅度调制而产生的。
当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。
这种遥控码具有以下特征:
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”。
上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制,然后再通过红外发射二极管产生红外线向空间发射。
一般电视遥控器的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
后16位为8位的操作码和8位的操作反码,用于核对数据是否接收准确。
根据红外编码的格式,发送数据前需要先发送9ms的起始码和4.5ms的结果码。
遥控串行数据编码波形如下图所示:
接收方一般使用TL0038一体化红外线接收器进行接收解码,当TL0038接收到38kHz红外信号时,输出端输出低电平,否则为高电平。
所以红外遥控器发送红外信号时,参考上面遥控串行数据编码波形图,在低电平处发送38kHz红外信号,高电平处则不发送红外信号。
单片机红外电视遥控器电路图如下:
C51程序代码:
#include
staticbitOP; //红外发射管的亮灭
staticunsignedintcount; //延时计数器
staticunsignedintendcount;//终止延时计数
staticunsignedcharflag; //红外发送标志
chariraddr1; //十六位地址的第一个字节
chariraddr2; //十六位地址的第二个字节
voidSendIRdata(charp_irdata);
voiddelay();
voidmain(void)
{
count=0;
flag=0;
OP=0;
P3_4=0;
EA=1;//允许CPU中断
TMOD=0x11;//设定时器0和1为16位模式1
ET0=1;//定时器0中断允许
TH0=0xFF;
TL0=0xE6;//设定时值0为38K也就是每隔26us中断一次
TR0=1;//开始计数
iraddr1=3;
iraddr2=252;
do{
delay();
SendIRdata(12);
}while
(1);
}
//定时器0中断处理
voidtimeint(void)interrupt1
{
TH0=0xFF;
TL0=0xE6;//设定时值为38K也就是每隔26us中断一次
count++;
if(flag==1)
{
OP=~OP;
}
else
{
OP=0;
}
P3_4=OP;
}
voidSendIRdata(charp_irdata)
{
inti;
charirdata=p_irdata;
//发送9ms的起始码
endcount=223;
flag=1;
count=0;
do{}while(count //发送4.5ms的结果码
endcount=117
flag=0;
count=0;
do{}while(count //发送十六位地址的前八位
irdata=iraddr1;
for(i=0;i<8;i++)
{
//先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
endcount=10;
flag=1;
count=0;
do{}while(count//停止发送红外信号(即编码中的高电平)
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=41; //1为宽的高电平
}
else
{
endcount=15; //0为窄的高电平
}
flag=0;
count=0;
do{}while(count irdata=irdata>>1;
}
//发送十六位地址的后八位
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count irdata=irdata>>1;
}
//发送八位数据
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count irdata=irdata>>1;
}
//发送八位数据的反码
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count irdata=irdata>>1;
}
endcount=10;
flag=1;
count=0;
do{}while(count flag=0;
}
voiddelay()
{
inti,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
制作的实物如下图所示:
步进电机
#include
#defineuintunsignedint
#defineucharunsignedchar
#definems*77
//f=12M
#defineLEDLen4
#defineDj_star(){IE=0x81;pri_dj=0;}
#defineDj_stop(){IE=0x00;pri_dj=1;P1=0xff;shache="0";delay(800ms);delay(800ms);delay(400ms);shache=1;}
#defineChilun_Num8
/*齿轮数8个*/
#defineset_display_num(){LEDBuf[0]=tmp/1000;LEDBuf[1]=tmp/100%10;\
LEDBuf[2]=tmp/10%10;LEDBuf[3]=tmp%10;}
ucharLEDBuf[LEDLen]={0,0,0,0};
voidread_num();/*读播码盘到set_round_num*8*/
voiddisplay();
voiddelay(uintdelay_time){uinti;for(i=0;ivoidrun();
voidfx_run();
uintround_num=0;/*记录已转的齿轮数,中断1次加1*/
uintset_round_num=0;/*播码盘设置圈数*/
uintset_pwm_width=0;/*播码盘设置步进电机正向速度*/
bitone_round_flg=0;
sbitled_1000=P0^7;//usefordisplay
sbitled_100=P0^6;//usefordisplay
sbitled_10=P0^5;//usefordisplay
sbitled_1=P0^4;//usefordisplay
sbitkey_start=P3^0;
sbitkey_puse=P3^0;
sbitkey_clear=P3^1;
/*P3^2接齿轮传感器中断*/
sbitbujin_zx_stop=P3^3;/*接步进电机,正向到位传感器,为0停机*/
sbitbujin_fx_stop=P3^4;/*接步进电机,反向到位传感器,为0停机*/
sbitshache=P3^5;/*接刹车控制继电器0电位有效*/
sbitpri_dj=P3^6;/*接主电机控制继电器0电位有效*/
voidmain(){
TCON=0x01;
display();
while
(1){
IE="0x00";
round_num=0;
display();
if(bujin_fx_stop)fx_run();
while(key_start);
delay(8ms);
if(!
key_start){
read_num();
//set_round_num=8;
while(!
key_start);
run();
fx_run();
}
}
}
voidrun(){
#defineDelay_time180
/*转一圈50次循环,每循环4步,50*4=200,200*1。
8=360*/
uchari;
P1=0xff;
set_pwm_width=15+set_pwm_width/10;
while
(1){
while(!
shache|!
key_start);
Dj_star();
for(i="0";bujin_zx_stop&!
pri_dj;i++){
P1=0xf9;
delay(Delay_time);//bujin_zx_stop=P3^3;
P1=0xfc;//bujin_fx_stop=P3^4;
delay(Delay_time);//key_puse=P3^0;
P1=0xf6;//key_clear=P3^1;
delay(Delay_time);//shache=P3^5;
P1=0xf3;//pri_dj=P3^6;
delay(Delay_time);
if(i==set_pwm_width){P1=0xff;i=0;one_round_flg=0;while(!
one_round_flg&key_puse);}
if(!
key_puse){delay(4ms);if(!
key_puse)break;}
}
P1=0xff;
if(pri_dj)break;
if(!
key_puse){
delay(8ms);
if(!
key_puse){
Dj_stop();
while(!
key_puse);
//nextpreekey
while(!
shache);
while
(1){
while(key_puse&key_clear);
delay(8ms);
if(!
key_clear){round_num=0;display();}
if(!
key_puse)break;
}
while(!
key_puse);
delay(8ms);
while(!
key_puse);
}
}
}
}
voidext_int0(void)interrupt0{/*主电机齿轮中断*/
uinttmp;
EA=0;
if(!
pri_dj){
round_num++;
if(round_num%Chilun_Num==0){
one_round_flg=1;
tmp=round_num/Chilun_Num;
set_display_num();
P0=0xf0;
P0=P0|LEDBuf[0];
led_1000=0;
P0|=0xf0;
P0=0xf0;
P0=P0|LEDBuf[1];
led_100=0;
P0|=0xf0;
P0=0xf0;
P0=P0|LEDBuf[2];
led_10=0;
P0|=0xf0;
P0=0xf0;
P0=P0|LEDBuf[3];
led_1=0;
P0|=0xf0;
P0=0xf0;
}
if(round_num>=set_round_num)Dj_stop();
}
EA=0x81;
}
voiddisplay(){
uchari;
uinttmp=0;
tmp=round_num/Chilun_Num;
set_display_num();
for(i=0;iP0=0xf0;
P0=P0|LEDBuf[i];
if(i==0)led_1000=0;//P0^4
if(i==1)led_100=0;//P0^5
if(i==2)led_10=0;//P0^6
if(i==3)led_1=0;//P0^7
P0|=0xf0;
}
P0=0xf0;
}
voidread_num(){
/*读播码盘到set_round_num,set_pwm_width*/
uchartmp;
P2=0xFF;
P2=0xEF;//11101111
delay(1ms);
tmp=~(P2|0xF0);
P2=0xDF;//11011111
delay(1ms);
tmp=(~(P2|0xF0))*10+tmp;
set_round_num=tmp;
P2=0xBF;//10111111
delay(1ms);
tmp=(~(P2|0xF0));
P2=0x7F;//01111111
delay(1ms);
tmp=(~(P2|0xF0))*10+tmp;
set_round_num=set_round_num+tmp*100;
set_round_num=set_round_num*Chilun_Num;
P2=0xFF;
P1=0xbF;//01111111
delay(1ms);
tmp=~(P2|0xF0);
P1=0xFF;
P2=0xFF;
P1&=0x7F;//10111111
delay(1ms);
tmp=(~(P2|0xF0))*10+tmp;
set_pwm_width=tmp;
P1=0xFF;
P2=0xFF;
}
voidfx_run(){
#definef_Delay_time180
while(bujin_fx_stop){/*反向回车直到传感器动作*/
P1=0xf3;//0011
delay(f_Delay_time);
P1=0xf6;//0110
delay(f_Delay_time);
P1=0xfc;//1100
delay(f_Delay_time);
P1=0xf9;//1001
delay(f_Delay_time);
}
P1=0xff;
}