单片机遥控.docx
《单片机遥控.docx》由会员分享,可在线阅读,更多相关《单片机遥控.docx(18页珍藏版)》请在冰豆网上搜索。
![单片机遥控.docx](https://file1.bdocx.com/fileroot1/2023-2/24/689e9f55-a317-470c-afed-a40a46ec350f/689e9f55-a317-470c-afed-a40a46ec350f1.gif)
单片机遥控
单片机红外遥控的设计
——南昌科技大学杜德钦
1.方案论证:
在现实生活中,随着技术的快速发展,自动化的程度越来越高;而在自动控制中,遥控控制成了不可缺少的一个部分,虽然现在有专门的编码遥控发送芯片,但本设计是基于AT89C51单片机的一种简易的遥控控制试验,用一块AT89C51单片机做发送模块用,主要是调制40KHz载波编码利用红外发送管,扫描键盘,通过相应的键值发出相应的脉冲数;用另一块AT89C51做接收处理器,解码并做出相应的处理;在本应用系统中主要以控制灯泡亮度控制为例。
2.系统硬件电路的设计:
单片机遥控应用系统电路分为遥控发送电路和接收电路
(1)遥控发送电路设计
a)详细电路图见后;
b)其中在原理图中:
P0口用着键盘扫描端口,利用矩阵式键盘有16个按键,分别有16个功能;第9脚是单片机复位脚,才用RC电路来实现上电复位;第15脚为红外线遥控码的输出口,用于输出40KHz载波编码,第18,19脚接12MHz晶振。
因为AT89C51单片机P0口内部不具有上拉电阻,所以要接上拉电阻。
c)AT89C51单片机
i.主芯片AT89C51内含8Kbflash存储器,256x8位内部RAM,两个定时器,使用5V电源供电,在发送电路中可以采用LV型,方便电池供电。
d)矩阵式键盘处理
I矩阵式键盘是用I/O口组成行列结构,用扫描方式来读取键码;
在这里是用P0口来扩展的,实现16个键盘。
(2)红外接收电路设计
a)详细电路图见后
b)在电路图中有电源电路,调光控制电路;交流电过电源检测电路;
c)我们把电灯的亮度分为7个档,同时用P1.0——P1.2作为数码管的二进制数据输出,显示数字0——7,采用4511集成硬件译码现实数值,以及P0.0——P0.7和P2.0——P2.6作为十五个电器的电源控制,接口可用继电器和可控硅。
d)本电路中P2.7为控制电灯的可调亮度。
P3.0为50H交流电相位基准输入,第12脚为中断输入口,P3.1用于接收红外遥控编码输入信号。
e)电源和交流电过零检测电路
f)开关及亮度控制电路
3.系统软件设计
1)遥控码的编码格式
遥控码采用脉冲个数编码个数编码,不同的脉冲个数代表不同的码,最小为2个脉冲,最大为17个脉冲;为了接收可靠,第一位脉宽为3ms,其余为1ms,遥控码数据帧间隔大于10ms,其编码图形如图所示:
编码1格式
编码2格式
2)遥控码的发送
当某个键按下时,单片机先读出键值,然后根据键值设定遥控码的个数,再调40khz方波有红外发光管发送出去。
P3.5端口的输出调波如下图所示
调光命令波形码
3)数据帧接收的处理
当红外接收器输出脉冲帧数据时,第一位码的低电平将起动中断程序,实时接收数据,在接收数据帧是,将第一位(起始位)码的脉宽进行验证,若第一位的低电平的脉宽小于3ms将做错误处理,当间隔位的高电平脉宽大于3ms,作为接收到结束信号;,结束接收,再根据脉冲计数器中脉冲的个数来做出相应的处理,下图为红外接收头输出的一帧遥控码波形:
4.遥控发射及接收控制程序设计流程图
1)遥控发送器主程序,键盘扫描程序,遥控码发送程序流程图如下图所示:
2)遥控接收主程序,中断程序流程图如下所示:
5.调试及性能分析
1)调试
在调试过程中一般先进行系统硬件检查后进行软件调试,对遥控器的调试主要是用示波器来观察接收到的遥控编码波形,能否达到要求。
其次调整发射电阻的大小可以改变红外线发送距离,电灯的控制系统中通过对可控制硅的延时时间的调整,电灯按0~7共8个档次来调整亮度。
红外接收头应尽量安装在靠表面,以扩大接收的角度,不同厂家的遥控接收头的接收角度不一致,以选择确定;
2)性能指示
调试后性能指标测试如下:
1.最大遥控距离:
10m;
2.发射接收角:
水平最大900;
3.遥控器发射时工作电流:
20mA;
4.电灯最亮电压:
AC220;
5.电灯最暗电压:
AC10;
当采用红外接收时距离和角度等使用效果都将受到一定的限制;当采用调频或调幅接收时距离会远些,接收不受角度的影响。
本单片机遥控编码及解码方案一般的遥控电器控制系统中!
6.控制源程序
以c语言为例:
1):
发送程序
/*********红外遥控发送AT89C5112MHz晶振***********/
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definekeyP0
sbithwout=P3^5;//红外输出脚
uchartemp1,m,n;
uchartemp=0;
/********1ms延时********/
voiddelay(uintt)
{
uchari,j;
for(i=0;ifor(j=0;j<120;j++);
}
/*********初始化程序*******/
voidinit()
{
IE=0x00;
IP=0x01;
hwout=0;
TMOD=0x020;
TH0=0xf3;
TL0=0xf3;
EA=1;
}
/*********定时器1中断***********/
voidtime1()interrupt4
{
hwout=~hwout;
}
/********发送程序*********/
voidsend(m)
{
TR1=1;//40KHz发3ms
ET1=1;
delay(3);
ET1=0;
TR1=0;
hwout=0;
for(n=0;n{
TR1=1;//40KHZ发1ms
ET1=1;
delay
(1);
ET1=0;
TR1=0;
hwout=0;
}
delay(10);
}
/**********键盘程序*********/
voidkeyscan()
{
key=0xf0;
_nop_();
temp=key;
if(temp!
=0xf0)
{
delay(3);//消抖
if(temp!
=0xf0)//确认是否有键按下
{
temp=key;
key=0x0f;
_nop_();
temp1=key;
temp=(temp&0xf0)|(temp1&0x0f);//获取键码
delay(3);
temp1=0;
while(temp1)//判断是否放开按键
{
key=0xf0;
_nop_();
temp1=key;
temp1^=0xf0;
}
switch(temp)//获取键值
{
case0x77:
m=1;
break;
case0xB7:
m=2;
break;
case0xD7:
m=3;
break;
case0xE7:
m=4;
break;
case0x7B:
m=5;
break;
case0xBB:
m=6;
break;
case0xDB:
m=7;
break;
case0xEB:
m=8;
break;
case0x7D:
m=9;
break;
case0xBD:
m=10;
break;
case0xDD:
m=11;
break;
case0xED:
m=12;
break;
case0x7E:
m=13;
break;
case0xBE:
m=14;
break;
case0xDE:
m=15;
break;
case0xEE:
m=16;
break;
default:
break;
}
send(m);
}
}
}
/**************主程序************/
voidmain()
{
init();
while
(1)
{
keyscan();
}
}
2):
接收程序
/*********红外遥控接收AT89C5112MHz晶振***********/
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definedisoutP1
sbitpowerin=P3^0;
sbithwin=P3^1;
/////对应按键的处理位定义
sbitkey1=P0^0;
sbitkey2=P0^1;
sbitkey3=P0^2;
sbitkey4=P0^3;
sbitkey5=P0^4;
sbitkey6=P0^5;
sbitkey7=P0^6;
sbitkey8=P0^7;
sbitkey9=P2^0;
sbitkey10=P2^1;
sbitkey11=P2^2;
sbitkey12=P2^3;
sbitkey13=P2^4;
sbitkey14=P2^5;
sbitkey15=P2^6;
sbitpwm=P2^7;//灯光pwm控制
/////变量定义
uintkey;//定义一个红外脉冲计数变量
uchark;//定义一个记时变量判断是否为结束信号
uints=1;
/*************1ms延时*********/
voiddelay(uintt)
{
uinti,j;
for(i=0;ifor(j=0;j<120;j++);
}
/********初始化程序**********/
voidinit()
{
EX0=1;
EA=1;
}
/********电灯调光程序*******/
voidtiaoguang()
{
pwm=0;
delay
(1);
pwm=1;
}
/********电灯调光延时程序*******/
voidloop()
{
switch(disout&0x07)
{
case0:
{s=1;break;}
case1:
{s=2;break;}
case2:
{s=3;break;}
case3:
{s=4;break;}
case4:
{s=5;break;}
case5:
{s=6;break;}
case6:
{s=7;break;}
case7:
{s=8;break;}
default:
break;
}
}
/*******外中断红外接收程序******/
voidintt0()interrupt0
{
EX0=0;
key=0;
if(hwin==0)
{
delay
(2);
if(hwin==0)
{
while
(1)
{
while(hwin==0);
key++;
k=0;
while(hwin==1)
{
delay
(1);
k++;
if(k>2)
{
gotoloopout;
}
}
loopout:
switch(key)//对应键盘选择相应的处理
{
case2:
{key1=~key1;break;}
case3:
{key2=~key2;break;}
case4:
{key3=~key3;break;}
case5:
{key4=~key4;break;}
case6:
{key5=~key5;break;}
case7:
{key6=~key6;break;}
case8:
{key7=~key7;break;}
case9:
{key8=~key8;break;}
case10:
{key9=~key9;break;}
case11:
{key10=~key10;break;}
case12:
{key11=~key11;break;}
case13:
{key12=~key12;break;}
case14:
{key13=~key13;break;}
case15:
{key14=~key14;break;}
case16:
{key15=~key15;break;}
case17:
{//调光和档次选择
if(disout==0x00)
{
disout=0xff;
}
else
{
disout--;
}
loop();
;break;
}
default:
break;
}
}
}
}
}
/***********主函数***********/
voidmain()
{
init();
loop();
P2=0xfe;
while
(1)
{
while(powerin==1)
{
delay(s);
tiaoguang();
}
}
}