1单片机编程注意事项一、变量或常数定义例如var1equ50hvar2equ51hsp_valequ65h其中前2项为变量定义,第3项为常数定义,在定义上没有区别,在使用的时候才有。如:movsp,#sp_valmovvar1,#21h注意:equ表示等价关系,是用于编译或者说是编译器使用的。2二、程序框架;变量常数定义,有助于程序阅读和修改方便var1equ50hvar2equ51hsp_valequ65h;中断向量表org00hajmpmainorg0bhajmptime0_serv;程序入口org100hmain:movsp,#sp_val;设置栈初始位置clrp3.5;显示使能,看图3movsp,#sp_valcallinitial_sub;初始化函数;主程序循环,一定要有loop:…..sjmploop;初始化函数体,例子为设置定时器,并开其中断initial_sub:movtmod,#01hmovtl0,#78hmovth0,#0echsetbET0setbtr0setbEAret4;定时器中断服务程序time0_serv:movtl0,#78hmovth0,#0ech......reti;其它中断服务程序或函数;编译结束标示end注意:1、中断服务程序不要用call调用2、中断服务程序或函数内有跳转指令时,不要跳转到本体之外,同样,其它地方的跳转指令也不要跳转中断服务程序或函数内部。5三、显示程序;要求做成函数如;12数码管显示函数Disf12:movdptr,#9000hmova,disvar12;disvar12为一变量,要事先定义movx@dptr,aret;调用时,使用movdisvar12,#??hcalldisf12;其它数码显示函数相似6四、显示移位程序显示变量为了描述方便,使用了v1、v2和v3,其后面的l和h分别表示,变量的低4位和高4位。要仔细分析移位过程,举例如下:7123456v1lv1hv2lv2hv3lv3hnew12345vnewv1lv1hv2lv2hv3lv3hMova,v1SwapaMovv1,aMova,v2SwapaMovv2,aMova,v3SwapaMovv3,a数码管显示向右移动移位v1hv1lv2hv2lv3hv3lanlv3,#0f0hMova,v2Anla,#0fhOrla,v3Movv3,a①anlv2,#0f0hMova,v1Anla,#0fhOrla,v2Movv2,a②③Movr0,#v3Mova,v2Xchda,@r0movv2,aMovr0,#v2Mova,v1Xchda,@r0movv1,a8五、定时器的使用;按照键盘的要求设置中断时间为20ms比较合适movtl0,#00hmovth0,#0b8h计算方法11.0592/12=0.9216Mhz1/0.9216Mhz=1.085us20ms=1.085us*x得到x=18432,65536-18432=47104=0xb800即tl0=00h,th0=b8h一个定时器可以扩展为多个使用9六、读键盘及软件去抖动movdptr,#0c000hmovxa,@dptrmovkeyinputl,amovdptr,#0d000hmovxa,@dptrmovkeyinputh,aFf的时候没有按键按下,某个bit为为零,表示对应按键按下。按键查表的一种方法movdptr,#0c000hmovxa,@dptrcplamovkeyinputl,aanla,#0fhmovdptr,#table1movca,@a+dptr10mova,keyinputlanla,#0f0hswapamovdptr,#table2movca,@dptr+aOrg900hTable1:;012345678Db55h,0f4h,0f3h,55h,0f2h,55h,55h,55h,0f1hTable2:;012345678Db55h,44h,07h,55h,04h,55h,55h,55h,01h;另外一半键盘同理11第一个图为高电平有效,我们用的是低电平有效,第二个图,抖动时间一般为10到20ms按键可以使用按下有效或抬起有效均可。用定时器来读键盘的示意图如下所示:无按键状态第一次按键发生定时中断,间隔20ms可能会抖动按下稳定状态按键第一次抬起可能会抖动无按键状态12软件去抖动的方法有很多种1、最简单的方法为延时的方法,此方法在第一次判断有键盘按下使用延时,可以把第一次抖动去掉,在第一次判断有键抬起使用延时,可以把第二次抖动去掉。延时长度要充分让过抖动,可以选30ms,此方法效率较低。2、使用定时器做延时的方法,即在判断第一次有键按下后,启动一个定时器或定时器内的一个计数器,把第一次抖动去掉,在判断第一次按键抬起的后,启动一个定时器或定时器内的一个计数器,把第二次抖动去掉。3、使用状态判断的方法,在判断第一次有键按下后,启动一个计数器,如果读键不变,计数器加1,如果读键变化(即出现抖动),计数器清零,判断计数器的值为3的时候,表示已经让过了第一次抖动,进入键盘按下的稳定状态,此时要等按键抬起,判断有第一次按键抬起后,启动一个计数器,如果读键不变,计数器加1,如果读键变化(即出现抖动),计数器清零,判断计数器的值为3的时候,表示已经让过了第二次抖动,进入键盘抬起的稳定状态。13软件去抖动的方法有很多种4、网上有人介绍的方法(此方法仅作为参考,不要求)设置3个变量Kready、Ktemp和Kinput,并设置定时中断周期为20ms。在定时中断服务程序中读取按键,并把读取的数据存于变量Kinput中。变量Kready中是所需要的稳定的按键信息;Ktemp是中间变量,它的值是上一次的Kinput。Keradyn=KtempKinput+Kreadyn-1(Ktemp⊙Kinput)(1)Ktemp=Kinput(2)14时刻KreadyKtempKinput100020013010400151116111711081019110100001100015时刻KreadyKreadyn-1KtempKinput10000200013001040001510116111171110811019111010010011000016时刻1为没有键按下的初始状态;时刻2的Kinput为1,但时刻3的Kinput又变为0,说明时刻2的Kinput为1并不是有键按下,可能只是干扰,所以Kreqdy为0;时刻4同时刻2的情况类似,但是时刻4和时刻5时Kinput都为1,说明有按键按下,在时刻5时Kready为1;虽然时刻7时Kinput为0,但时刻5、6、8时Kinput都为1,说明按键一直按下,只不过有干扰,Kready保持为1;时刻9、10连续两个时刻Kinput为0,表示按键抬起,时刻10时Kready为0。17通过分析可以看出,Kready中是消除了抖动并在一定程度上排除了干扰的有效按键信息。从按键按下到Kready为1,最长时间约为40ms,最短约为20ms。其时间长短取决于键按下时处于定时中断周期的所在时刻。如果按键一直按下,则有效键信息以20ms的间隔重复输出。还可知道当前时刻Kready的值不但与Ktemp和Kinput有关,还与Kready前一时刻的值有关。我们把Keady的当前时刻记作Kreadyn,作为因变量;前一时刻记作Kreadyn-1,并和Ktemp、Kinput一起作为自变量18状态KreadyKreadyn-1KtempKinput100002000130010410115010061101711108111119Kready和Kreadyn-1的初始设置均为0得到逻辑式如下:Keradyn=KtempKinput+Kreadyn-1(Ktemp⊙Kinput)(1)Ktemp=Kinput(2)20表达式(1)中的Kready提供的是间隔20ms的重复键信息;有的地址不需要重复键值,按一次键获得一次键值就够了;而有的应用系统则两种键值都要有,比如电视监控系统的控制键盘中对镜头云台的控制需要重复键值,其他命令键则不需要。为了满足这种要求,就要对表达式(1)进行扩展。为此,引入了另外两个变量和1个常量。它们分别是Koutput、Kstore和Kconst。Koutput作为最终的键信息输出;Kstore作为中间变量用作保存上一次去抖动后的键信息;Kconst是常量,它的值需要先给定;0对应非重复键,1则对应重复键。表露Koutput、Kconst、Kstore和Kready之间关系的真值表21KoutputKconstKstoreKready1x01111100110x100x0022获得了如下最简逻辑表达式,作为表达式(1)的扩展:Kstore中是上一次的Kready,所以Kstroe=Kready(4)根据表2绘出的卡诺图如图2所示。表达式(3)是1个包含了表达式(1)的通用逻辑表达式。它用于既有重复键输出也有非重复键输出的系统中。对于只有重复键输出的系统,Kconst全为1,则Koutput=Kready,所以只用表达式(1)就可以了。如果系统只要求非重复键输出,则Kconst全为0,表达式(3)简化为此为按下有效,抬起有效,为Kready的反与上Kstroe23例子,使用30ms的定时器,在定时中断服务程序中读键盘变量定义keyinputlequ40hkeyprelequ41hkeyoutlequ42hkeyinputhequ43hkeyprehequ44hkeyouthequ45h在初始化程序中设置变量的初始值movkeyinputl,#00hmovkeyprel,#00hmovkeyinputh,#00hmovkeypreh,#00hmovkeyoutl,#00hmovkeyouth,#00h24在定时器中断服务程序中读键盘及去抖动Key_left:movdptr,#0c000hmovxa,@dptrcplamovkeyinputl,acplaanla,keyprelmovkeyoutl,amovkeypre,keyinputljzkeyrightanla,#0fhmovdptr,#table1movca,@a+dptr25keyinputkeypre00010101Keyout=(~keyinput)andkeypre下个时刻无抖动,此处为变化无按键状态上个时刻有抖动,此处为变化26上面的例子在有些键盘(有些故障)的抖动是消不掉,有2种方法,一个是增加定时长度,二是采用下面的例子。变量定义,增加2个变量,表示再前面的键盘值keypprelequ46hkeypprehequ46h在初始化程序中设置变量的初始值,增加的变量也是设置为0movkeypprel,#00hmovkeyppreh,#00h27keyinputkeypre0000100101Keyout=(~keyinput)and(~keypre)andkeyppre无按键状态需要判断的状态为100其中1为keyppre,另外2个0位keypre和keyinputkeyppre1110000028在定时器中断服务程序中读键盘及去抖动Key_left:movdptr,#0c000hmovxa,@dptrcplamovkeyinputl,acplamovr0,amova,keyprelcplaanla,r0anla,keypprelmovkeyoutl,amovkeyppre,keypremovkeypre,keyinputljzkeyright.......