资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,/50,增强型,8051,单片机实用开发技术,第,7,章 定时,/,计数器,7.1 STC12C5A60S2,单片机的定时,/,计数器,7.3,STC12C5A,60S2,单片机,的PCA模块,7.2 STC12C5A60S2,单片机的,可编程时钟输出,在计算机控制中可供选择的定时方法,(,1,)软件定时,执行一个循环程序来实现。,(,2,)硬件定时,定时全部由硬件电路完成,不占用,CPU,时间,但需要通过改变电路的元件参数来调节定时时间,在使用控制上不够方便,同时增加了开发成本。,(,3,)可编程定时器定时,由单片机内部的定时模块单元完成。,STC12C5A60S2,单片机内部有,:,1,)两个,16,位的定时,/,计数器,不仅可以方便地用于定时控制,而且还可以用作分频器和用于事件记录;,2,)可编程时钟输出功能,可用于给外部器件提供时钟;,3,)两路可编程计数器阵列(,Programmable Counter Array,,,PCA,)。可用于软件定时器、外部脉冲的捕捉、高速输出以及脉宽调制(,Pulse Width Modulation,,,PWM,)输出。,7.1 STC12C5A60S2,单片机的定时,/,计数器,7.1.1,定时,/,计数器的结构及工作原理,定时,/,计数器的核心是一个加,1,计数器,加,1,计数器的脉冲有两个来源,一个是外部脉冲源,另一个是系统的时钟振荡器。计数器对两个脉冲源之一进行输入计数,每输入一个脉冲,计数值加,1,。当计数到计数器为全,1,时,再输入一个脉冲就使计数值回零,同时从最高位溢出一个脉冲使特殊功能寄存器,TCON,(定时器控制寄存器)的某一位,TF0,或,TF1,置,1,,作为计数器的溢出中断标志。,单片机中的微处理器、寄存器,TCON,和,TMOD,与定时,/,计数器,T0,、,T1,之间的关系,7.1.2,定时/计数器,的相关,寄存器,1,、定时器工作方式控制寄存器,TMOD,(地址为89H,复位值为00H),M0,M1,C/T,GATE,M0,M1,C/T,GATE,定时器,0,定时器,1,定时器,D0,D1,D2,D3,D4,D5,D6,D7,位号,M1 M0,工作方式,功能说明,0 0,0,13,位计数器,0 1,1,16,位计数器,1 0,2,可自动装入的,8,位计数器,1 1,3,定时器,0,:分成两个,8,位计数器,定时器,1,:停止计数,1,),M1,和,M0,:方式选择控制位。,2,),C/,:功能选择位。,用于“计数器”或“定时器”功能的选择。,3,),GATE,:门控位。,GATE,用于选通控制。,位名称,2,、定时器控制寄存器,TCON,(地址为,88H,,复位值为,00H,),1,),TF1,:定时器,/,计数器,1,溢出标志位。,2,),TR1,:定时器,T1,的运行控制位。,3,),TF0,:定时器,/,计数器,0,溢出标志位。,4,),TR0,:定时器,T0,的,运行,控制位。,TCON,的,0,3,位与外部中断有关。,IT0,IE0,IT1,IE1,TR0,TF0,TR1,TF1,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,3,、,AUXR,:辅助寄存器(地址为,8EH,,复位值为,00H,),-,-,ELVDI,ESPI,EADCI,UART_M0 x6,T1x12,T0 x12,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,与定时器速度相关的控制位有,:,1)T0 x12:定时器0速度控制位。,0:定时器0的速度是传统8051单片机定时器的速度,即12分频。,1:定时器0的速度是传统8051单片机定时器速度的12倍,即不分频。,2)T1x12:定时器1速度控制位。,0:定时器1的速度是传统8051单片机定时器的速度,即12分频。,1:定时器1的速度是传统8051单片机定时器速度的12倍,即不分频。,如果UART串口用T1作为波特率发生器,T1x12位决定UART串口是12T 还是1T。,UART_M0 x6、BRTR、S2SMOD、BRTx12和S1BRS用于控制UART串口的速度。EXTRAM用于设置是否允许使用内部1024字节的扩展RAM。,7.1.3,定时,/,计数器的工作方式,方式,0,和方式,1,方式,2,方式,3,当工作于定时状态时,定时,/,计数器是对时钟周期进行计数,若对时钟进行,12,分频,则对每,12,个时钟周期计数。当晶振频率为,6MH,z,,采用,12,分频时,计数的单位时间间隔为,单位时间间隔,T,u,=,定时时间为:,T,C,=,XT,u,。其中,,T,u,为单位时间间隔,,T,C,为定时时间。,7.1.4,定时,/,计数器量程的扩展,STC12C5A60S2,单片机中提供的定时,/,计数器可以使用户很方便地实现定时和对外部事件计数。但是在实际应用中,需要的定时时间或计数值可能超过定时,/,计数器的定时或计数能力,特别是当单片机的系统时钟频率较高时,定时能力就更为有限。为了满足需要,有时需要对单片机的定时计数能力进行扩展。定时能力和计数能力扩展的方法相同,在此主要对定时能力的扩展进行讨论,计数能力的扩展可参考定时能力扩展的方法进行。,s=2s,STC12C5A60S2,单片机的定时器,/,计数器,0,或,1,是对脉冲进行不断加,1,进行计数的,因此,不能直接将实际的计数值作为计数初值送入计数寄存器,THX,、,TLX,中,而必须将实际计数值以,2,8,、,2,13,、,2,16,为模求补,以补码作为计数初值设置,THX,和,TLX,。即应装入计数,/,定时器的初值为:,n,=8,13,或,16,=,系统时钟频率为,6MHz,进行,12,分频,时,定时器的最大定时能力,T,(,2,16,0,),2s,131072s,131.072ms,16,T,(,2,13,0,),2s,16384s,16.384ms,13,T,(,2,8,0,),2s,512s,8,最大定时能力,位数,扩展方法:,(,1,)软件扩展方法,扩展方法是在定时器中断服务程序中对定时器中断请求进行计数,当中断请求的次数达到要求的值时才进行相应的处理。,例如,某事件的处理周期为,1s,,但由于受到最大定时时间的限制,无法一次完成定时,此时可以将定时器的定时时间设为以,10ms,为一个单位,启动定时器后的每一次定时器溢出中断产生,10ms,的定时,进入中断服务程序后,对定时器的中断次数进行统计,每,100,次定时器溢出中断进行一次事件的处理,然后再以同样的方式进入下一个周期的事件处理。,(,2,)硬件扩展方法,硬件扩展方法可以使用外接通用定时器芯片对单片机的定时能力进行扩展,如使用定时,/,计数器芯片,8253,,也可以利用单片机自身的资源对定时能力进行扩展。,由于单片机的定时器没有对外输出引脚,所以两个,16,位的定时,/,计数器不能直接连在一起,可以通过单片机的端口,P0,P3,实现连接。下图给出了一种具体的连接方法。,1,),T0,设置为,16,位定时器方式,当,T0,溢出时,执行,T0,的中断服务程序。在,T0,的中断服务程序中将,P1.0,取反。这样在,P1.0,将输出一个方波,其周期为,T0,定时时间的,2,倍。设,T0,的定时时间为,TIME,,则由,P1.0,输出的方波的周期为,2TIME,。,2,),T1,设置为,16,位计数器方式,将,P1.0,输出的方波接到,T1,的定时器外部输入端,T1,(,P3.5,),作为定时,/,计数器,1,的外部计数脉冲,其每个周期的下降沿使,T1,加,1,。设计数器,T1,的计数脉冲数为,COUNT,,则当,T1,溢出时,总定时时间,T,为:,T=2TIMECOUNT,。,7.1.5,定时,/,计数器编程举例,定时,/,计数器的应用编程主要有两点:一是能正确初始化,包括写入控制字,进行时间常数的计算并装入;二是中断服务程序的编写,即在中断服务程序中编写实现定时完成的任务代码。一般情况下,定时,/,计数器初始化部分的步骤大致如下:,(,1,)设置工作方式,将控制字写入,TMOD,寄存器。,(,2,)设置分频方式,将控制字写入,AUXR,寄存器。默认的情况是,12,分频(兼容传统,8051,单片机),因此,如果使用传统,8051,单片机模式,可以不进行设置。,(,3,)把定时,/,计数初值装入,TLX,、,THX,寄存器。,(,4,)置位,ETX,允许定时,/,计数器中断(如果需要)。,(,5,)置位,EA,使,CPU,开放中断。,(,6,)置位,TRX,以启动定时,/,计数。,【,例,7-1】,设系统时钟频率为,6MHz,,利用定时器,T0,定时,每隔,1s,将,P2.0,的状态取反。,思路:,将定时器的定时时间设为,50ms,,在中断服务程序中对定时器,溢出中断请求进行计数,当计够,20,次时,将,P2.0,的状态取反,否则直接返回主程序。,选择定时器,T0,的工作方式:软件启动、定时方式、,16,位定时器,方式字为,01H,。由于系统时钟频率为,6MHz,,,12,分频时,计数单位为,2s,。定时器,T0,的装入初值为,汇编语言程序代码如下:,$INCLUDE (STC12C5A.INC);,包含,STC12C5A60S2,寄存器定义文件,ORG0000H,LJMP MAIN ;,转主程序,ORG000BH;T0,中断服务程序入口地址,LJMPT0_ISR,ORG 0100H,MAIN:MOV SP,#60H ;,设置堆栈指针,MOV TMOD,#01H ;T0,初始化,MOV TL0,#58H,MOV TH0,#9EH,MOV A,#20 ;,累加器,A,置,20,SETB ET0 ;,允外,T0,中断,SETB EA;CPU,开中断,SETB TR0 ;,启动,T0,计数,SJMP$;,等待,T0_ISR:MOV TL0,#58H,MOV TH0,#9EH;,重新装入时间常数,DEC A ;,累加器,A,内容减,1,JNZEXIT,CPL P2.0,MOV A,#20 ;,累加器,A,重载,20,EXIT:RETI,END,对应的,C,语言程序如下:,#include“stc12c5a.h”/包含STC12C5A60S2的寄存器定义文件,sbit,P20=P20;/声明P2.0的引脚位变量,unsigned char i;/声明计数变量。在C语言程序中,尽量不要使用ACC,void main(void),/SP=0 x60;/使用C语言设计程序时,可以不设置堆栈指针,TMOD=0 x01;,TL0=0 x58;,TH0=0 x9E;,i=20;/,计数变量赋初值,ET0=1;/允许T0中断,EA=1;/,开放总的中断,TR0=1;/启动T0计数,while(1);/,等待中断,void T0_ISR(void)interrupt 1 /定时器T0中断函数,TL0=0 x58;/,重新装入时间常数,TH0=0 x9E;,i-;/计数变量减1,if(i,=0)/若减到0,则将P2.0取反,P20=!P20;,/将P2.0取反,i=20;/,重新给计数变量赋值,解:以,T0,为例,下面列出实现这一方法的关键代码,完整的程序,请读者自行编写。,MOV TMOD,#09H ;T0,初始化,,T0,工作于方式,1,、定时、,GATE,置,1,MOV TL0,#00H,MOV TH0,#00H,JNB P3.2,$;,等待升高,SETB TR0,JB P3.2,$;,等待下降,CLR TR0 ;,关,T0,MOV A,TL0 ;T0,内容高,8,位送,B,,低,8,位送,A,MOV B,TH0,;,计算脉宽或送显示器显示,【,例,7-2】,利用定时器的门控方式可以实现正脉冲的脉宽测量。,当,GATE=1,,,TRX=1,,只有,/INTX,引脚输入高电平时,,TX,才被允许计数,利用这一特点,可测量,/INTX,引脚上正脉冲的宽度,如下图所示。,注意教材上的思考问题!,定时/计数器应用中应注意的问题,(1),定时,/,计数器的实时性,大多数应用场合可忽略不计,但对某些要求实时性苛刻的场合,应采用补偿措施。,(2),动态读取运行中的计数值,在动态读取运行中的定时,/,计数器的计数值时,如果不加注意,就可能出错。这是因为不可能在同一时刻同时读取,THX,和,TLX,中的计数值。,一种可避免读错的方法是:先读,THX,,后读,TLX,,重读,THX,,将两次读得的,THX,进行比较;若两次读得的值相等,则可确定读的值是正确的,否则重复上述过程,重复读得的值一般不会再错。,7.2,STC12C5A,60S2,单片机的可编程时钟输出,STC12C5A60S2,单片机提供了,3,路可编程时钟输出功能。,7.2.1,可编程时钟输出的相关寄存器,1,、掉电唤醒寄存器,WAKE_CLKO,(地址为,8FH,,复位值为,00000000B,),T0CLKO,T1CLKO,BRTCLKO,LVD_WAKE,T1_PIN_IE,T1_PIN_IE,RXD_PIN_IE,PCAWAKEUP,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,1,),BRTCLKO,:是否允许,P1.0,(,CLKOUT2,)脚输出时钟。,0,:不允许,BRT,在,P1.0,(,CLKOUT2,)脚输出时钟。,1,:允许,P1.0,(,CLKOUT2,)脚输出时钟,输出时钟频率,=BRT,溢出率,/2,2,),T1CLKO,:是否允许,T1,(,P3.5,)脚输出溢出脉冲。,0,:不允许,T1,(,P3.5,)脚输出溢出脉冲。,1,:允许,T1,(,P3.5,)脚输出溢出脉冲,输出时钟频率,=T1,溢出率,/2,3,),T0CLKO,:是否允许,T0,(,P3.4,)脚输出溢出脉冲。,0,:不允许,T0,(,P3.4,)脚输出溢出脉冲。,1,:允许,T0,(,P3.4,)脚输出溢出脉冲,输出时钟频率,=T0,溢出率,/2,2,、辅助寄存器,AUXR,(地址为,8EH,,复位值为,00H,),S1BRS,EXTRAM,BRTx12,S2SMOD,BRTR,UART_M0 x6,T1x12,T0 x12,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,其中,与,CLKOUT2/P1.0,时钟输出有关的位有:,1,),BRTx12,:,CLKOUT2/P1.0,的时钟输出频率控制位。,0,:独立波特率发生器工作在,12T,模式。,CLKOUT2,工作在,12T,模式时的输出频率,CLKOUT2=(Fosc/2)/12/(256-BRT),1,:独立波特率发生器工作在,1T,模式。,CLKOUT2,工作在,1T,模式时的输出频率,CLKOUT2=(Fosc/2)/(256-BRT),2,),BRTR,:独立波特率发生器运行控制位。,0,:不允许独立波特率发生器运行。,1,:允许独立波特率发生器运行。,如果需要从,CLKOUT2/P1.0,脚输出时钟,需要在用户程序中进行下面的设置:,1,)对,BRT,寄存器送,8,位重装载值(使用“,BRT=#,reload_data,;”语句);,2,)对,AUXR,寄存器中的,BRTR,位置,1,,让独立波特率发生器运行;,3,)对,WAKE_CLKO,寄存器中的,BRTCLKO,位置,1,,让独立波特率发生器的溢出在,P1.0,口输出时钟。,7.2.2,可编程时钟输出的编程实例,【,例,7-3】,设时钟频率,Fosc,=18.432MHz,,设计程序,从,P1.0/CLKOUT2,引脚输出频率为,124.540KHz,的时钟;从,T0,(,P3.4,)引脚输出频率为,125KHz,的时钟;从,T1,(,P3.5,)引脚输出频率为,38.4KHz,的时钟。,解:使用,STC12C5A60S2,的可编程时钟输出功能完成所需要求。在下面的程序设计中(在此只给出,C,语言程序),,T0,、,T1,和独立波特率发生器,BRT,均工作在,1T,模式。,程序编制如下:,#include stc12c5a.h /,包含,STC12C5A60S2,的寄存器定义头文件,void,main(void,),TMOD=0 x22;/T0,和,T1,工作在方式,2,,,8,位自动重装计数器,AUXR=,AUXR,|0 x80;/T0,工作在,1T,模式,AUXR=,AUXR,|0 x40;/T1,工作在,1T,模式,AUXR=,AUXR,|0 x04;/,独立波特率发生器工作在,1T,模式,/,设置,BRT,的,8,位自动重装计数初值,输出时钟频率,124.540KHz,BRT=(256-74);,/,设置,T0,的,8,位自动重装计数初值,输出频率,18432000/2/74=124540.54,约为,125KHz,TH0=(256-74);,/,设置,T1,的,8,位自动重装计数初值,输出时钟频率,18432000/2/240=38400Hz,TH1=(256-240);,WAKE_CLKO=WAKE_CLKO|0 x07;/,允许,T0,T1,独立波特率发生器输出时钟,TR0=1,;,/,启动,T0,开始计数,对系统时钟进行分频输出,TR1=1,;,/,启动,T1,开始计数,对系统时钟进行分频输出,AUXR=AUXR|0 x10;/,启动,BRT,工作,对系统时钟进行分频输出,/,至此时钟已经输出,用户可以通过示波器观看到输出的时钟频率,while(1);,7.3,STC12C5A60S2的可编程计数器阵列模块,7.3.1,PCA模块的结构,PCA/PWM,含有一个特殊的,16,位定时器,有,2,个,16,位的捕获,/,比较模块与之相连。,模块,0,连接到,P1.3/CCP0,(可以通过,AUXR1,寄存器设置切换到,P4.2/CCP0/MISO,口),模块,1,连接到,P1.4/CCP1,(可以通过,AUXR1,寄存器设置切换到,P4.3/CCP1/SCLK,口)。每个模块可编程工作在,4,种模式:上升,/,下降沿捕获、软件定时器、高速输出或可调制脉冲输出。,16,位,PCA,定时器,/,计数器的结构,寄存器,CH,和,CL,的内容是自动递增计数的,16,位,PCA,定时器的值。,PCA,定时器的时钟源有以下几种:,1/12,振荡频率、,1/8,振荡频率、,1/6,振荡频率、,1/4,振荡频率、,1/2,振荡频率、振荡频率、定时器,0,溢出或,ECI,脚的输入(,P1.2,)。定时器的计数源可通过设置特殊功能寄存器,CMOD,的,CPS2,、,CPS1,和,CPS0,位选择其中一种。,CMOD,中的,CIDL,位用于控制空闲模式下是否允许停止,PCA,;,CMOD,中的,ECF,位用于中断控制,置位时,使能,PCA,中断。当,PCA,定时器溢出时,,PCA,计数溢出标志,CF,置位。,CCON,中的,CR,位是,PCA,的运行控制位。,CR=1,时,运行,PCA,。,CR=0,时,关闭,PCA,。,CCON,中还包括,PCA,定时器标志(,CF,)以及各个模块的标志(,CCF1/CCF0,)。当,PCA,计数器溢出时,,CF,位置位,如果,CMOD,寄存器的,ECF,位置位,就产生中断。,CF,位只能通过软件清除。,CCON,寄存器中的,CCF0,是,PCA,模块,0,的标志,,CCF1,是模块,1,的标志。当发生匹配或比较时由硬件置位。这些标志也只能通过软件清除。所有模块共用一个中断向量,可以在中断服务程序中判断,CCF0,和,CCF1,,以确定到底是哪个模块产生了中断。,7.3.2,PCA/PWM模块的特殊功能寄存器,1,、,PCA,工作模式寄存器,CMOD,(地址为,D9H,,复位值为,0XXX0000B,),ECF,CPS0,CPS1,CPS2,-,-,-,CIDL,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,1,),CIDL,:,空闲模式下是否停止,PCA,计数的控制位。,CIDL=0,时,空闲模式下,PCA,计数器继续计数。,CIDL=1,时,空闲模式下,PCA,计数器停止计数。,2,),CPS2,、,CPS1,、,CPS0,:,PCA,计数脉冲源选择控制位。,PCA,计数脉冲选择如表,7-3,所示,(,见教材,),。,3,),ECF,:,PCA,计数器溢出中断使能位。,ECF=1,时,允许寄存器,CCON,中,CF,位的中断。,ECF=0,时,禁止寄存器,CCON,中,CF,位的中断。,2,、,PCA,控制寄存器,CCON,(地址为,D8H,,复位值为,00XXXX00B,),CCF0,CCF1,-,-,-,-,CR,CF,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,1,),CF,:,PCA,计数器溢出标志位。当,PCA,计数器溢出时,,CF,位由硬件置位。如果,CMOD,寄存器的,ECF,位置位,,CF,标志可用来产生中断。,CF,位可通过硬件或软件置位,但只能通过软件清零。,2,),CR,:,PCA,计数器的运行控制位。通过软件置位,CR,位时,启动,PCA,计数器计数;清零,CR,位时,关闭,PCA,计数器。,3,),CCF1/CCF0,:,PCA,各个模块的标志(,CCF0,对应模块,0,,,CCF1,对应模块,1,)。当发生匹配或比较时由硬件置位相应的标志位。这些标志只能通过软件清除。,3,、,PCA,比较,/,捕获工作模式寄存器,CCAPMn,(,n=0,,,1,,下同。地址分别对应,DAH,和,DBH,,复位值均为,X0000000B,),1)ECOMn:,允许比较器功能控制位。ECOMn=1时,允许比较器功能。,2)CAPPn:,正捕获控制位。CAPPn=1时,允许上升沿捕获。,3)CAPNn:,负捕获控制位。CAPNn=1时,允许下降沿捕获。,4)MATn:,匹配控制位。,当MATn,=1时,PCA计数值与模块的比较/捕获寄存器的值匹配时,将置位CCON寄存器的中断标志位CCFn。,5)TOGn:,翻转控制位。,当TOGn,=1时,工作于PCA高速输出模式,PCA计数器的值与模块的比较/捕获寄存器的值匹配时,将使CEXn脚(CEX0/P3.7,CEX1/P3.5,CEX2/P2.0,CEX3/P2.4),翻转,。,6)PWMn:,脉宽调制模式。当PWMn=1时,CEXn脚用作脉宽调制输出。,7)ECCFn:,使能CCFn中断。使能寄存器CCON的比较/捕获标志CCFn,用来产生中断。,位名称,ECCFn,PWMn,TOGn,MATn,CAPNn,CAPPn,ECOMn,-,位号,D0,D1,D2,D3,D4,D5,D6,D7,PCA,模块的工作模式设定,16,位高速输出,4DH,X,0,1,1,0,0,1,16,位软件定时器,49H,X,0,0,1,0,0,1,16,位捕获模式,由,CEXn,的跳变触发,31H,X,0,0,0,1,1,X,16,位捕获模式,由,CEXn,的下降沿触发,11H,X,0,0,0,1,0,X,16,位捕获模式,由,CEXn,的上升沿触发,21H,X,0,0,0,0,1,X,8,位,PWM,输出,由低变高或者由高变低均可产生中断,73H,1,1,0,0,1,1,1,8,位,PWM,输出,由高变低可产生中断,53H,1,1,0,0,1,0,1,8,位,PWM,输出,由低变高可产生中断,63H,1,1,0,0,0,1,1,8,位,PWM,,无中断,42H,0,1,0,0,0,0,1,无此操作,00H,0,0,0,0,0,0,0,模块功能,可设数值,ECCFn,PWMn,TOGn,MATn,CAPNn,CAPPn,ECOMn,4,、,PCA/PWM,模块寄存器,PCA_PWMn,(,n=0,、,1,,分别对应模块,0,和模块,1,,地址分别为,F2H,和,F3H,,复位值均为,XXXXXX00B,),1,),EPCnH,:,在,PWM,模式下,与,CCAPnH,组成,9,位数。,2,),EPCnL,:,在,PWM,模式下,与,CCAPnL,组成,9,位数。,5,、,PCA,的,16,计数器低,8,位,CL,和高,8,位,CH,。它们用于保存,PCA,的装载值。,6,、,PCA,捕捉,/,比较寄存器,CCAPnL,(低位字节)和,CCAPnH,(高位字节),用于保存各个模块的捕捉计数值。,EPCnL,EPCnH,-,-,-,-,-,-,位名称,D0,D1,D2,D3,D4,D5,D6,D7,位号,7.3.3,PCA/PWM模块的工作模式,1,、,捕获模式,2,、,16位软件定时器模式,3,、高速输出模式,4,、脉宽调节模式,开漏,开漏,PWM,无效,仅为输入,/,高阻,强推挽输出,/,强上拉输出,要加输出限流电阻,1K-10K,强推挽输出,/,强上拉输出,强推挽输出,/,强上拉输出,要加输出限流电阻,1K-10K,弱上拉,/,准双向口,PWM,输出时的状态,PWM,之前的状态,I/O,口作为,PWM,使用时的状态,7.3.4,PCA/PWM模块的应用,(,1,)设置,PCA,模块的工作方式,将控制字写入,CMOD,、,CCON,和,CCAPMn,寄存器。,(,2,)设置捕捉寄存器,CCAPnL,(低位字节)和,CCAPnH,(高位字节)初值。,(,3,)根据需要,开放,PCA,中断,将,ECF/ECCF0/ECCF1,需要置,1,的置,1,,并将,EA,置,1,。,(,4,)启动,PCA,计数器(,CH,,,CL,)计数(使,CR=1,)。,【,例,7-4】,利用PCA模块扩展外部中断。将P1.3(PCA模块0的外部输入)扩展为下降沿触发的外部中断,将P1.4(PCA模块1的外部输入)扩展为上升沿/下降沿都可触发的外部中断。当P1.3出现下降沿时产生中断,对 P1.5 取反;当P1.4出现下降沿或上升沿时都产生中断,对P1.6取反。(P1.5和P1.6可连接LED指示灯指示状态。),解:当,PCA,模块工作在捕获模式时,对外部输入,CEXn,的跳变进行采样。当采样到有效跳变时,,PCA,硬件将,PCA,计数器阵列寄存器(,CH,和,CL,)的值装载到捕获寄存器(,CCAPnH,和,CCAPnL,)中。如果,CCON,中的,CCFn,位和,CCAPMn,中的,ECCFn,位被置位,将产生中断。由此,可以将,PCA,模块作为扩展外部中断使用。按照要求,设置控制字时,,PCA,模块,0,应设为下降沿捕获(即,CAPP0=0,并且,CAPN0=1,),,PCA,模块,1,应设为上升沿和下降沿都能捕获的方式(即,CAPP1=1,并且,CAPN1=1,)。,汇编语言程序清单如下:,$INCLUDE(STC12C5A.INC);包含STC12C5A60S2寄存器定义文件,LED_PCA0 EQU P1.5,LED_PCA1 EQU P1.6,ORG 0000H,LJMP MAIN ;,转主程序,ORG 003BH;PCA中断,LJMP PCA_ISR,ORG 0050H,MAIN:MOV SP,#70H,;,初始化,PCA,MOV CMOD,#10000000B;空闲模式下停止PCA计数器工作,;PCA时钟源为FOSC/12,禁止PCA计数器溢出时中断,MOV CCON,#00H ;,清零,PCA计数器溢出中断请求标志位CF,;CR=0,不允许PCA计数器计数;清零,PCA各模块中断请求标志位CCFn,MOV CL,#00H,;清零PCA计数器,MOV CH,#00H,MOV CCAPM0,#11H ;设置PCA模块0下降沿触发捕捉功能,ECCF0=1,MOV CCAPM1,#31H ;模块1上升/下降沿均可触发捕捉功能,ECCF1=1,SETB EA ;,开整个单片机所有中断共享的总中断控制位,SETB CR ;启动PCA计数器(CH,CL)计数,SJMP$;,循环等待中断,;-PCA中断服务程序-,PCA_ISR:,JNB CCF0,Not_PCA0 ;如果CCF0不等于1,则不是PCA模块0中断,;直接去判是否是PCA模块1中断,;PCA模块0中断服务程序,CPL LED_PCA0 ;LED_PCA0取反,表示PCA模块0发生了一次中断,CLR CCF0 ;清PCA模块0中断标志,Not_PCA0:,JNB CCF1,PCA_Exit,;CCF1不等于1,不是PCA模块1中断,直接退出,;PCA模块1中断服务程序,CPL LED_PCA1 ;LED_PCA1取反,表示PCA模块1发生了一次中断,CLR CCF1,;清PCA模块1中断标志,PCA_Exit,:,RETI,END,C,语言版本的程序如下:,#include“stc12c5a.h”/包含STC12C5A60S2寄存器定义文件,sbit,LED_PCA0=P15;,sbit,LED_PCA1=P16;,void main(void),CMOD=0 x80;/空闲模式下停止PCA,计数器工作,/PCA 时钟源为FOSC/12,禁止PCA,计数器溢出时中断,CCON=0;/,清零,PCA计数器溢出中断请求标志位CF,/CR=0,不允许PCA计数器计数;PCA各模块中断请求标志位CCFn清零,CL=0;/PCA,计数器清零,CH=0;,CCAPM0=0 x11;/设置PCA模块0下降沿触发捕捉功能,CCAPM1=0 x31;/设置PCA模块1上升/下降沿均可触发捕捉功能,EA=1;/,开整个单片机所有中断共享的总中断控制位,CR=1;/,启动,PCA 计数器(CH,CL)计数,while(1);,/,等待中断,void,PCA_ISR(void,)interrupt 7 /PCA中断服务程序,if(CCF0)/PCA模块0中断服务程序,LED_PCA0=!LED_PCA0;/LED_PCA0取反,表示PCA模块0发生了中断,CCF0=0;/清PCA模块0中断标志,else if(CCF1)/PCA模块1中断服务程序,LED_PCA1=!LED_PCA1;/LED_PCA1取反,表示PCA模块1发生了中断,CCF1=0;/清PCA模块1中断标志,【,例,7-5】,利用,PCA,功能做定时器使用。利用,PCA,模块的软件定时功能,实现在,P1.6,输出脉冲宽度为,1,秒钟的方波。假设晶振频率,fosc,=18.432MHz,。,解:在此选择,PCA,模块,0,实现定时功能。通过置位,CCAPM0,寄存器的,ECOM,位和,MAT,位,使,PCA,模块,0,工作于软件定时器模式。定时时间的长短,取决于时钟源的选择以及,PCA,计数器计数值的设置。本例中,时钟频率,FOSC=18.432MHz,,可以选择,PCA,模块的时钟源为,FOSC/12,,基本定时时间单位,T,为,5ms,,对,5ms,计数,200,次以后,即可实现,1s,的定时。通过计算,,PCA,计数器计数值为,1E00H,,可在中断服务程序中,将该值赋给,CCAP0H,CCAP0L,。,汇编语言程序清单如下:,$INCLUDE(STC12C5A.inc);包含STC12C5A60S2寄存器定义文件,COUNTER EQU 30H ;,声明一个计数器,用来计数中断的次数,LED_1s EQU P1.6,ORG 0000H,LJMP MAIN,;,转主程序,ORG 003BH,;PCA中断入口地址,LJMP PCA_ISR,ORG 0050H,MAIN:MOV SP,#70H,MOV COUNTER,#200 ;设置COUNTER计数器初值,;初始化PCA模块,MOV CMOD,#10000000B ;空闲模式下停止PCA计数器工作,;选择PCA的时钟源为fOSC/12,禁止PCA计数器溢出时中断,MOV CCON,#00H ;,清零,PCA计数器溢出中断请求标志位CF,;CR=0,不允许,PCA,计数器计数;清零PCA各模块中断请求标志位CCFn,MOV CL,#00H,;,清零,PCA,计数器,MOV CH,#00H,MOV CCAP0L,#00H,;给PCA模块0的CCAP0L置初值,MOV CCAP0H,#1EH ;给PCA模块0的CCAP0H,置初值,MOV CCAPM0,#49H ;设置PCA模块0为16位软件定时器,;ECCF0=1允许PCA模块0中断,;当CH,CL=CCAP0H,CCAP0L时,产生中断请求,CCF0=1,请求中断,SETB EA ;,开整个单片机所有中断共享的总中断控制位,SETB CR ;启动PCA计数器(CH,CL)计数,SJMP$;,循环等待中断,PCA_ISR:,;PCA中断服务程序,PUSH ACC,;,保护现场,PUSH PSW,;每5mS中断一次,MOV A,#00H,;给CCAP0H,CCAP0L增加一个数值,ADD A,CCAP0L,MOV CCAP0L,A,MOV A,#1EH,ADDC A,CCAP0H,MOV CCAP0H,A,CLR CCF0 ;清 PCA 模块0,中断标志,DJNZ COUNTER,PCA_EXIT;中断计数没有减到0,直接退出,MOVCOUNTER,#200;,恢复中断计数初值,CPL LED_1s ;LED_1S输出脉冲宽度为1秒钟的方波,PCA_EXIT:,POP PSW ;,恢复现场,POP ACC,RETI,END,对应的C语言程序如下:,#include“stc12c5a.h”/,包含,STC12C5A60S2,寄存器定义文件,sbit,LED_1s=P16;,unsigned char,cnt,;/,中断计数变量,void main(void),cnt,=200;/,设置,COUNTER,计数器初值,CMOD=0 x80;/#10000000B,空闲模式下停止,PCA,计数器工作,/,选择,PCA,时钟源为,FOSC/12,,禁止,PCA,计数器溢出时中断,CCON=0;/,清零,PCA,计数器溢出中断请求标志位,CF,/CR=0,不允许,PCA,计数器计数;清零,PCA,各模块中断请求标志位,CCFn,CL=0;/,清零,PCA,计数器,CH=0;,CCAP0L=0;/,给,PCA,模块,0,的,CCAP0L,置初值,CCAP0H=0 x1e;/,给,PCA,模块,0,的,CCAP0H,置初值,CCAPM0=0 x49;/,设置,PCA,模块,0,为,16,位软件定时器,/ECCF0=1,允许,PCA,模块,0,中断,/,当,CH,,,CL=CCAP0H,,,CCAP0L,时,,CCF0=1,,产生中断请求,EA=1;/,开整个单片机所有中断共享的总中断控制位,CR=1;/,启动,PCA,计数器,(CH,CL),计数,while(1);/,等待中断,void,PCA_ISR(void,)interrupt 7/PCA,中断服务程序,union /,定义一个联合,以进行,16,位加法,unsigned,int,num;,struct,/,在联合中定义一个结构,unsigned char,Hi,Lo,;,Result;,temp;,/,每,5ms,中断一次,temp.num,=(unsigned int)(CCAP0H8)+CCAP0L+0 x1e00;,CCAP0L=,temp.Result.Lo,;/,取计算结果的低,8,位,CCAP0H=,temp.Result.Hi,;/,取计算结果的高,8,位,CCF0=0;/,清,PCA,模块,0,中断标志,cnt,-;/,修改中断计数,if(,cnt,=0),cnt,=200;/,恢复中断计数初值,LED_1s=!LED_1s;/,在,P1.6,输出脉冲宽度为,1,秒钟的方波,【,例,7-6】,利用PCA模块进行PWM输出。PWM脉冲由P1.3输出。假设晶振频率FOSC=18.432MHz。,解:,PWM,无需中断支持,只需根据需要设置,PCA,模块的参数,并通过指令
展开阅读全文