让找料更便捷
电子元器件
采购信息平台
生意随身带
随时随地找货
一站式电子元器件
采购平台
半导体行业观察第一站
本词条由华强电子网用户提供,如果涉嫌侵权,请与我们客服联系,我们核实后将及时处理。
关键词:
PIC单片机是一个小的计算机PIC单片机有计算功能和记忆内存像CPU并由软件控制允行。然而,处理能力-存储器容量却很有限,这取决于PIC的类型。但是它们的最高操作频率大约都在20MHz左右,存储器容量用做写程序的大约1K-4K字节。时钟频率与扫描程序的时间和执行程序指令的时间有关系。但不能仅以时钟频率来判断程序处理能力,它还随处理装置的体系结构改变(1*)。如果是同样的体系结构,时钟频率较高的处理能力会较强。
PIC单片机系列是美国微芯公司(MiCroShip)的产品,是当前市场份额增长最快的单片机之一。CPU采用RISC结构,分别有33、35、58条指令(视单片机的级别而定),属精简指令集。而51系列有111条指令,AVR单片机有118条指令,都比前者复杂。采用Haryard双总线结构,运行速度快(指令周期约160~200nS),它能使程序存储器的访问和数据存储器的访问并行处理,这种指令流水线结构,在一个周期内完成两部分工作,一是执行指令,二是从程序存储器取出下一条指令,这样总的看来每条指令只需一个周期(个别除外),这也是高效率运行的原因之一。此外,它还具有低工作电压、低功耗、驱动能力强等特点。PIC系列单片机共分三个级别,即基本级、中级、高级。其中又以中级的PICl6F873(A)、PICl6F877(A)用的最多,本文以这两种单片机为例进行说明。这两种芯片除了引出脚不同外(:PICl6F873(A)为28脚的PDIP或SOIC封装PICl6F877(A)为40脚的PDIP或44脚的PICC/QFP封装),其他的差别并不很大。
PIC系列单片机的:I/O口是双向的,其输出电路为CMOS互补推挽输出电路。I/O脚增加了用于设置输入或输出状态的方向寄存器(TRISn,其中n对应各口,如A、B、C、D、E等),从而解决了51系列I/O脚为高电平时同为输入和输出的状态。当置位1时为输入状态,且不管该脚呈高电平或低电平,对外均呈高阻状态;置位0时为输出状态,不管该脚为何种电平,均呈低阻状态,有相当的驱动能力,低电平吸人电流达25mA,高电平输出电流可达20mA。相对于51系列而言,这是一个很大的优点,它可以直接驱动数码管显示且外电路简单。它的A/D为10位,能满足精度要求。具有在线调试及编程(ISP)功能。
该系列单片机的专用寄存器(SFR)并不像51系列那样都集中在一个固定的地址区间内(80~FFH),而是分散在四个地址区间内,即存储体0(Bank0:00-7FH)、存储体1(Bankl:80-FFH)、存储体2(Bank2:100-17FH)、存储体3(Bank3:180-1FFH)。只有5个专用寄存器PCL、STATUS、FSR、PCLATH、INTCON在4个存储体内同时出现。在编程过程中,少不了要与专用寄存器打交道,得反复地选择对应的存储体,也即对状态寄存器STATUS的第6位(RPl)和第5位(RPO)置位或清零。如:
例4:
CLRF STATUS ;清零RPl,RPO。选择存储体O BSF STAUS,RPO;置位RPO。选择存储体1 BCF STATUS,RPO;清零RPO。选择存储体O
这多少给编程带来了一些麻烦。对于上述的单片机,它的位指令操作通常限制在存储体0区间(00~7FH)。
数据的传送和逻辑运算基本上都得通过工作寄存器w(相当于5l系列的累加器A)来进行,而51系列的还可以通过寄存器相互之间直接传送(如:MOV30H,20H;将寄存器20H的内容直接传送至寄存器30H中),因而PIC单片机的瓶颈现象比51系列还要严重,这在编程中很有感受。
据统计,我国的单片机年容量已达1-3亿片,且每年以大约16[%]的速度增长,但相对于世界市场我国的占有率还不到1[%]。这说明单片机应用在我国才刚刚起步,有着广阔的前景。培养单片机应用人才,特别是在工程技术人员中普及单片机知识有着重要的现实意义。
当今单片机厂商琳琅满目,产品性能各异。针对具体情况,我们应选何种型号呢?首先,我们来弄清两个概念:集中指令集(CISC)和精简指令集(RISC)。采用CISC结构的单片机数据线和指令线分时复用,即所谓冯.诺伊曼结构。它的指令丰富,功能较强,但取指令和取数据不能同时进行,速度受限,价格亦高。采用RISC结构的单片机数据线和指令线分离,即所谓哈佛结构。这使得取指令和取数据可同时进行,且由于一般指令线宽于数据线,使其指令较同类CISC单片机指令包含更多的处理信息,执行效率更高,速度亦更快。同时,这种单片机指令多为单字节,程序存储器的空间利用率大大提高,有利于实现超小型化。属于CISC结构的单片机有Intel8051系列、Motorola和M68HC系列、Atmel的AT89系列、台湾Winbond(华邦)W78系列、荷兰Pilips的PCF80C51系列等;属于RISC结构的有Microchip公司的PIC系列、Zilog的Z86系列、Atmel的AT90S系列、韩国三星公司的KS57C系列4位单片机、台湾义隆的EM-78系列等。一般来说,控制关系较简单的小家电,可以采用RISC型单片机;控制关系较复杂的场合,如通讯产品、工业控制系统应采用CISC单片机。不过,RISC单片机的迅速完善,使其佼佼者在控制关系复杂的场合也毫不逊色。
根据程序存储方式的不同,单片机可分为EPROM、OTP(一次可编程)、QTP(掩膜)三种。我国一开始都采用ROMless型单片机(片内无ROM,需片外配EPROM),对单片机的普及起了很大作用,但这种强调接口的单片机无法广泛应用,甚至走入了误区。如单片机的应用一味强调接口,外接I/O及存储器,便失去了单片机的特色。目前单片机大都将程序存储体置于其内,给应用带来了极大的方便。值得一提的是,以往OTP型单片机的价格是QTP的3倍,而现在已降至1.5-1.2倍,选用OTP型以免订货周期、批量的麻烦是可取的。
二、PIC系列单片机有什么优势?
自从我95年接触PIC单片机以来,便一直热衷于这种单片机的开发与应用。有不少朋友问我:PIC到底有什么优势?也许你也会有这样的疑问,所以我在这里略谈几点自己的看法。
1)PIC最大的特点是不搞单纯的功能堆积,而是从实际出发,重视产品的性能与价格比,靠发展多种型号来满足不同层次的应用要求。就实际而言,不同的应用对单片机功能和资源的需求也是不同的。比如,一个摩托车的点火器需要一个I/O较少、RAM及程序存储空间不大、可靠性较高的小型单片机,若采用40脚且功能强大的单片机,投资大不说,使用起来也不方便。PIC系列从低到高有几十个型号,可以满足各种需要。其中,PIC12C508单片机仅有8个引脚,是世界上最小的单片机。
该型号有512字节ROM、25字节RAM、一个8位、一根输入线、5根I/O线,市面售价在3-6元人人民币。这样一款单片机在象摩托车点火器这样的应用无疑是非常适合。PIC的高档型号,如PIC16C74(尚不是最高档型号)有40个引脚,其内部资源为ROM共4K、192字节RAM、8路A/D、3个8位定时器、2个*模块、三个串行口、1个并行口、11个中断源、33个I/O脚。这样一个型号可以和其它品牌的高档型号媲美。
2) 精简指令使其执行效率大为提高。PIC系列8位CMOS单片机具有独特的RISC结构,数据总线和指令总线分离的哈佛总线(Harvard)结构,使指令具有单字长的特性,且允许指令码的位数可多于8位的数据位数,这与传统的采用CISC结构的8位单片机相比,可以达到2:1的代码压缩,速度提高4倍。
3) 产品上市零等待(Zero time to market)。采用PIC的低价OTP型芯片,可使单片机在其应用程序开发完成后立刻使该产品上市。
4) PIC有优越开发环境。OTP单片机开发系统的实时性是一个重要的指标,象普通51单片机的开发系统大都采用高档型号仿真低档型号,其实时性不尽理想。PIC在推出一款新型号的同时推出相应的仿真芯片,所有的开发系统由专用的仿真芯片支持,实时性非常好。就我个人的经验看,还没有出现过仿真结果与实际运行结果不同的情况。
5) 其引脚具有防瞬态能力,通过限流电阻可以接至220V交流电源,可直接与继电器控制电路相连,无须光电耦合器隔离,给应用带来极大方便。
6) 彻底的保密性。PIC以保密熔丝来保护代码,用户在烧入代码后熔断熔丝,别人再也无法读出,除非恢复熔丝。目前,PIC采用熔丝深埋工艺,恢复熔丝的可能性极小。
7) 自带看门狗定时器,可以用来提高程序运行的可靠性。
8) 睡眠和低功耗模式。虽然PIC在这方面已不能与新型的TI-MSP430相比,但在大多数应用场合还是能满足需要的。
PIC单片机采用精简指令集,例如对于PIC16F716单片机,只有35条单字节指令。要用这么少的指令实现复杂的控制或计算,显然要在程序设计上多做文章,以下就程序设计需要注意的问题谈一些看法。 美国微芯公司开发的CMOS工艺PIC系列单片机,特别是采用内置第二代Flash存储器的微控制器在快速应用方面具有独到之处。PIC单片机系列内大都包含运算器、存储器、A/D、PWM、输入和输出I/O、通信等常用接口。自由灵活的定义功能可以适应不同的控制要求。
一、区分指令的大小写
编写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。
美国微芯公司(Microch{p Technology Inc.)开发的CM0S工艺PIC系列8位单片机(RISC微控制器),特别是采用内置第二代Flash存储器(40年存储寿命)的微控制器在快速应用方面具有独到之处。由于其易用性和高可靠性,该系列微控制器稳居8位单片机全球出货量之首。PIC系列单片机具有指令集简洁、简单易学、速度高、功能强、功耗低、价格低廉、体积小巧、适用性好及抗干扰能力强等特点,大量应用于汽车电气控制、电机控制、工业控制仪表和仪表、通信、家电、玩具、低功耗的测控应用等领域,在国内越来越受到广大设计者的欢迎,微芯公司的单片机已经成为目前单片机世界的主流产品。
PIC 8位单片机内已经包含运算器、存储器、A/D、PWM、输入和输出I/O(灌电流可达25mA)、通信等常用接口,自由灵活的定义功能可以适应不同的控制要求。而不必增加额外的IC芯片。这样电路结构很简单,开发周期将大为缩短。
PICl6系列单片机属于PIC8位单片机的中级型产品,采用14位的RISC指令系统。笔者使用PICl6F716单片机设计了一个电动机保护器,在设计过程中遇到很多问题,通过多方查找资料以及向Microchip公司技术人员寻求支持,问题一一得到解决。现将部分问题记录如下,与大家一起探讨。
1 ICD2作为程序烧写的使用
1.1 ICD2简介
MPLAB ICD2在线调试器是一款低价位的PIC开发工具。它利用Flash工艺芯片的程序区自读写功能来实现仿真器调试功能;使用的软件平台是Microchip的MPLAB IDE(集成开发环境软件包),兼容Windows NT、Windows 2000和Windlows XP等操作系统。其通信接口方式可以是USB(最高可达2Mb/s)或RS-232串行接口方式;工作电压范围为2.O~5.5V,可支持最低2.0V的低压调试。
MPLABICD2可以支持大部分Flash工艺的芯片。它不仅可以用作调试器,同时还可以作为开发型的烧写器使用。
1.2 ICD2作为烧写器时的配置
烧写芯片的方式有两种:普通烧写和在线烧写。在线烧写是适合大批量生产方式的烧写办法。使用在线烧写时通常用户都已经把芯片焊到了板上,此时就要求用户板上有预留的烧写接口。用户板上的接口是通过一条6芯的扁平电缆与ICD2主机上同样的接口一一对应连接的。图1显示了MPLAB ICD2与目标板上模块连接插座的互连状况。
ICD连接插座有6个引脚,但只使用了其中的5个引脚,分别是VDD(电源)、VSS(地)、VPP(编程电压)、PGC(同步时钟)和PGD(数据)。
1.3 ICD2作为烧写器时容易出现的问题及解决方法
尽管MPLAG ICD2与目标板的互连非常简单,但是一不小心就会出现问题,基本上每一个PIC的入门者都会碰到类似的问题。下面就一些常见问题作简要叙述。
如图1所示,在VPP与VDD之间通常要串接一个上拉电阻(通常约为10kΩ),这样VPP线可置为低电平来手动复位PICmicro单片机。但是对一般设计者来说,都是采用上电自动复位。如果在这里采用集成器件DMP809,那么就会导致连接不上,程序没有办法烧入。
对于PGC、PGD两根线,由于在ICD2内部已经进行了上拉,所以在外围设计中,不要冉进行上拉,否则会造成分压。对于PGC、PGD和VPP三根线,不要对地接电容.因为电容会阻碍在数据和时钟线上电平的快速转换,从而影响ICD2与目标板的连接。同样对于PGC、PGD,由于数据或时钟都是双向传输的,这时如果在中间串一个二极管,则会影响ICD2与单片机的双向通信。
但是,对PGC和PGD来说,在单片机上同时复用为普通I/O口,而有些使用上必须要接对地电容或者是串接二极管。对于这种情况,唯一的处理方式就是在烧写时从芯片的PGC和PGD端口直接跳线到程序烧写口。
2 A/D转换通道切换问题
笔者所设计的电动机保护器需要进行很多A/D转换,比如三相电流转换、零序电流转换以及各种*等。但是笔者所采用的PIC16F716单片机只有5路A/D转换通道,因此附加了一个多位选择开关对一个A/D通道进行复用。而在调试中发现这样一个问题,就是A/D转换值不准确,甚至有点乱,但从程序流程以及代码角度均查不出任何问题。后查明PICl6F716单片机进行A/D转换通道切换时,需要一定的延时,延时时间是毫秒级。解决办法是:在通道问切换时,当第一个通道转换完成后,先转到另一个通道;然后延时1ms左右,再进行A/D转换。而对同一个通道信号切换时,要在第一个信号转换完成后,禁止信号输入,延时1ms左右;然后输人信号,再进行A/D转换。
这种做法比较麻烦,也很占用时间,并且从调试结果来看,问题并没有解决。在反复进行调试中,最后得到的优化解决办法是:对于通道间转换以及同一通道信号转换,要对每一个信号至少进行两次A/D转换;第一次的转换结果,舍弃不予处理,只取第二次A/D转换的结果。从调试结果来看,很好地解决了这一问题。
3 软件开发小技巧
PIC单片机采用精简指令集,例如对于PICl6F716单片机,只有35条单字节指令。要用这么少的指令实现复杂的控制或计算,显然要在软件设计上多下功夫,并且PIC的指令系统与51系列单片机有很大不同,这让PIC初学者很不适应。下面笔者就自己的体会,谈一些软件设计需要注意的问题。
3.1 指令的大小写问题
编写PIC单片机的源程序,除了源程序的开始处需要严格的列表指令外,还须注意源程序中字母符号的大小写规则,否则在PC机上汇编程序时不会成功。在源程序中都会使用伪指令INCLUDE。这条指令将列表中指定的单片机文件(在MPLAB中)读入源程序作为源程序的一部分,所以凡是MPLAB中有关该单片机已有的寄存器在源程序中无需再用赋值指令(EQU)赋值,这就使所建立的源程序大为简化。
此外,由于有了伪指令INCLUDE,所以根据MPLAB软件中的格式,在源程序中的操作数凡是涉及MPLAB已规定的寄存器名称的,其字母一律只能大写,不能小写。其余操作码、符号字母可任意大小写,但0x中的x应小写。否则汇编不会成功。鉴于上述原因,为了书写方便,在使用MPLAB软件时,PIC单片机的源程序均用大写字母为宜(0x例外)。
3.2 振荡器的配置以及时序的计算
PIC系列单片机可以工作于以下4种不同的振荡器方式:LP(低功耗晶体振荡器)、XT(晶体谐振器)、HS(高速晶体谐振器)和RC(阻容振荡器)。用户可以根据其系统设计的需要,通过对配置位(FOSC1和F0SC2)编程,选择其中一种工作模式。
而一旦振荡器配置完成,那么根据用户的配置,可以轻松地计算出程序运行的时间以及A/D转换所占用的时间,这样就会很轻松地安排好单片机的时序。例如,如果采用4 MHz的HS振荡模式,那么单片机的时钟频率为FOSC/4,也就是说执行一条指令需要1μs;对于需要两个指令周期的指令,需要2μs。而对于A/D转换,如果A/D转换时钟位选择为FOSC/8,那么A/D转换模块转换一个位的时间Tad就为2μs。对一个8位的转换来说,需要的时间为9.5Tad,也就是完成一次A/D转换的时间为19μs。这样只需要查看源程序的行数并作简要分析,就可以计算出程序运行的时间。
3.3 存储体的选择
PIC单片机的数据存储器通常分为两个存储体,即存储体O(Bank0)和存储体1(Bankl)。每个存储体都是由专用寄存器和通用寄存器两部分组成的。两个存储体中的一毡寄存器单元实际上是同一个寄存器单元,却又具有不同的地址。
不同型号的PIC单片机,其数据存储器的组成(即功能)是不完全相同的,所以设计人员一旦选用了某个PIC单片机的型号后,就要查找该单片机的数据存储器资料,以便编程使用。
笔者所采用的PICl6F716单片机的存储区,是通过STATUS寄存器的RPl位和RP0位来选择的。当配置为00时,表示选择存储区0;当配置为01时,表示选择存储区1。因为存储区的改变只须改变RP0位,所以通常在程序编写时,只改变RP0位来选择存储区。但是这样容易造成程序的混乱,因此,笔者建议在每次更换存储区时,要分别对RPO和RPl进行置位。在程序初始化时,最好将寄存器的初始化分为两部分:第一部分为存储区O;第二部分为存储区1。然后将每个需要初始化的寄存器分别在对应的存储区进行初始化即可。
3.4 GOTO和CALL指令的不同使用
在PIC的汇编程序中,CALL与GOT0指令使用的场台不同。CALL是用来调用子程序的,在调用完子程序后返回到调用前的程序;而GOTO是无条件转移,即由此状态进入另外一个状态而不需要返回。
为了使程序更加具有可读性,使流程更加清晰、合理,通常程序都采用模块化程序设计,即将程序按照功能分成不同的子程序,而主程序则相当简洁,只须采用CALL指令对子程序进行调用。
由于PIC单片机的堆栈有限,在程序中不能无止境地使用GOTO指令,否则会使堆栈溢出,程序无法正常运行。但是在有些时候,例如当程序出现分支时,则不得不使用GOTO指令。对于PICl6F7x系列单片机,程序出现分支时只能通过STATUS寄存器的Z位或C位进行判断。这时在两种情况的前一种情况下,必须使用GOTO指令进行转移;否则在执行完第一种情况后,紧接着又执行第二种情况。程序如下:
BTFSS STATUS,Z
GOTO A
GOTO B
在跳转到A时,必须使用GOTO指令;否则执行完这条语句以后,紧接着执行GOTO B。这样无论Z为何值,程序都将跳转到B。而对于GOT0 B,则可以不必使用GOTO指令。
在上面这种情况下,由于GOTO只在子程序内部进行跳转,小程序内部循环占用堆栈的级数不多,因此使用GOTO指令是可行的。但是在大的程序中使用GOTO指令,将有可能无法返回到调用前的下一条指令。
因此,笔者建议,在使用汇编语言进行程序设计时,应该将程序分解成一级级的子程序;然后在程序之间进行调用,尽量将GOTO指令跳转的范围缩小。
3.5 对芯片的重复烧写
对没有硬件仿真器的设计者来说,总是选用带有EPROM的芯片来调试程序,通过反复的修改来观看运行结果,以便对程序进行调试。每更改一次程序.都是将原来的内容先擦除,再编程,浪费了相当多的时间,又缩短了芯片的使用寿命。如果后一次编程较前一次,仅是对应的机器码字节的相同位由1变为0,那么就可在前一次编程芯片上再次写入数据,而不必擦除原片内容。
在程序调试
过程中,经常遇到常数的调整。如果常数的改变能保证对应位由1变0,则都可在原片内容的基础上继续编程。另外,由于指令NOP对应的机器码为00,调试过程中指令的删除,可先用NOP指令替代,编译后也可在原片内容上继续编程。
结语
在采用PIC单片机进行设计过程中,注意到PIC单片机自身的特点,可尽量少走弯路,从而缩短开发周期。同样在软件设计上采用合适的方法,可以使整个程序运行稳定,而且程序空间的使用也将有所减少,避免了调试中的Bug。以上只是笔者在实际设计过程中一些小小的体会。希望与大家一起探讨,并在共同学习中为PIC单片机的普及和推广做出贡献。
PIC16F877单片机配置了两个CCP(捕捉/比较/脉宽调制)模块,即CCP1和CCP2。它们各白都有独立的16位寄存器CCPR1和CCPR2。两个模块的结构、功能、操作方法基本一样,区别仅在于它们各自有独立的外部引脚和特殊事件触发器。CCP模块的功能包括外部信号捕捉、内部比较输出以及PWM输出,它往往与定时器/计数器配合使用。
CCP模块可工作在3种模式下:捕捉方式、比较方式和脉宽调制方式。
· 捕捉方式是指检测引脚上输入信号的状态,当信号的状态符合设定的条件时(信号上升沿或下降沿出现时)产生中断,并记录当时的定时器/计数器值,当CCP模块工作在捕捉方式时,TMR1控制寄存器必须工作在定时器或同步计数方式下。
· 比较方式是指将事先设定好的值与定时器方式或同步计数方式下的值相互比较,当两个值相等时,产生中断并驱动事先设定好的动作。
· 脉宽调制功能适用于从引脚上输出脉冲宽度随时可调的PWM信号,来实玑直流电机的调速、D/A转换和步进电机的步进控制。
本设计应用PIC16F877单片机的CCP模块的捕获工作方式进行频率计的设计,具体设计要求如下。
测量对象为100~1000Hz的TTL电平信号,待测量的参数有:
· 频率,测量误差小于0.1%;
· 周期,测量误差小于0.1%;
· 脉冲宽度(高电平持续时间),脉冲宽度大于100μs,测量误差小于1%;
· 占空比,占空比的变化范围为10%~90%,测量误差小于1%。
频率计的设计原理如下。
在t1时刻之前把CCP1设置为捕捉脉冲上升沿。当信号上升沿到来时,产生CCP中断,在中断服务程序中捕捉该时刻TMR1寄存器中16位的值time1,将CCP1设置为捕捉脉冲的下降沿。
当该信号下降沿到来时,产生CPP中断,在中断服务程序中捕捉该时刻TMR1寄存器中16位的值time2,而后再把CCP1设置为捕捉脉冲的上升沿。
当信号的下一个上升沿来到时,又产生CCP中断,在中断服务程序中捕捉此刻TMR1寄存器中的16位的值time3,则信号的周期T=(time3-time1)μS,信号频率f=1/T,脉冲宽度P=(time2-time1)μS,占空比D=P/T×100%。
考虑到CCP捕捉方式可能发生的最大误差为±1μs,为满足误差要求,可把上述过程多进行几次,将各次测试的平均值作为最后的测量值。
图 频率计设计原理示意图
如果需要测量的最高频率为1000Hz,周期只有1000μs,且占空比的变化范围为10%~90%,则高低电平持续的最短时间都为100μs,可以有充分的时间执行中断服务程序。
如果实际应用中发现两次捕捉中断的时间间隔小于1次中断服务时间,则可以通过适当设置寄存器CCPICON的值,使CCP模块每4个脉冲上升沿捕捉1次或每16个脉冲上升沿捕捉一次,这样两次中断的时间间隔就增大了。如果还不能达到要求,则可用分频器对输入频率信号分频处理后,再由CCP1引脚输入。