历史上的今天
今天是:2025年02月08日(星期六)
2020年02月08日 | PIC单片机程序设计需要注意的一些问题及看法
2020-02-08 来源:eefocus
一、区分指令的大小写
编写PIC单片机的源程序,除了源程序的开始处需要严格的列表指令外,还须注意源程序中字母符号的大小写规则,否则在PC机上汇编程序时不会成功。在源程序中都会使用伪指令INCLUDE。这条指令将列表中指定的单片机文件(在MPLAB中)渎入源程序作为源程序的一部分,所以凡是MPLAB中有关该单片机已有的寄存器在源程序中无须再用赋值指令(EQU)赋值,这就使所建立的源程序大为简化。
此外,由于有了伪指令INCLUDE,所以根据MPLAB软件中的格式,在源程序中的操作数凡是涉及MPLAB已规定的寄存器名称的,其字母一律只能大写,不能小写。其余操作码、符号字母可任意大小写,但0x中的X应小写。否则汇编不会成功。鉴于上述原因,为了书写方便,在使用MPLAB软件时,PIC单片机的源程序均用大写字母为宜(0x例外)。
以下举例有关机器人控制的实现。控制部分采用PIC16F7X系列单片机,运用汇编语言编程,运行速度较快,能够达到系统的要求。
二、动作标志位的使用
在整个控制中,组合的动作很多,当所有动作定位都通过光电开关控制时,在程序编写上就有一些问题。如要求左手上升到鼓掌位、右手上升到举手位(手初始位置在最下的放下位),光电开关0有效(即为0时是挡住),到达正确位置。用简单的理解可以写成下面的程序:
list P=16c73
call lefthandup
call righthandup
L0 call readinsignal
bdss csl_v,lefthandligbts
call lefthandstop
bfsc csl_v,righthandlight4
goto L0
call righthandstop
L1 call readinsignal
bfsc csl_v,lefthandlight3
goto L1
call lefthandstop
lefthandlight表示光电开关,由此判断是否到相应的位置。1表示在手臂最下面的位置;2表示在手臂的握手位置;3表示在手臂的鼓掌位置;4表示在手臂的高举手位置。上面程序描写左手臂上升到举手位置和右手臂上升到鼓掌位置并停止的过程。先判断左手到达否,到达则左手停止,接着看右手是否到达举手位,到达则停止,否则循环上述的检测,直到左手到达鼓掌位,右手到达举手位。
注意,这里的3,4表示的就是鼓掌位、举手位。经过循环检测可以让手臂停在各位上,然而机械动作是有惯性的,机械停止位可能在该位的上一点或下一点,这就影响下面动作的进行,可能在若干动作后机械动作出现失常,也就是程序没法正常地运行。在此情况下,需要修改程序的编写方式,采用标志位来控制动作的进行。如果采用控制标志位,一定要在动作子函数中对标志位置零。
三、区分GOTO和CALL指令的使用场合
在PIC的汇编程序中,CALL与GOTO指令的使用比较多、且容易混淆,一般情况下,在于程序与主程序之间大多用CALL指令;而状态转换模块之间大多用GOTO指令,即由此状态进入另一种状态不需返回。由于PIC单片机的堆栈有限,在程序中,不能无止境地使用GOTO语句,否则会使堆栈溢出,程序无法正常运行。各个小程序内部循环占用堆栈的级数不多,使用GOTO指令是可行的,但在大的程序中用GOTO则无法返回到调用前程序的下一条指令。CALL指令完成调用完子程序后返回到调用前的程序。如在超声检测中程序如下:
list D=16c76
start:call setcpu
call automaflsmstate1
L3 call readinsignal
bfsc es2_v,ultrasonicdetect1
goto L3
goto automatlsmstate2:
automatlsmstate2:
return
automafismstate1、automatlsmstate2表示两种状态,ultrasonicdetect1表示一个输入超声检测信号。上面程序描写调用automatlstmstatei状态,执行完后进行下面的检测uhrasonicdetect1,没有触发就一直循环检测,触发就进入automatlsmstate2状态,执行完也不再回到下面的程序。
由于PIC单片机的堆栈有限,在程序中不能无止境地使用GOTO指令,否则会使堆栈溢出,程序无法正常运行。但是在有些时候,例如当程序出现分支时,则不得不使用GOTO指令。对于PIC16F7X系列单片机,程序出现分支时只能通过STATUS寄存器的z位或c位进行判断。这时在两种情况的前一种情况下,必须使用GOTO指令进行转移;否则在执行完第一种情况后,紧接着又执行第二种情况。因此,在使用汇编语言进行程序设计时,应该将程序分解成一级级的子程序;然后在程序之间进行调用,尽量将GOTO指令跳转的范围缩小。
四、注意状态标志位Z、C的不同使用情况
在进行判断标志位时,Z(零标志)、C(借位标志)是不同的。Z为1时,表示上面的结果为0,Z为0时,则结果不为0。C为1时,借位,C为0时,没有借位。在使用定时器的时候,一般使用C标志位,这是由于当完成某一动作去检查定时器时,时间可能没到,或是正好,或是已经超过时间,只要到了或超过时间,都要按照要求关闭定时器,如下面程序所述。如果用Z标志位,等于0时可能没有检测到,无法判断停止的状态,而用Z可以很好地控制时间定时。进行一般的计算时大多用Z,如前面的动作标志位中就是如此使用的。
list D=16c76
call openfimer0
L4 movlw d'30'
subwf t0_v2,W
bfsc status,c
goto L4
call dosetimer0
程序检测时间是否到达1.5s,没有则循环等待,到了或检测时间过了就关闭定时器,执行下面的程序。
总之,在PIC单片机的编程中采用合适的方法,可以使整个程序运行稳定,而且程序空间的使用也将有所减小,避免了调试中的Bug。
上一篇:关于PIC单片机之探讨低功耗
史海拾趣
|
现在手机中的射频信号通道越来越拥挤。蜂窝电话已经从双频向三频甚至四频快速发展。这些复杂手机还需要处理来自外围无线设备的各种信号,如蓝牙、Wi-Fi和GPS。而随着WiMAX和LTE(4G)的加入,这种复杂度将越来越高。在移动电话中,天线开关控制着天线 ...… 查看全部问答> |
|
我用这个方法,但是好像获取的大小有问题,不知道这个方法是不是正确的方法,还没有更好的办法? DDCAPS ddcaps; ddcaps.dwSize = sizeof DDCAPS; lpdd ...… 查看全部问答> |
|
大型ARM+linux+android嵌入式技术专题公益讲座 华清远见武汉华嵌中心将于2010年4月24日下午1:00-5:00在武汉大学联手ARM中国公司,开展“基于ARM平台的嵌入式系统设计专题讲座”。 详情请点击: http://www.embedhq.org/html/mianfei/2010/0408/382.html… 查看全部问答> |
|
LPCWSTR strDrvName=L\"\"; strDrvName=TEXT(\"NDS0:\"); HANDLE hHandle; hHandle ...… 查看全部问答> |
|
请问有人做过误码仪吗?最近在做一个误码仪,有个问题卡在那边,问题是要我产生误码,之后就是让我检测误码,码型为NRZ,RZ,AMI,HDB3码,关于NRZ,RZ码我就不知道了,这种码还能判断误码?… 查看全部问答> |
|
128M扩到512M,我用的是uboot+NK.nb0,uboot已经改好ram初始化部分,没有开mmu,在uboot下测试512内存读写正常,wince改了config.bib中ram大小,oemtable也改了内存映射,但是现在内核跑到oeminit跑完就死了,不好调试。试着用oemgetextensiondram( ...… 查看全部问答> |
|
渥瑞达“3G移动开发”免费试听课于北京交通大学举行,欢迎大家光临! 渥瑞达“3G移动开发”免费试听课于北京交通大学举行,欢迎大家光临! 渥瑞达“3G移动开发”免费试听课于北京交通大学举行,欢迎大家光临! 详情请参见 www.neworigin.net 同时欢迎大家与我们的609期学员交流!这期学员已与2月11日毕业 ...… 查看全部问答> |
|
【连载】【ALIENTEK MiniSTM32 开发板】STM32不完全手册-内部温度传感器实验(14) 开发板购买地址:http://shop62103354.taobao.com [ 本帖最后由 正点原子 于 2010-9-7 09:45 编辑 ]… 查看全部问答> |
|
今天在看书时发现一点疑惑,问题大致是这样的: 一个电路网络,要对其中一个2输入与门的输出(定义为tmp吧,其实此处并不存在端口或变量)进行一些赋值操作,。在Verilog编程中按说是应该把其定义为wire型变量,可是今天看的一个例子却定义成了reg ...… 查看全部问答> |




