分别用K0H、K0L——K7H、K7L来定义,这样做不影响整个程序的执行,但便于阅读和理解程序。定义格式如下:
K0 BIT P1.0 ? K7 BIT P1.7
由于P1.0至P1.7对应的红外发射频率分别为300Hz、600 Hz、900 Hz、1200 Hz、1500 Hz、1800 Hz、2100 Hz、2400 Hz,而T1的定时时间是50ms故在这七种状态下面,P3.4端口状态分别反转15次、30次、45次、60次、75次、90次、105次、120次。故定时器T0对应的定时时间分别为50ms/15、50ms/30、50ms/45、50ms/60、50ms/75、50ms/90、50ms/105、50ms/120,即分别为:3.33ms、1.67ms、1.11ms、0.833ms、0.667ms、0.556ms、0.476ms、0.417ms。由前述定时器初值计算方法可算出各状态定时器的初值。
定时器T1的定时初值计算如下:
由于工作在方式一,时钟频率为12MHz,故定时最大值M为65536
初值 X=M—定时值/T
X=65536—50000/1=15536
即T1的初值为15536,转化为十六进制为3CB0H
各情况下,定时T0的定时初值计算如下:
当按下K0键时,定时时间为3.33ms,此时定时器初值为 X0= 65536—3330/1=62206
转化为十六进制为
0F2FEH
当按下K1键时,定时时间为1.67ms,此时定时器初值为 X1=65536—1670/1=63866 转化为十六进制为0F97AH
当按下K2键时,定时时间为1.11ms,此时定时器初值为 X2=65536-1110/1=64426 转化为十六进制为0FBAAH
当按下键K3时,定时时间为0.833ms,此时定时器初值为 X3=65536-833/1=64703 转化为十六进制为0FCBFH
当按下键K4时,定时时间为0.667ms,此时定时器初值为 X4=65536-667/1=64869
23
转化为十六进制为0FD65H
当按下键K5时,定时时间为0.556ms,此时定时器初值为 X5=65536-556/1=64980 转化为十六进制为0FDD4H
当按下键K6时,定时时间为0.476ms,此时定时器初值为 X6=65536-476/1=65060 转化为十六进制数为0FE24H
当按下键K7时,定时时间为0.417ms,此时定时器初值为 X7=65536-417/1=65119 转化为十六进制数为0FE5FH
为了便于理解源程序,各种情况下定时器的初值采用K0H—K7H和K0L—K7L来表示,分别存入定时器的高8位和低8位。采用赋值伪指令EQU,格式如下:
K0H EQU #0F2H K0L EQU #0FEH
通常,在一个汇编语言源程序的开始,响应中断前,都要设置一条ORG伪指令来指定该程序在存储器中存放的起始位置。若省略ORG指令,则该程序从0000H单元开始存放。在一个源程序中,可以多次使用ORG伪指令,以规定不同程序段或数据段存放的起始地址,但要求16位地址由小到大顺序排列,不允许空间重叠。汇编语言结束应加一个END指令,表示汇编程序已经结束,处于END之后的程序,汇编程序不予处理。
对于初始化程序,就是对P1口、P3口赋初值,此时遥控器没有工作,两个8位端口均赋以0FFH;设置定时器0和定时器1方式控制寄存器TMOD,由于T0和T1均工作在方式1,功能选择为定时器,故TMOD的值为11H,然后开放所有中断,将单片机设置为空闲工作方式,即将电源控制寄存器的值设为01H,初始化完毕,程序即进入键盘扫描程序。
4.1.3键盘扫描程序
键盘扫描程序就是扫描键盘看是否有键按下,如有键按下,判断出是哪一个键,当确定按下某一个键后,即执行红外发射程序。扫描的方法是判断P1口各位的电平,无按键按下时,各位均为高电平,当某一个按键按下以后,该位即为低电平。
24
通常,按键所用开关为机械弹性开关,均利用了机械触点的合、断。一个电压通过机械触点的断开、闭合过程,由于机械触点的弹性作用,一个按键开关在闭和时不会马上稳定接通,在断开时也不会一下断开。因而,在闭合和断开的瞬间均伴随着一连串的抖动,抖动时间的长短由按键的机械特性决定,一般为5—10ms。按键电路的消抖措施通常有硬件和软件两种方法[24]。硬件消除键盘抖动措施主要就是外加双稳态电路或者滤波电路的方法。本电路采用的是软件消抖的方法,就是调用一个延时子程序,延时时间设定为6ms,延时子程序如下:
DL1: MOV R4,#0CH DL2: MOV R5,#0FFH DL3: DJNZ R5,DL3 DJNZ R4,DL2 RET
延时时间的计算就是根据执行指令所需时间的总和,0CH、0FFH分别为十进制数的12和255,因此这个程序所耗用的时间为
1+(255*2+2+1)*12+1+2=6160个机器周期
由于晶振采用的是12MHz,所以1机器周期=1us,执行程序的总时间为6.16ms,与6ms存在0.16ms的误差,不过这不影响程序的执行。
4.1.4 中断服务程序 1.外部中断1
外部中断1在程序中的作用就是唤醒单片机,使单片机从空闲方式回到工作状态。当有键按下时,通过与门触发外部中断1中断,IDL被硬件硬件清零,单片机结束低功耗空闲节电方式[25]。
外部中断是由外部原因引起的,共有两个中断源,即外部中断0和外部中断1,相应的中断请求信号输入端是INT0和INT1。
外部中断请求有两种触发方式,即电平触发方式和脉冲出发方式。 定时器/计数器控制寄存器TCON的低四位用于控制外部中断请求和触发方式,有关的位表示如下:
IE:外部中断请求标志位,当CPU采样到INT端出现有效的中断请求时,次位由硬件置1,表示外部事件请求中断,中断响应完成后,再由硬件自动清零。
IT:外部中断请求触发方式控制位。当IT=1,选择脉冲触发方式(也称边沿触发方式)负跳变有效;当IT=0,选择电平出发方式,低电平有效。
中断的允许或禁止是由片内的中断允许寄存器IE控制的。IE的格式如
25
下: EA — ET2 ES ET1 EX1 ET0 EX0 IE的每一位都可以由软件置1或清零。且1——中断允许,0——中断屏蔽 EA:中断允许总控制位。EA=0时,表示CPU禁止所有中断,即所有的中断请求被屏蔽;EA=1时,表示CPU开放中断,但每个中断源的中断请求是允许还是禁止,要由各自的允许位控制。
EX:外部中断允许控制位 ET:外部中断允许控制位。 ET:定时/计数器的中断允许控制位 ES:串行中断允许控制位。
中断的各控制位在初始化程序中定义,在初始化程序中应当开外部中断1和总中断,触发方式选择为脉冲触发方式,后负跳变有效。中断程序如下: INT1: CLR IE1
ANL PCON,#00H RETI
2. 定时器中断服务程序
定时器T1作为发射时间控制器,当确认某一按键被按下后,T1开始记时,记时时间为50ms,记时时间到,定时器1产生中断,红外脉冲停止发射。同时将红外脉冲发射端口P3.4电平置成无效电平
定时器T0作为红外线发射频率控制器,当定时时间到产生中断,将P3.4端口反转一次,同时对定时器重新装初值,定时时间与前相同,T0重新定时,时间到又将P3.4端口反转一次,如此往复,直到定时器1记时时间到,关闭定时器1和定时器0重新回到主程序。此处采用了一个位标志bz,在宏指令中将其定义为位寻址区的07H,当定时器在执行中断服务程序时,将该位定义为高点平1,使主程序不断的查询该位,当该位为1时,等待中断程序的执行,此时向外发射红外脉冲;当该位为0时,中断结束,主程序继续向下执行
[26]
。其流程图如下:
开始
确认是否有键按下 Y N 26
启动定时器T1,定时时间为50ms
Y
Y N
N
图4.2 定时器中断服务子程序流程图
4.2 遥控接收器程序设计
4.2.1 程序总体结构
遥控接收器是根据接收到的不同频率的红外光信号,由CPU转化为对应的控制功能对控制电路实施控制。当接收电路接收到第一个红外线脉冲时,中断INT1被触发,启动定时器1和计数器0。定时器1作为计数时间控制器,计数器0作为在规定记数时间内所记得的红外脉冲数。接收信号端接至P3.3和P3.4口,该两引脚为复用引脚,P3.3引脚复用为外部中断1请求输入端;P3.4引脚复用为定时器/计数器0计数脉冲输入端。当收到第一个红外脉冲时,INT1被触发,T0和T1开始工作,每收到一个红外脉冲,计数器0记数值加一,当定时器定时时间到,产生中断,保存计数器0的计数值。由于定时时间为50ms,故各种不同状态对应的红外脉冲数大约为15、30、45、60、75、90、105、120个,然后将记数值与上述各值比较。由于存在误差,计数器0的记数值不可能严格和上述值相等,只要近似相等就行,限制的误差范围为5,即将记数值加减5得到两个数值,再判断哪一个值在这一范围之内,即可断定遥控发射器发
27