跟我学51单片机(六):单片机外部中断及红外遥控器解码
rrupt 1 ( 1)
bit in = ~IR_Input; ( 2)
TH0 = 0XFF; ( 3)
TL0 = 0X83; ( 4)
IR_Data[IR_sign] = IR_Data[IR_sign] | in; ( 5)
IR_count++; ( 6)
if(IR_count == 1 || IR_count == 2) ( 7)
{
if(in == 0) ( 8)
{
TR0 = 0; ( 9)
EX1 = 1; ( 10)
return; ( 11)
}
}
if(IR_count == 3) ( 12)
{
IR_sign = 1; ( 13)
}
else if(IR_count == 8) ( 14)
{
if(IR_Data[1] != 0) ( 15)
{
TR0 = 0; ( 16)
EX1 = 1;
return;
}
IR_sign = 2; ( 17)
}
else if(IR_count == 14) ( 18)
{
IR_sign = 3; ( 19)
}
else if(IR_sign == 3) ( 20)
{
TR0 = 0; ( 21)
IR_Success(); ( 22)
return; ( 23)
}
else
IR_Data[IR_sign] = IR_Data[IR_sign] 《 1; ( 24)
程序详细说明:
(1)定时器中断0 服务函数,红外接收头解码数据触发外部中断1 后,引发定时器中断,从而进行捕获解码。
(2)解码时, 将载频部分变为低电平, 即低电平实际为1, 高电平实际为0。
(3)设置定时器0 高八位初值,因为要定时间长度为一个数据位周期。
(4) 设置定时器0 低八位初值。经过实测,SAA3010 的位时间在1.655ms 左右。
(5)将红外数据放入最低位。
(6)红外计数没进一次定时器中断就加1。
(7)如果当前是第1 次和第2 次进入定时器中断。
(8)如果此时in 的值为0,即如果发现起始两位不全是1 的情况。
(9)关闭定时器0。
(10)重新打开外部中断进行接收。即起始两位必须都为1。
(11)退出返回。
(12)如果接收完起始位(2 位)和控制位(1 位)。
(13)IR_sign 置1,即将接收到的红外系统码放到IR_Data[1] 中。
(14)如果当前计数达到第8 次,即接收完5 位系统码。
(15)如果接收到的系统码不为0,即要求系统码全为0 才正确。
(16)则关闭定时器和重开外部中断并返回。
(17)IR_sign 置2,将接收到的红外数据位放到IR_Data[2] 中。
(18)如果当前计数达到第14 次,即接收完6 位数据码。
(19)IR_sign 置3,表示数据码接收成功。
(20)如果IR_sign 等于3,即表示如果接收完成。
(21)接收完成,关闭定时器0,不再捕获。
(22)接收完成后跳转到执行IR_Success() 函数,进行显示以及重新初始化等。
(23)返回。
(24)将数据左移一位, 以便将一下位数据并于最低位。
五、调试要点与实验现象
接好硬件,通过冷启动方式将程序所生成的。hex 文件下载到单片机运行后,打开串口调试助手软件,设置好波特率9600,复位单片机,然后按下SAA3010 遥控器上的相应按键,可以观察到在接收窗口有接收到的数据显示见图8,此外电路板上的串行通信指示灯也会闪烁,P0 口也会将所接到的数据显示在LED 灯上。
值得注意的是,不同红外遥控器的编码格式不同,即便是同一型号的红外遥控器,其发射出来的码值也可能稍有微小的区别,例如笔者手里所用的SAA3010 红外遥控器,其位时间实测在1.655ms 左右,而不是在标称的1.688ms,因此,有条件的读者可以用示波器或者逻辑分析仪之类的仪表对遥控器发射出来的码值进行测量,从而相应的修改所捕获的时间,确保无误。此外,红外的穿透能力较弱,例如我们用手遮挡住遥控器的发射头或者接收头时,此时难以收到数据或者引入干扰。
六、总结
本讲介绍了51 单片机如何利用外部中断触发和内部定时器捕获的方式进行红外遥控器解码,现简单总结如下:
要对红外遥控器解码,首先应当知道遥控器的编码标准,无论是本文中所介绍的NEC 标准和PHILIPS 标准,还是其他编码格式,因为不了解编码格式,难以对编码进行判断,从而造成解错码。其次,由于晶振(如遥控器内部和单片机晶振)本身的不稳定性等,为保证解码的准确性,应对每位码长时间经行测量,如利用仪表或者使用单片机本身,从而得到准备结果。下讲将讲述单片机驱动字符型液晶1602 模块的原理与实例,敬请期待。
- 关于RTX51 TINY的分析与探讨(05-30)
- 浅析8051模块化编程技巧(05-28)
- 基于DSP和单片机通信的液晶显示设计方案(07-20)
- 锁相环控制及初始化简析(08-27)
- 基于MSP430自动胀管控制器的研究(09-07)
- 嵌入式C实现延时程序的不同变量的区别(03-01)