单片机相关例子.docx
- 文档编号:3431747
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:19
- 大小:169.59KB
单片机相关例子.docx
《单片机相关例子.docx》由会员分享,可在线阅读,更多相关《单片机相关例子.docx(19页珍藏版)》请在冰豆网上搜索。
单片机相关例子
基于单片机的红外遥控器解码器的设计
TC9012F是一种通用型红外遥控信号发送用CMOS大规模集成电路,适用于电视(TV),磁带录像机(VTR),激光唱机等设备的遥控操作。
市场上,以TC9012F为核心的9012型红外遥控器被广泛使用且价格便宜。
将设计的基于单片机AT89C51的9012型红外遥控解码器应用于生产即时显示系统中,作为参数设置和系统控制用红外遥控器,在实际应用中收到了良好效果。
1红外线遥控信号发送器电路TC9012F的遥控信号
TC9012F为4位专用微控制器,其内部振荡电路的振荡频率fosc典型值为455kHz。
当不按下操作键时,其内部455kHz的时钟振荡器停止工作,以减少电池消耗。
内部分频电路将振荡频率,fosc进行12分频后,变成频率fc=37.9kHz,占空比为1/3的脉冲载波信号。
红外遥控信号发送器电路由集成电路TC9012F、键盘矩阵电路、驱动器和红外发光二极管组成,遥控信号为37.9kHz的脉冲载波被遥控编码脉冲调制的已调波,如图1所示。
遥控编码脉冲由引导码、用户码、功能码和功能码的相反码组成,用户码是同一组码发送两次,如图2所示。
用户码为8位,所以整个脉冲码为32位。
引导码作为接收数据的准备脉冲,他由8TCP(4.5ms)的高电平和8TCP(4.5ms)的低电平组成。
用户码和功能码采用脉冲位置调制(PPM)方式编码,根据脉冲之间的时间间隔来区分码值的"0"或"1"。
对应于二进制数字信号的"0"或"1",脉冲时间间隔分别为2TCP(1.125ms)和4TCP(2.25ms),而每一脉冲的宽度仍不变,均为TCP(0.5626ms)。
由于用户码发送两次,功能码与其相反码一起发送,因此系统的误动作很少。
本遥控器采用第一次发送的遥控信号的编码脉冲(图3所示)和第二、第三次连续发送的遥控信号的编码脉冲(图4所示)不同的工作方式。
这样,当按键一直按着的时候,从第二次连续发送开始,只发送引导码和用户码第一位SO的相反码SO,因此可减少接收处理时间和红外发光二极管功耗,遥控编码脉冲经脉冲载波调制后由TC9021F的第脚输出,再经激励器驱动红外发光二极管,发送出波长为940nm的脉冲红外光。
假设用户码为十六进制的76H则第一次发送的遥控信号的编码脉冲如图3所示。
由图2和图3可以看出,遥控编码脉冲波形的输出时间为192TCP或224TCP,α为用户码(8位)的输出时间。
当α≥26TCP时,遥控编码脉冲波形输出时间为224TCP.另外,对于连续发送的编码脉冲中用户码第一位的相反码的脉冲间隔时间,当SO="1"时,则SO="0",该时间为2TCP,当SO="0"时,则SO="1",该时间为4TCP.2解码器硬件设计
解码器硬件以AT89C51单片机为核心,如图5所示,图中只给出接收红外遥控信号的部分电路。
红外遥控信号经过红外接收模块接收后,解调为遥控信号的编码脉冲由输出端A输出,其波形如图3和图4所示,此信号经过反相器74LS04输出到AT89C51的外部中断INT0输入端.单片机通过运行程序对红外遥控器TC9021所发出的编码脉冲进行接收和译码。
3单片机程序设计
单片机程序主要解决的问题就是如何对接收到的9021型红外遥控器所发射的信号进行解码,编码脉冲信号是由引导码、用户码、和功能码等部分组成,我们只对获取其功能码过程进行分析。
在单片机设置中,将单片机AT89C51内部定时器/计数器T0设为定时方式1,定时时间为1ms;设外部中断INT0为下降沿中断触发方式,由于在接收时将编码脉冲信号进行反相,因此,每当INT0外管脚信号下降沿到来时,外部中断INT0发生中断,启动定时器T0,定时器每次中断定时时间为1ms并累加到定时计数器中,在下一次外部中断INT0发生中断时读取定时计数器中的时间,通过对两个脉冲之间的定时时间的分析来对遥控器功能码进行解码。
图6、图7和图8分别给出解码器主程序、定时器T0中断程序和外部中断INT0中断程序的流程图。
4结语
生产即时显示系统面向生产现场,对生产效率进行量化管理,目前在发达国家和国内一些外资企业已经得到广泛的应用。
他通过即时显示生产中的定额任务量、生产目标以及当前时刻实际完成的生产数量,可以使生产情况一目了然,提高了生产效率。
此显示系统一般都安放在生产线上方,工作人员需要经常对显示系统进行操作,设定和修改数据,用红外遥控器对生产即时显示系统进行不接触的参数设定,可以使操作灵活方便,抗干扰强。
单片机红外遥控解码程序
红外遥控器软件解码程序
红外一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲,本程序经过试用,能解大部分遥控器的编码!
#include "at89x52.h"
#define NULL 0x00//数据无效
#define RESET 0X01//程序复位
#define REQUEST 0X02//请求信号
#define ACK 0x03//应答信号,在接收数据后发送ACK信号表示数据接收正确,
也位请求信号的应答信号
#define NACK 0x04//应答信号,表示接收数据错误
#define BUSY 0x05//忙信号,表示正在忙
#define FREE 0x06//空闲信号,表示处于空闲状态
#define READ_IR 0x0b//读取红外
#define STORE_IR 0x0c//保存数据
#define READ_KEY 0x0d//读取键值
#define RECEIVE 0Xf400//接收缓冲开始地址
#define SEND 0xfa00//发送缓冲开始地址
#define IR 0x50//红外接收缓冲开始地址
#define HEAD 0xaa//数据帧头
#define TAIL 0x55//数据帧尾
#define SDA P1_7
#define SCL P1_6
unsignedcharxdata*buf1; //接受数据缓冲
unsignedint buf1_length; //接收到的数据实际长度
unsignedcharxdata*buf2; //发送数据缓冲
unsignedint buf2_length; //要发送的数据实际长度
bitbuf1_flag; //接收标志,1表示接受到一个数据帧,0表示没有接受到数据帧或数据
帧为空
bitbuf2_flag; //发送标志,1表示需要发送或没发送完毕,0表示没有要发送的数据或
发送完毕
unsignedcharstate1,state2; //用来标志接收字符的状态,state1用来表示接
收状态,state2用来表示发送状态
unsignedchardata*ir;
union{
unsignedchara[2];
unsignedintb;
unsignedchardata*p1[2];
unsignedintdata*p2[2];
unsignedcharxdata*p3; //红外缓冲的指针
unsignedintxdata*p4;
}p;
//union{ //
// unsignedchara[2]; //
// unsignedintb;
// unsignedchardata*p1[2];
// unsignedintdata*p2[2];
// unsignedcharxdata*p3;
// unsignedintxdata*p4; //地址指针
//}q; //
union{
unsignedchara[2];
unsignedintb;
}count;
union{
unsignedchara[2];
unsignedintb;
}temp;
union{
unsignedchara[4];
unsignedintb[2];
unsignedlongc;
}ir_code;
union{
unsignedchara[4];
unsignedintb[2];
unsignedlongc;
unsignedchardata*p1[4];
unsignedintdata*p2[4];
unsignedcharxdata*p3[2];
unsignedintxdata*p4[2];
}i;
unsignedcharir_key;
bitir_flag; //红外接收标志,0为缓冲区空,1为接收成功,2为缓冲溢出
voidsub(void);
voiddelay(void);
voidie_0(void);
voidtf_0(void);
voidie_1(void);
voidtf_1(void);
voidtf_2(void);
voidread_ir(void);
voidir_jiema(void);
voidir_init(void);
voidir_exit(void);
voidstore_ir(void);
voidread_key(void);
voidreset_iic(void);
unsignedcharread_byte_ack_iic(void);
unsignedcharread_byte_nack_iic(void);
bitwrite_byte_iic(unsignedchara);
voidsend_ack_iic(void);
voidsend_nack_iic(void);
bitreceive_ack_iic(void);
voidstart_iic(void);
voidstop_iic(void);
voidwrite_key_data(unsignedchara);
unsignedintread_key_data(unsignedchara);
voidie0(void) interrupt0{ie_0();}
voidtf0(void) interrupt1{tf_0();}
voidie1(void) interrupt2{ie_1();}
voidtf1(void) interrupt3{tf_1();tf_2();}
voidtf2(void) interrupt5{ //采用中断方式跟查询方式相结合的办法解
码
EA=0; //禁止中断
if(TF2){ //判断是否是溢出还是电平变化产生的中断
TF2=0; //如果是溢出产生的中断则清除溢出位,重
新开放中断退出
EA=1;
gotoend;
}
EXF2=0; //清除电平变化产生的中断位
*ir=RCAP2H; //把捕捉的数保存起来
ir++;
*ir=RCAP2L;
*ir++;
F0=1;
TR0=1; //开启计数器0
loop:
TL0=0; //将计数器0重新置为零
TH0=0;
while(!
EXF2){ //查询等待EXF2变为1
if(TF0)gotoexit; //检查有没超时,如果超时则退出
};
EXF2=0; //将EXF2清零
if(!
TH0) //判断是否是长低电平脉冲过来了
{ //不是长低电平脉冲而是短低电平
if(F0)count.b++; //短脉冲数加一
temp.a[0]=RCAP2H; //将捕捉数临时存放起来
temp.a[1]=RCAP2L;
gotoloop; //返回继续查询
}
else{ //是低电平脉冲,则进行处理
F0=0;
*ir=temp.a[0]; //把连续的短脉冲总时间记录下来
ir++;
*ir=temp.a[1];
ir++;
*ir=RCAP2H; //把长电平脉冲时间记录下来
ir++;
*ir=RCAP2L;
ir++;
if(ir>=0xda){
gotoexit; //判断是否溢出缓冲,如果溢出则失败退出
}
gotoloop; //返回继续查询
}
exit:
ir_flag=1; //置ir_flag为1表示接收成功
end:
;
}
voidrs232(void) interrupt 4{
staticunsignedcharsbuf1,sbuf2,rsbuf1,rsbuf2; //sbuf1,sbuf2用来接收
发送临时用,rsbuf1,rsbuf2用来分别用来存放接收发送的半字节
EA=0; //禁止中断
if(RI){
RI=0; //清除接收中断标志位
sbuf1=SBUF; //将接收缓冲的字符复制到sbuf1
if(sbuf1==HEAD){ //判断是否帧开头
state1=10; //是则把state赋值为10
buf1=RECEIVE; //初始化接收地
址
}
else{
switch(state1){
case10:
sbuf2=sbuf1>>4; //把高半字节右移到的半字节
sbuf2=~sbuf2; //把低半字节取反
if((sbuf2&0x0f)!
=(sbuf1&0x0f)) //判断接收是否正确
{ //接收错误,有可能接收的是数
据帧尾,也有可能是接收错误
if(sbuf1==TAIL) //判断是否接收到数据帧尾
{ //是接收到数据帧尾
buf1=RECEIVE; //初始化接收的地址
if(*buf1==RESET) //判断是否为复位命令
{
ES=0;
sbuf2=SP+1;
for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1
[0]++)*p.p1[0]=0;
}
state1=0; //将接收状态标志置为零,接收
下一个数据帧
buf1_flag=1; //置接收标志为1,表示已经接收
到一个数据帧
REN=0; //禁止接收
}
else
{ //不是接受到数据帧尾,表明接
收错误
state1=0; //将接收状态标志置为零,重新
接收
buf1=RECEIVE; //初始化发送的地址
*buf1=NACK; //把NACK信号存入接收缓冲里
buf1_flag=1; //置标志位为1,使主程序能对接
收错误进行处理
REN=0; //禁止接收
}
}
else
{ //接收正确
rsbuf1=~sbuf1; //按位取反,使高半字节变原码
rsbuf1&=0xf0; //仅保留高半字节,低半字节去
掉
state1=20; //将状态标志置为20,准备接收
低半字节
}
break;
case20:
sbuf2=sbuf1>>4; //把高半字节右移到的半字节
sbuf2=~sbuf2; //将低半字节取反
if((sbuf2&0x0f)!
=(sbuf1&0x0f)) //判断接收是否正确
{ //接受错误
state1=0; //将接收状态标志置为零,重新
接收
buf1=RECEIVE; //初始化接收的地址
*buf1=NACK; //把NACK信号存入发送缓冲里
buf1_flag=1; //置标志位为1,使主程序能对接
收错误进行处理
REN=0; //禁止接收
}
else
{
sbuf1&=0x0f; //仅保留低半字节,去掉高半字
节
rsbuf1|=sbuf1; //高低半字节合并
*buf1++=rsbuf1; //将接收的数据保存至接收缓冲
里,并且数据指针加一
buf1_length++; //接收数据长度加一
state1=10; //将state1置为10,准备接收下
个字节的高半字节
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 相关 例子