第8章 定时计数器的结构与应用

更新时间:2024-06-20 08:10:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

,基于AVR的单片嵌入式系统原理与实践应用

第8章 定时计数器的结构与应用

定时计数器(Timer/Counter)是单片机中最基本的接口之一,它的用途非常广泛,常用于计数、延时、测量周期、频率、脉宽、提供定时脉冲信号等。在实际应用中,对于转速,位移、速度、流量等物理量的测量,通常也是由传感器转换成脉冲电信号,通过使用定时计数器来测量其周期或频率,再经过计算处理获得。

相对于一般8位单片机而言,AVR不仅配备了更多的定时计数器接口,而且还是增强型的,如通过定时计数器与比较匹配寄存器相互配合,生成占空比可变的方波信号,即脉冲宽度调制输出PWM信号,用于D/A、马达无级调速控制、变频控制等,功能非常强大。

ATmega16一共配置了2个8位和1个16位,共3个定时计数器,它们是8位的定时计数器T/C0、T/C2和16位的定时计数器T/C1。本章将着重对AVR的8位定时计数器的结构、功能和应用进行讲解,并介绍基本的使用设计方法。

8.1 定时计数器的结构

在单片机内部,一般都会集成由专门硬件电路构成的可编程定时计数器。定时计数器最基本的功能就是对脉冲信号“自动”进行计数。这里所谓的“自动”,指计数的过程是由硬件完成的,不需要MCU的干预。但MCU可以通过指令设置定时计数器的工作方式,以及根据定时计数器的计数值或工作状态做必要的处理和响应。

学习和使用定时计数器时,必须注意以下的基本要素:

? 定时计数器的长度。定时计数器的长度是指计数单元的位长度,一般为8位(一个

字节)或16位(2个字节)。 ? 脉冲信号源。脉冲信号源是指输入到定时计数器的计数脉冲信号。通常用于定时计

数器计数的脉冲信号可以由外部输入引脚提供,也可以由单片机内部提供。 ? 计数器类型。计数器类型是指计数器的计数运行方式,可分为加一(减一)计数器,

单程计数或双向计数等。

? 计数器的上下限。计数器的上下限指计数单元的最小值和最大值。一般情况下,计

数器的下限值为零,上限值为计数单元的最大计数值,即255(8位)或65535(16位)。需要注意的是,当计数器工作在不同模式下时,计数器的上限值并不都是计数单元的最大计数值255或65535,它将取决于用户的配置和设定。 ? 计数器的事件。计数器的事件指计数器处于某种状态时的输出信号,该信号通常可

以向MCU申请中断。如当计数器计数到达计数上限值255时,产生“溢出”信号,向MCU申请中断。

8.1.1 8位定时计数器T/C0的结构

ATmega16中有两个8位的定时计数器:T/C0、T/C2,它们都是通用的多功能定时计数器,其主要特点是:

? 单通道计数器。

? 比较匹配时清零计数器(自动重装特性,Auto Reload)。

? 可产生无输出抖动(glitch-free)的,相位可调的脉宽调制(PWM)信号输出。 ? 频率发生器。

华东师范大学 电子系 马 潮 8-1

第8章 8位定时计数器结构与应用

? 外部事件计数器(仅T/C0)。 ? 带10位的时钟预分频器。

? 溢出和比较匹配中断源(TOV0、OCF0和TOV2、OCF2)。

? 允许使用外部引脚的32kHz手表晶振作为独立的计数时钟源(仅T/C2)。 T/C0、T/C2的主要结构和大部分的功能是相同或类似的,因此,我们先介绍T/C0的结构和应用。

1.T/C0的组成结构

图8-1为8位T/C0的硬件结构框图。图中给出了MCU可以操作的寄存器以及相关的标志位。在T/C0中,有两个8位的寄存器:计数寄存器TCNT0和输出比较寄存器OCR0。其它相关的寄存器还有T/C0的控制寄存器TCCR0,中断标志寄存器TIFR和定时器中断屏蔽寄存器TIMSK。T/C0的计数器事件输出信号有两个,计数器计数溢出TOV0和比较匹配相等OCF0。这两个事件的输出信号都可以申请中断,中断请求信号TOV0、OCF0可以在定时器中断标志寄存器TIFR中找到,同时在定时器中断屏蔽寄存器TIMSK中,可以找到与TOV0、OCF0对应的两个相互独立的中断屏蔽控制位TOIE0、OCIE0。

图8-1 8位T/C0的结构框图

(1)T/C0的时钟源

T/C0的计数时钟源可由来自外部引脚T0的信号提供,也可来自芯片的内部。图8-2为T/C0时钟源部分的内部功能图。

? T/C0计数时钟源的选择

T/C0的时钟源的选择由T/C0的控制寄存器TCCR0中的3个标志位CS0[2:0]确定,共有8种选择。其中包括无时钟源(停止计数),外部引脚T0的上升沿或下降沿,以及内部系统时钟经过一个10位预定比例分频器分频的5种频率的时钟信号(1/1、1/8、1/64、1/256、1/1024)。T/C0与T/C1共享一个预定比例分频器,但它们时钟源的选择是独立的。

? 使用系统内部时钟源

当定时计数器使用系统内部时钟作为计数源时,通常作为定时器和波形发生器使用。因为系统时钟的频率是已知的,这样通过计数器的计数值就可以知道时间值。

,基于AVR的单片嵌入式系统原理与实践应用

AVR在定时计数器和内部系统时钟之间增加了一个预定比例分频器,分频器对系统时钟信号进行不同比例的分频,分频后的时钟信号提供定时计数器使用。利用预定比例分频器,定时计数器可以从内部系统时钟获得几种不同频率的计数脉冲信号,使用非常灵活。

图8-2 T/C0的时钟源与10位预定比例分频器

? 使用外部时钟源

当定时计数器使用外部时钟作为计数源时,通常作为计数器使用,用于记录外部脉冲的个数。图8-3为外部时钟源的检测采样逻辑功能图。

图8-3 T/C0外部时钟检测采样逻辑功能图

外部引脚T0(PB0)上的脉冲信号可以作为C/T0的计数时钟源。PB0引脚内部有一个同步采样电路(Synchronization),它在每个系统时钟周期都对T0引脚上的电平进行同步采样,然后将同步采样信号送到边沿检测器(Edge Detector)中。同步采样电路在系统时钟的上升沿将引脚信号电平打入寄存器,因此当系统的时钟频率大大高于外部引脚上电平变化的频率时,同步采样寄存器可以看作是透明的。边沿检测电路对同步采样的输出信号进行边沿检测,当检测到一个正跳变(CS0[2:0]=7)或负跳变(CS0[2:0]=8)时产生一个计数脉冲CLKT0。

由于引脚内部的同步采样和边沿检测电路的存在,引脚电平的变化需要经过2.5~3.5个系统时钟后才能在边沿检测的输出端上反映出来。因此,要使外部时钟源能正确的被引脚的检测采样,外部时钟源的最高频率不能大于 fclk_I/O/2.5,脉冲宽度也要大于一个系统时钟周期。另外,外部时钟源是不进入预定比例分频器进行分频的。 (2)T/C0的计数单元

华东师范大学 电子系 马 潮 8-3

第8章 8位定时计数器结构与应用

T/C0的计数单元是一个可编程的8位双向计数器,图8-4是它的逻辑功能图,图中符号所代表的意义如下:

? ? ? ? ? ?

计数(count) 清除(clear) 计数时钟(clkT0) 顶部值(TOP) 底部值(BOTTOM)

TCNT0加1或减1。 加或减的控制。 清零TCNT0。 C/T0时钟源

表示TCNT0计数值到达上边界。 表示TCNT0计数值到达下边界(零)。

方向(direction)

图8-4 T/C0计数单元逻辑功能图

T/C0根据计数器的工作模式,在每一个clkT0时钟到来时,计数器进行加1、减1或清零操作。clkT0的来源由标志位CS0[2:0]设定。当CS0[2:0]=0时,计数器停止计数(无计数时钟源)。

T/C0的计数值保存在8位的寄存器TCNT0中,MCU可以在任何时间访问(读/写)TCNT0。MCU写入TCNT0的值将立即覆盖其中原有的内容,同时也会影响到计数器的运行。 计数器的计数序列取决于寄存器TCCR0中标志位WGM0[1:0]的设置。WGM0[1:0]的设置直接影响到计数器的计数方式和OC0的输出,同时也影响和涉及T/C0的溢出标志位TOV0的置位。标志位TOV0可以用于产生中断申请。 (3)比较匹配单元

图8-5 T/C0比较匹配单元逻辑功能图

图8-5为T/C0的比较匹配单元逻辑功能图。在T/C0运行期间,比较匹配单元一直将寄存器TCNT0的计数值同寄存器OCR0的内容进行比较(硬件进行自动比较处理)。一旦两者相

,基于AVR的单片嵌入式系统原理与实践应用

等,在下一个计数时钟脉冲到达时置位OCF0标志位。标志位OCF0也可以用于产生中断申请。根据WGM0[1:0]和COM0[1:0]的不同设置,可以控制比较匹配单元产生和输出不同类型的脉冲波形。

寄存器OCR0实际上配置有一个辅助缓存器。当T/C0工作在非PWM模式下时,该辅助缓存器处于被禁止使用状态,此时MCU直接访问和操作寄存器OCR0。当T/C0工作在PWM模式时,该辅助缓存器投入使用,这时MCU对OCR0的访问操作,实际上是对OCR0的辅助缓存器操作。一旦计数器TCNT0的计数值达到设定的最大值(TOP)或最小值(BOTTOM)时,辅助缓存器中的内容将同步更新比较寄存器OCR0的值。这将有效防止产生奇边非对称的PWM脉冲信号,使输出的PWM波中没有杂散脉冲。

? 强制输出比较

在非PWM波形发生模式下,写1到强制输出比较位(FOC0)时,将强制比较器产生一个比较匹配输出信号。强制比较输出信号不会置OCF0标志位或重新装载/清零计数器,但是会像真的发生了比较匹配事件一样更新OC0输出引脚输出。

? 通过写TCNT0寄存器屏蔽比较匹配事件

任何MCU对TCNT0寄存器的写操作都会屏蔽在下一个定时器时钟周期中的发生的比较匹配事件,即使在定时器暂停时。这一特性使OCR0可以被初始化为与TCNT0相同的值,而不会在定时计数器被使能时触发中断。

? 使用输出比较单元 由于在任何工作模式下,写TCNT0寄存器都会使得输出比较匹配事件被屏蔽一个定时器时钟周期,因此可能会影响比较匹配输出的正确性。例如,写入一个与OCR0相同的值到TCNT0时,将丢失一次比较匹配事件,从而引起发生不正确的波形。同样,当定时器是向下计数时,不要将下边界的值写入TCNT0。

外部引脚OC0的设置必须在设置该端口引脚(PB3)为输出之前。设置OC0的值最简单的方法是在通常模式下使用FOC0来设置,这是因为在改变工作模式时,OC0寄存器将保持其原来的值。

需要注意的是,COM0[1:0]是无缓冲的,改变COM0[1:0]位的设置,会立即影响T/C0的工作方式。

(4)比较匹配输出单元

标志位COM0[1:0]有两个作用:定义OC0的输出状态,以及控制外部引脚OC0是否输出OC0寄存器的值。图8-6为比较匹配输出单元的逻辑图。

图8-6 T/C0比较匹配输出单元逻辑图

华东师范大学 电子系 马 潮 8-5

,基于AVR的单片嵌入式系统原理与实践应用

设置OCR0的值为0xFF时,OC0的输出为恒定的高(低)电平。

当OC0的输出方式为触发方式时(COM0[1:0]=1),T/C0将产生占空比为50%的PWM波形。此时设置OCR0的值为0x00时,T/C0将产生占空比为50%的最高频率PWM波形,频率为

fOC0=fclk_I/O/2。

(4)相位可调PWM模式(WGM0[1:0]=1)

相位可调PWM模式可以产生高精度相位可调的PWM波形。当T/C0工作在此模式下时,计数器为双程计数器:从0x00一直加到0xFF,在下一个计数脉冲到达时,改变计数方向,从0xFF开始减1计数到0x00。设置正向比较匹配输出(COM0[1:0]=2)方式:在正向加1过程中,TCNT0的计数值与OCR0的值相同匹配时清零OC0;在反向减1过程中,当计数器TCNT0的值与OCR0相同时置位OC0。设置反向比较匹配输出(COM0[1:0]=3)方式:在正向加1过程中,TCNT0的计数值与OCR0的值相同匹配时置位OC0;在反向减1过程中,当计数器TCNT0的值与OCR0相同时清零OC0。图8-9为相位可调PWM工作时序图。

图8-9 T/C0相位可调PWM工作时序

由于相位可调PWM模式采用双程计数方式,所以它产生的PWM波的频率比快速PWM低。其相位可调的特性(即OC0逻辑电平的改变不是固定在TCNT0=0x00处),适用于马达控制一类的应用。

在TCNT0的计数值到达0x00时,置溢出标志位TOV0为“1”。标志位TOV0可以用于申请溢出中断。

在相位可调PWM模式下,OC0输出的PWM波形频率由下式确定,式中N的取值为 1、8、64、256或1024。

fOC0PCPWM?fclk_I/O 510N通过设置寄存器OCR0的值,可以获得不同占空比的脉冲波形。OCR0的一些特殊值,会产生极端的PWM波形。当COM0[1:0]=2且OCR0的值为0xFF时,OC0的输出为恒定的高电平;而OCR0的值为0x00时,OC0的输出为恒定的低电平。

华东师范大学 电子系 马 潮 8-11

第8章 8位定时计数器结构与应用

8.1.3 8位T/C0的计数工作时序

图8-10、图8-11、图8-12和图8-13给出了T/C0在同步工作情况下的各种计数时序,同时给出标志位TOV0和OCF0的置位条件。图中MAX=0xFF,BOTTOM=0x00,TOP=[OCRn]。

图8-10 T/C0计数时序(无预分频)

图8-10是T/C0对外部时钟或直接对内部时钟(无分频)计数工作的时序图。从图中看出,T/C0的计数是同系统时钟同步的(在系统时钟上升沿)。当TCNT0的值到达MAX(0xFF)后,在下一个系统时钟的上升沿处把TCNT0的值清为BOTTOM(0x00),同时置位TOV0申请中断。然而T/C0的计数过程并没有停止,重新从0x00开始继续加1计数。

图8-11 T/C0计数时序,带1/8预分频

图8-11是T/C0对经过预分频器的内部时钟(8分频)计数工作的时序图。从图中看出,T/C0的计数是同系统时钟同步的(每隔8个系统时钟的上升沿)。当TCNT0的值到达MAX(0xFF)后,在接下来第8个系统时钟的上升沿处将TCNT0的值清为BOTTOM(0x00),同时置位TOV0申请中断。然而T/C0的计数过程并没有停止,重新从0x00开始继续加1计数。

图8-12 T/C0计数时序,OCFn置位,带1/8预分频(CTC模式除外)

,基于AVR的单片嵌入式系统原理与实践应用

图8-12给出了T/C0工作在各种模式(除CTC模式外)时,比较匹配输出的标志位OCF0的置位情况。在T/CO对经过预分频器的内部时钟(8分频)计数过程中,比较匹配单元将寄存器TCNT0中的计数值和比较匹配寄存器OCR0中的值进行比较。一旦两者相等,在下一个计数脉冲到达时置位OCF0标志位,申请中断,然而T/C0的计数过程并没有停止,继续加1向上计数。

图8-13是T/C0工作在CTC模式时的比较匹配输出标志位OCF0的置位情况。在T/CO对经过预分频器的内部时钟(8分频)计数过程中,比较匹配单元将寄存器TCNT0中的计数值和比较匹配寄存器OCR0中的值进行比较。一旦两者相等(此时OCR0的值是计数器的上限值TOP),在下一个计数脉冲到达时置位OCF0标志位,申请中断,并同时将TCNT0的值清为BOTTOM(0x00)。然而T/C0的计数过程并没有停止,重新从0x00开始继续加1计数。

图8-13 T/C0计数时序,OCFn置位,带1/8预分频(CTC模式)

8.2 8位定时计数器T/C0的应用

使用定时计数器进行系统设计是非常灵活的,用户需要对实际的情况做仔细的分析,充分考虑利用定时计数器的特点,采用不同的方式来实现。 尽管定时计数器的基本工作原理比较简单,其基本特点为:

? 对一个序列的脉冲信号进行计数,而且计数过程由硬件自己完成,不需要软件干预。 ? 一旦计数值到达某个值,通常是MAX(0xFF)、BOTTOM(0x00)或TOP时,可以产

生中断申请,通知MCU进行处理。

但在实际使用中,如果能巧妙的结合定时计数器各种不同的工作模式,则会产生多种变化。因此用户在使用定时计数器进行设计时,应该注意以下几个要点。

? 仔细确定使用哪个定时计数器。ATmega16一共配置了2个8位和1个16位,共3

个定时计数器,不仅长度不同,而且其功能也不同。要选择适合的定时计数器使用。 ? 脉冲信号源。脉冲信号源是指输入到定时计数器的计数脉冲信号。用于定时计数器

计数的脉冲信号可以由外部输入引脚提供,也可以由单片机内部提供。当使用内部计数脉冲信号时,应选择合适的分频比例与计数值的配合(建议使用CVAVR系统中的程序生成器功能)。

? 计数器的工作模式和触发方式的选择。

? 中断服务程序的正确设计。定时计数器的使用通常都是与中断相结合一起使用的,

因此要非常清楚中断的产生条件,以及在中断服务程序中正确的进行中断处理以及相关的设置。

华东师范大学 电子系 马 潮 8-13

第8章 8位定时计数器结构与应用

本节将给出一些定时计数器基本的应用和设计,以便读者能在学习和理解这些基本使用方法的过程中,更好的掌握定时计数器的特点,进而能达到能真正的在实际系统中灵活的使用定时计数器的目的。

8.2.1 外部事件计数器

T/C0作为外部事件计数器使用时,是指其计数脉冲信号来自外部的引脚T0(PB0)。

注意,外部引脚T0输入的脉冲信号是不通过ATmega16内部的预分频器的。

通常对外部输入的脉冲信号的基本处理有两种: ? 对外部的脉冲信号进行计数,即记录脉冲的个数,一旦记录的脉冲个数到达一设定

值时进行必要的处理。

? 对外部的脉冲信号的频率(周期)进行测定。

在本小节中,我们只介绍前一种的应用。关于对外部的脉冲信号的频率(周期)进行测定的设计,将在本书后面的相关章节中介绍。 例8.1 2N分频系统设计一 1) 硬件电路

2N分频系统要实现的功能是对TO脚输入的方波信号进行偶数次的分频,以获得频率低于TO输入的方波信号。

本设计的硬件电路非常简单,将实验板上的250Hz的方波信号输出与ATmega16的T0脚连接,作为T/C0计数器的外部输入。另外将PA0作为分频后的脉冲输出脚,用PAO控制一个LED的显示,通过LED的亮暗变化可以简单的观察方波的频率。当然最好的方式是使用示波器观察PA0的输出。 2) 软件设计

首先考虑使用T/C0的普通模式(WGM0[1:0]=0),采用TO上升沿触发(CS0[2:0]=111),并设置TCNT0的初值为0xFF。当TO引脚输入电平出现一个上跳变时,T/CO的TCNTO回到0x00,并产生溢出中断(参考图8-10),在溢出中断服务中重新设置TCNT0为0xFF,并改变PA0口的输出电平(取反输出)。在TO引脚输入电平出现第二个上跳变时,又会产生中断,在中断服务程序中再次改变PAO的输出,这样在PAO上就得到TO的2分频输出信号。同理,如果将TCNT0的初值设置为0xFE,则在PA0上得到TO的4分频输出信号,0xFD?6分频,0xFC—>8分频??,而当TCNT0的初值设置为0x00时,可实现最大512分频的输出。

下面,我们给出在PA0上输出1Hz的方波(LED亮0.5s,暗0.5s)的设计和程序。由于T0输入的频率为250Hz,所以分频系数为250,因此TCNTO的初值=255-124(0x83),即T/C0计数125次时PA0的电平改变一次。

再次建议读者使用CVAVR中的程序生成向导功能来帮助你建立整个程序的框架,以及芯片的初始化部分的语句,可以省掉你过多的查看器件手册和考虑寄存器的设置值等。

图8-14是在CVAVR的程序生成向导中设置T/C0的对话窗口。选择T/CO的计数时钟源为T0的上升沿,工作方式为普通模式,允许溢出中断,TCNT0的初值为0x83。

利用CVAVR的程序生成向导,在它的帮助下生成一个程序框架后,然后再加入自己的程序和进行必要的修改。

,基于AVR的单片嵌入式系统原理与实践应用

图8-14 在程序生成向导中设置T/C0

/********************************************* File name

: Demo_8_1.c

Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256

*********************************************/

#include

// Timer 0 溢出中断服务

interrupt [TIM0_OVF] void timer0_ovf_isr(void) { }

void main(void) {

PORTA=0x01; DDRA=0x01;

// 设置PA0输出方式

TCNT0=0x83;

// 重新设置TCNT0的初值 // PA0取反输出

PORTA.0 = ~PORTA.0;

华东师范大学 电子系 马 潮 8-15

第8章 8位定时计数器结构与应用

PORTB=0x01;

// T/C0 初始化 TCCR0=0x07; TCNT0=0x83; OCR0=0x00;

TIMSK=0x01;

#asm(\

while (1) }

{

// Place your code here };

// 开放全局中断

// 允许T0溢出中断

// T/C0工作于普通模式,T0上升沿触发

// 设置PB0(T0)为输入方式

DDRB=0x00;

上面的程序,就是先利用CVAVR的程序生成向导功能进行配置,然后在它生成的程序框架基础上完成的。

在程序中,主程序对T/C0进行初始化后进入一个无限的循环。在T/CO的中断服务程序中,重新设置TCNT0的初值,并将PA0取反输出。这时PA0上可以获得1Hz的方波输出。 3) 思考与实践

? 为什么在中断服务程序中要重新设置TCNT0的初值? ? 如何计算TCNTO的初值,使得PA0输出0.5Hz的方波。 例8.2 2N分频系统设计二 1)硬件电路

同2N分频系统设计一。 2)软件设计

2N分频系统设计一中使用了T/C0的普通模式,因此在中断服务程序中必须重新对TCNT0进行初始化。其实,更方便的方法是使用T/CO的CTC模式,利用T/CO的自动重装特性。当T/C0工作在CTC模式时,计数器TCNT0的值与OCR0的值比较,一旦相等,在下一次计数脉冲到来时,清零TCNT0,并产生T/C0的比较匹配中断(参考图8-13)。此时在比较匹配中断服务程序中改变PA0的输出即可。

/********************************************* File name

: demo_8_2.c

Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256

*********************************************/

,基于AVR的单片嵌入式系统原理与实践应用

#include

// Timer 0 比较匹配中断服务

interrupt [TIM0_COMP] void timer0_comp_isr(void) { }

void main(void) {

PORTA=0x01; DDRA=0x01;

PORTB=0x01; DDRB=0x00;

// T/C0 初始化 TCCR0=0x0F; TCNT0=0x00; OCR0=0x7C;

TIMSK=0x02; #asm(\

while (1) { }; }

// Place your code here

// 允许T/C0的比较匹配中断 // 开放全局中断

// 设置OCR0的比较值为124(0x7C)

// T/C0工作于CTC模式,T0上升沿触发

PORTA.0=~PORTA.0;

// PA0取反输出

3) 思考与实践

? 比较demo_8_1.c和demo_8_2.c中T/C0两种方式的特点。 ? 如何利用T/C0实现N分频? 例8.3 N分频系统设计 1)硬件电路

同2N分频系统设计,但在PA0上得到N分频的输出。 2)软件设计

实际上,利用T/C0的比较匹配的特点,可以实现N分频的系统。

/********************************************* File name Chip type Program type Memory model

: demo_8_3.c : ATmega16 : Application : 4.000000 MHz : Small

Clock frequency

External SRAM size : 0

华东师范大学 电子系 马 潮 8-17

第8章 8位定时计数器结构与应用

Data Stack size

#include

// Timer 0 溢出中断服务

interrupt [TIM0_OVF] void timer0_ovf_isr(void) {

TCNT0=0xFB;

}

// Timer 0 比较匹配中断服务

interrupt [TIM0_COMP] void timer0_comp_isr(void) { }

void main(void) {

PORTA=0x00; DDRA=0x01;

PORTB=0x01; DDRB=0x00;

// T/C0 初始化 TCCR0=0x07; TCNT0=0xFB; OCR0=0xFD;

TIMSK=0x03; #asm(\

while (1)

{ }; }

// Place your code here

// 允许T/C0的溢出和比较匹配中断 // 开放全局中断

// 设置OCR0的比较值,>TCNT0的初始值,<0xFF

// T/C0工作于普通模式,T0上升沿触发

PORTA = ~PORTA;

// PA0取反输出

PORTA = ~PORTA;

// 重新设置TCNT0的初值 // PA0取反输出

: 256

*********************************************/

程序demo_8_3.c设置T/CO工作在普通模式,并结合比较匹配的特性,在比较匹配中断和溢出中断中都改变PA0的输出,在PA0上获得5分频的脉冲信号。 3) 思考与实践

? 请读者自己分析程序实现N分频的原理。

? 如果要实现11分频的输出,TCNT0的初值应该如何计算,为什么同例8.1 不同?

,基于AVR的单片嵌入式系统原理与实践应用

? 在N分频的系统中,OCR0的值应该如何设置?

? 在PA0上输出的方波序列的占空比同例8.1和例8.2有何不同? ? 利用这个方法,能否在PA0上获得占空比可调的PWM波?

8.2.2 定时器应用设计

实际上不管定时计数器是作为计数器使用还是作为定时器使用,其根本的工作原理并没有改变,都是对一个脉冲系列信号进行计数。通常所谓的定时器,更多的情况是指其计数脉冲信号来自芯片本身的内部。由于内部的计数脉冲信号的频率(周期)是已知的或固定的,因此用户可以根据需要来设定计数器脉冲计数的个数,以获得一个等间隔的定时中断。利用定时中断,可以方便的实现系统定时访问外设或处理事物,以及获得更加准确的延时等等。

同其他一些单片机类似,AVR的定时计数器的计数脉冲可以来自外部的引脚,也可以从内部系统时钟获得,但AVR的定时计数器在内部系统时钟和计数单元之间增加了一个可设置的预分频器,利用这个预分频器,定时计数器可以从内部系统中获得不同频率的计数脉冲信号。表8.6给出了系统时钟为4MHz时,ATmega16芯片本身能够提供给T/C0的计数脉冲信号的最高计时精度和时宽范围。

表8.1 T/C0计时精度和时宽(系统时钟4MHz)

分频系数 1 8 64 256 1024 计时频率 4MHz 500KHz 62.5KHz 15.625KHz 3906.25Hz 最高计时精度 (TCNT0=255) 0.25us 2us 16us 64us 256us 最宽时宽 (TCNT0=0) 64us 512us 4.096ms 16.384ms 65.536ms 从表中看出,在系统时钟为4Mh条件下,8位的T/C0最高计时精度为0.25us,而最长的时宽可达到65.536ms。而如果使用16位的定时计数器T/C1时,不需要使用辅助软件计数器,就可以非常方便的设计一个时间长达16.777216秒(精度为256us)的定时器,这是其它的8位单片机所做不到的。

AVR单片机的每一个定时计数器都配备独立的、多达10位的预分频器,由软件设定分频系数,与8/16位定时计数器配合,可以提供多种档次的定时时间。使用时可选取最接近的定时档次,即选8/16位定时计数器与分频系数的最优组合,减少了定时误差。所以,AVR定时计数器的显著特点之一是:高精度和宽时范围,使得用户应用起来更加灵活和方便。 例8.4 采用T/C0硬件定时器的时钟系统 1) 硬件电路

在第六章中的例6.5,“六位LED数码管动态扫描控制显示设计(一)”中,使用调用CVAVR中软件延时函数的方法给出了一个使用6个数码管组成时钟系统。采用软件延时,时钟是不准确的,因为一旦系统中使用了中断,就可能打断延时程序的执行,使延时时间发生变化。另外使用软件延时的方法,也降低了MCU的效率。

而在第七章中的例7.2,“采用外部中断方式,用外部振荡源为基准的时钟系统”中,系统时钟的基准信号来自外部的标准方波信号源,这样尽管定时时间比采用软件延时方式要准确的多,但由于采用外部标准方波信号源而增加了系统的成本。

实际上更加方便和简单的方式是采用系统本身的时钟信号,配合T/C0产生时钟系统的定时信号。下面给出采用T/C0硬件定时器实现的时钟系统设计。时钟系统的硬件电路仍旧

华东师范大学 电子系 马 潮 8-19

第8章 8位定时计数器结构与应用

与图6-15相同。 2) 软件设计

下面是一个采用C编写的系统源程序。

/********************************************* File name

: demo_8_4.c

Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256

*********************************************/

#include

flash char led_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; flash char position[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

char time[3]; int bit

void display(void) {

PORTC = 0xff;

}

// Timer 0 比较匹配中断服务

interrupt [TIM0_COMP] void timer0_comp_isr(void) { }

void time_to_disbuffer(void)

// 时钟时间送显示缓冲区函数

display(); { }

time_counter = 0; time_1s_ok = 1;

// 调用LED扫描显示

if (++time_counter>=500)

PORTA = led_7[dis_buff[posit]];

if (point_on && (posit==2||posit==4)) PORTA |= 0x80; PORTC = position[posit]; if (++posit >=6 ) posit = 0;

// 6位LED数码管动态扫描函数

// 时、分、秒计数单元

// 显示缓冲区,存放要显示的6个字符的段码值 // 中断次数计数单元

char dis_buff[6];

time_counter;

char posit;

point_on, time_1s_ok;

第8章 8位定时计数器结构与应用

Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256

*********************************************/

#include

flash char auc_SinParam[128] = {

128,134,140,147,153,159,165,171,177,182,188,193,199,204,209,213, 218,222,226,230,234,237,240,243,245,248,250,251,253,254,254,255, 255,255,254,254,253,251,250,248,245,243,240,237,234,230,226,222, 218,213,209,204,199,193,188,182,177,171,165,159,153,147,140,134, 128,122,116,109,103,97,91,85,79,74,68,63,57,52,47,43, 38,34,30,26,22,19,16,13,11,8,6,5,3,2,2,1, 1,1,2,2,3,5,6,8,11,13,16,19,22,26,30,34,

38,43,47,52,57,63,68,74,79,85,91,97,103,109,116,122}

char x_SW = 8,X_LUT = 0;

// T/C0 溢出中断服务

interrupt [TIM0_OVF] void timer0_ovf_isr(void) {

X_LUT += x_SW;

}

void main(void) {

TIMSK=0x01; #asm(\

// 允许T/C0溢出中断 // 开放全局中断

DDRB=0x08;

// PB3输出方式,作为OC0输出PWM波

// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 4000.000 kHz // Mode: Fast PWM top=FFh // OC0 output: Non-Inverted PWM TCCR0=0x69; OCR0=128;

// 新样点指针

// 取样点指针到比较匹配寄存器

if (X_LUT > 127) X_LUT -= 128; // 样点指针调整 OCR0 = auc_SinParam[X_LUT]; // OCR0+=1;

// 128点正弦波样本值

,基于AVR的单片嵌入式系统原理与实践应用

}

while (1)

{};

程序中,在每次的计数器溢出中断的服务中取出一个正弦波的样点值到比较匹配寄存器中,用于调整下一个PWM的脉冲宽度,这样在PB3引脚上输出了按正弦波调制的PWM方波。当PB3的输出通过低通滤波器后,便得到一个976.56Hz的正弦波了。

如要得到更精确的1KHz的正弦波,可使用ATmega16的T/C1,选择工作模式10,设置ICR1=250为计数器的上限值(将在以后的章节中给出)。

图8-17为程序运行后使用示波器在B点测量的实际波形。B点的波形轮廓非常接近正弦波,频率为976.7Hz,幅度在0-5v之间。由于滤波电路由非常简单的RC电路构成,因此还能够看出在正弦波的轮廓上的高频成分。如果用示波器在A点测量的话,可以观察到一个占空比变化的序列方波。

图8-17 实际测量到的正弦波输出波形

3) 思考与实践

? 根据T/C0的PWM模式,再结合本例,详细描述快速PWM的工作原理。

? 减小或增加程序中变量x_SW的值时,B点输出的波形有何变化?如何进行理论的

计算?

? 如果将T/C0中断服务程序中的语句清除到,用OCR0+=1代替时,分析B点输出的

波形,以及频率,并用示波器观察。

8.4 16位定时计数器T/C1的应用

ATmega16的T/C1是一个16位的多功能定时计数器,图8-18为该16位定时计数器的结构框图。其主要特点有: ? 真正的16位设计。

? 2个独立的输出比较匹配单元。 ? 双缓冲输出比较寄存器。

华东师范大学 电子系 马 潮 8-27

第8章 8位定时计数器结构与应用

? 一个输入捕捉单元。 ? 输入捕捉躁声抑制。

? 比较匹配时清零计数器(自动重装特性,Auto Reload)。

? 可产生无输出抖动(glitch-free)的,相位可调的脉宽调制(PWM)信号输出。 ? 周期可调的PWM波形输出。 ? 频率发生器。 ? 外部事件计数器。 ? 带10位的时钟预分频器。

? 4个独立的中断源(TOV1、OCF1A、OCF1B、ICF1)。

图8-18 T/C1结构图(图中n为1)

图中给出了MCU可以操作的寄存器以及相关的标志位,其中计数器寄存器TCNT1、输出比较寄存器OCR1A、OCR1B和输入捕捉寄存器ICR1都是16位的寄存器。T/C1所有的中断请求信号TOV1、OC1A、OC1B、ICF1可以在定时计数器中断标志寄存器TIFR找到,而在定时器中断屏蔽寄存器TIMSK中,可以找到与它们对应的4个相互独立的中断屏蔽控制位TOIE1、OCIE1A、OCIE1B和TICIE1。TCCR1A、TCCR1B为2个8位寄存器,是T/C1的控制寄存器。

T/C1的时钟源的选择由T/C1的控制寄存器TCCR1B中的3个标志位CS1[2:0]确定,共有8种选择。其中包括无时钟源(停止计数),外部引脚T1的上升沿或下降沿,以及内部系

,基于AVR的单片嵌入式系统原理与实践应用

统时钟经过一个10位预定比例分频器分频的5种频率的时钟信号(1/1、1/8、1/64、1/256、1/1024)。

T/C1基本的工作原理和功能与8位定时计数器相同,常规的使用方法也是类同的。但与8位的T/C0、T/C2相比,T/C1不仅位数增加到16位,其功能也更加强大。由于篇幅有限,本节着重介绍T/C1一些增强的功能和基本应用。

8.4.1 16位T/C1增强功能介绍

与8位T/C0、T/C2相比,T/C1的功能增强主要表现在以下几个方面。 1.16位的计数器

由于T/C1是16位的计数器,因此它的计数宽度、计时长度大大增加,配合一个独立的10位预定比例分频器,在系统时钟为4Mh条件下,16位的T/C1最高计时精度为0.25us,而最长的时宽可达到16.777216秒(精度为256us),这是其它的8位单片机所做不到的。

需要注意的是,AVR的内部有许多16位的寄存器,这些寄存器都是由两个8位的寄存器组成的。如16位的寄存器TCNT1实际由2个8位寄存器TCNT1H、TCNT1L组成的。对这些16位寄存器的读写操作需要遵循以下特定的步骤。

2.16位寄存器的读写操作步骤

由于AVR的内部数据总线为8位,因此读写16位的寄存器需要分两次操作。为了能够同步读写16位寄存器,每一个16位寄存器分别配有一个8位的临时辅助寄存器(Temporary Register),用于保存16位寄存器的高8位数据。要同步读写这些16位的寄存器,读写操作应遵循以下特定的步骤:

? 16位寄存器的读操作

当MCU读取16位寄存器的低字节(低8位)时,16位寄存器低字节内容被送到MCU,而高字节(高8位)内容在读低字节操作的同时被置于临时辅助(TEMP)寄存器中。当MCU读取高字节时,读到的是TEMP寄存器中的内容。因此,要同步读取16位寄存器中的数据,应先读取该寄存器的低位字节,再立即读取其高位字节。

? 16位寄存器的写入操作

当MCU写入数据到16位寄存器的高位字节时,数据是写入到TEMP寄存器中。当MCU写入数据到16位寄存器的低位字节时,写入的8位数据与TEMP寄存器中的8位数据组合成一个16位数据,同步写入到16位寄存器中。因此,要同步写16位寄存器时,应先写入该寄存器的高位字节,再立即写入它的低位字节。

用户编写汇编程序时,如要对16位寄存器进行读写操作,应遵循以上特定的步骤。此外,在对16位寄存器操作时,最好将中断响应屏蔽,防止在主程序读写16位寄存器的两条指令之间插入一个含有对该寄存器操作的中断服务。如果这种情况发生,那么中断返回后,寄存器中的内容已经改变,会造成主程序中对16位寄存器的读写失误。下面是读写16位寄存器的汇编子程序示例。

;汇编代码:TIME16_Read_Write_TCNT1: ;保存寄存器SREG in r18,SREG ;禁止中断 cli

;读TCNT1 到r17:r16 in r16,TCNT1L in r17,TCNT1H ;置TCNT1为0x01FF

华东师范大学 电子系 马 潮 8-29

第8章 8位定时计数器结构与应用

ldi r17,0x01 ldi r16,0xFF out TCNT1H,r17 out TCNT1l,r16 ;恢复寄存器SREG out SREG,r18 ret

采用C等高级语言编写程序则可以直接对16位的寄存器进行操作,因为这些高级语言的编译系统会根据16位寄存器的操作步骤生成正确的执行代码。

3. 更加强大和完善的PWM功能

T/C1配备了2个比较匹配输出单元OC1A、OC1B和比较匹配寄存器OCR1A、OCR1B。同时它的PWM模式,有多种不同的计数器上限(TOP)值可供选择,因此T/C1的PWM功能具备以下特点:

? 可产生频率、相位均可调整的PWM波。

T/C1有15种工作模式,除了常规的计数、CTC模式外,还可以产生频率可调、相位可调、频率相位均可调的多种形式的PWM波。其中频率可调的PWM波利用8位定时计数器是不能实现的。T/C1的频率调整范围可以达到16位的精度,它是通过改变计数器的上限值实现的。

? 可同时产生2路不同占空比的PWM波

由于T/C1配备了2个比较匹配输出单元OC1A、OC1B和比较匹配寄存器OCR1A、OCR1B,因此使用一个计数器就可以得到相同频率,不同占空比的2路PWM输出。2路PWM波的占空比的确定和调整分别由寄存器OCR1A、OCR1B确定,分别在OC1A、OC1B上输出。

4.输入捕捉功能

T/C1的输入捕捉功能是AVR定时计数器的另一个非常有特点的功能。T/C1的输入捕捉单元(如图8-19所示)可应用于精确捕捉一个外部事件的发生,记录事件发生的时间印记(Time-stamp)。捕捉外部事件发生的触发信号由引脚ICP1输入,或模拟比较器的AC0单元的输出信号也可作为外部事件捕获的触发信号。

图8-19 T/C1的外部事件输入捕捉单元(n为1)

本文来源:https://www.bwwdw.com/article/qo13.html

Top