第13讲 定时/计数器2

ATmega32单片机片内的T/C2模块功能非常接近与T/C0,它最大的特点就是可以使用外接与TOSC1和TOSC2引脚的晶体振荡器作为计数时钟,使其可以在低功耗的状态下实现实时时钟(RTC)的功能。

10.1

认识T/C2

10.1.1

T/C2的内部结构

T/C2的内部由计数器单元、输出比较单元和同步控制单元三部分构成,具体如图10-1所示。

1.计数器单元

T/C2的核心部分是一个可编程8位双向计数单元,称为TCNT2,它可以由来自系统的同步时钟驱动,也可以由外接于TOSC1和TOSC2引脚的异步时钟驱动。这两种时钟信号均需经过独立的预分频器后,输出clk 2.输出比较单元

输出比较单元用于持续地将计数器TCNT2的值与输出比较寄存器OCR2的值作比较,一旦发现二者相等,比较器立即产生一个匹配信号,并在下一个定时器时钟到来时置位OCF2标志位,如果此中断得到允许,将引发输出比较中断。中断执行后,标志位OCF2自动清零,也可以通过软件对该位写1以清零此标志位。

波形发生器利用比较结果产生PWM波形或在比较输出引脚OC2输出可变频率的信号。当T/C2工作在比较输出模式或PWM模式时,引脚OC2的功能由配置寄存器使能(TCCR2寄存器的COM21:COM20位),但引脚的方向需要设定为输出。

3.同步控制单元

同步控制单元用于控制T/C2的工作状态,它决定T/C2是工作于使用系统时钟的同步状态还是使用外部时钟的异步状态。工作状态的设定是通过异步状态寄存器ASSR的AS2位来实现的,通过ASSR寄存器,还可以对TCNT2及OCR2寄存器的状态进行监控。

10.1.2

T/C2的工作模式

按照配置的不同,T/C2可以配置成以下几种模式:

1.普通模式(定时器模式)

普通模式是最基本的工作模式,在此模式下,计数器TCNT2的值在计数时钟的驱动下不停地累加,当计数到达最大值0xFF后,在下一个时钟到来时产生计数溢出,计数值返回到0x00并重新开始计数。在计数器TCNT2为0x00的同时,T/C2溢出标志位TOV2置位。如果T/C2溢出中断得到使能,就会引发单片机执行中断服务程序,一旦中断服务程序得到执行,TOV2标志位会硬件清零。在普通模式下,用户可以随时软件写入寄存器TCNT2。

2.CTC模式(比较匹配清零定时器模式)

在此模式下输出比较寄存器OCR2用于保存匹配值,计数器TCNT2的值持续累加,当TCNT2的值等于OCR2时,二者产生匹配,随后计数器TCNT2的值会清零,并且相应的中断标志位OCF2会置位,如果此中断得到使能,即可执行中断服务程序。T/C2的CTC模式时序如图10-2所示。

在CTC模式下,将引脚OC2的数据方向设定为输出,引脚上将会产生电平变化,具体变化方式由T/C2控制寄存器TCCR2的COM21:COM20位决定。为了使OC2引脚能输出正确的波形,可以将引脚电平变化的方式设定为比较匹配时电平取反,其频率可由下式计算:

比较器输出频率=系统时钟(或异步时钟)/[2×N×(1+寄存器OCR2值)]

在上面的公式中,N为预分频因子,其值可以为1、8、32、64、128、256或1024。

3.快速PWM模式

快速PWM模式是基于单斜坡操作的,这有利于产生更高频率的PWM波形。在快速PWM模式下,计数器从BOTTOM计到MAX,然后立即返回到BOTTOM并重新开始计数。当计数器TCNT2的值与OCR2的值匹配时,引脚OC2上的电平将会按照TCCR2寄存器COM21:COM20位设定的方式动作。T/C2的快速PWM模式时序如图10-3所示。

与T/C0相同的是,T/C2在快速PWM方式下,由于计数器TCNT2的计数值是从BOTTOM计到MAX,所以PWM的周期也是一个固定的值,在图10-3中,快速PWM的工作过程如下:

·A点:计数器的值为最小值BOTTOM,此时OC2引脚输出高电平。

·B点:计数器TCNT2的值不断累加到与OCR2的值匹配时,OC2引脚电平翻转并输出低电平,输出比较中断标志位OCF2置位。

·C点:计数器TCNT2计数达到最大值MAX,T/C2的溢出标志位TOV2置位,此时OCR2寄存器中保存的值会进行一次更新,此更新可以改变PWM波形的占空比。

·D点:计数器TCNT2由于溢出而清零到BOTTOM,OC2引脚电平翻转,输出高电平。

快速PWM模式下的输出频率可由下式计算:

PWM频率=系统时钟频率(异步时钟频率)/(N×256)

在上面的公式中,N为预分频因子,其值为1、8、32、64、128、256或1024。

4.相位修正PWM模式

相位修正PWM模式是基于双斜坡操作的。在此模式下,计数器TCNT2重复地从BOTTOM计数到MAX,然后再从MAX倒退计数到BOTTOM。T/C2的相位修正PWM模式的时序如图10-4所示。

在图10-4所示的相位修正PWM模式中,其工作方式如下:

·A点:计数器TCNT2因上一次计数达到MAX值,这时比较匹配寄存器OCR2的值得到更新,这个更新可以用于改变PWM波形的占空比,也是一个新PWM周期的开始,此时OC2引脚电平翻转,按照COM21:0位的设定,引脚输出低电平。

·B点:计数器TCNT2反向计数到OCR2指定的匹配值,这时输出比较标志位OCF2置位,按照COM21:COM20位的设定,引脚OC2电平再次翻转,输出高电平。

·C点:计数器清零并重新开始正向计数,计数器溢出且中断标志位TOV2置位。

·D点:计数器TCNT2正向计数到OCR2指定的匹配值,引脚OC2输出低电平,输出比较标志位OCF2置位。

·E点:计数器TCNT2正向计数到达最大值MAX,比较匹配寄存器OCR2的值再次得到更新,本次PWM周期结束。

相位修正PWM方式的输出频率可由下式计算:

PWM频率=系统时钟频率(异步时钟频率)/(N×510)

N为预分频因子,其值可为1、8、32、64、128、256或1024。

10.2

T/C2的控制

10.2.1

T/C2的相关寄存器

1.TCCR2寄存器

该寄存器是T/C2的控制寄存器,包含了多个T/C2的模式控制位和比较匹配单元输出模式控制位。

TCCR2寄存器:T/C2控制寄存器

bit 7FOC2:强制输出比较控制位。该位置1时将强制OC2引脚进入比较匹配的状态,具体由COM21:COM20位设定。强制输出比较匹配状态不会引发中断,而且此位只在非PWM模式时有效,在PWM模式下不可将该位置1。

bit 6,3WGM21:WGM20:波形发生模式设定位,用于设定T/C2的工作状态,具体详见表10-1。

bit 5:4COM21:COM20:比较匹配输出模式设定位(OC2引脚),具体详见表10-2。

bit 2:0CS22:CS20:T/C2时钟源选择位,用于选择T/C2的时钟源或设定预分频比,具体详见表10-3。

注意:虽然引脚OC2的比较输出状态由寄存器TCCR2的COM21:COM20位控制,但它也同时受引脚的方向寄存器控制,使用时需要将其设定为输出,才能在OC2引脚上正常输出信号。

2.TCNT2寄存器

该寄存器是T/C2的数据寄存器,用于保存定时或计数值,TCNT2寄存器可以随时读写。

TCNT2寄存器:T/C2的数据寄存器

3.OCR2寄存器

T/C2的输出比较寄存器,该寄存器中的数值与TCNT2的计数值进行连续的比较,一旦数据匹配,将产生一个输出比较中断,并且可以改变OC2引脚的电平状态。

OCR2寄存器:输出比较寄存器

4.ASSR寄存器

T/C2的异步状态控制寄存器,包含了多个T/C2异步工作状态设定位以及T/C2的相关状态位。

ASSR寄存器:异步状态寄存器

bit 7-4未用位。

bit 3AS2:T/C2异步模式选择位。该位置1时T/C2由连接于TOSC1和TOSC2引脚的晶体振荡器驱动,清零时T/C2由系统时钟驱动。

bit 2TCN2UB:T/C2更新状态位。当T/C2工作在异步模式时,写TCNT2寄存器将引起TCN2UB位置1,TCNT2寄存器更新完毕后,TCN2UB位硬件清零。

bit 1OCR2UB:输出比较寄存器2更新状态位。当T/C2工作在异步模式时,写OCR2寄存器将引起OCR2UB位置1,OCR2寄存器更新完毕后,TCN2UB位硬件清零。

bit 0TCR2UB:T/C2控制寄存器更新状态位。当T/C2工作在异步模式时,写TCCR2寄存器将引起TCR2UB位置1,TCCR2寄存器更新完毕后,TCR2UB位硬件清零。

注意:当更新标志位TCN2UB、OCR2UB和TCR2UB位清零时,即表示可以向其相关寄存器中写入新值。如果在更新标志位为1时写入上述相关寄存器将会破坏数据。

5.TIMSK寄存器

该寄存器是T/C的中断屏蔽寄存器,该寄存器包含了多个定时/计数器的中断控制位。

TIMSK寄存器:T/C中断屏蔽寄存器

bit 7OCIE2:T/C2输出比较匹配中断使能位。该位置1时,T/C2输出比较匹配中断使能。

bit 6TOIE2:T/C2溢出中断使能位。该位置1时,T/C2溢出中断使能。

bit 5-0暂不介绍。

6.TIFR寄存器

该寄存器是T/C的中断标志寄存器,该寄存器包含了多个定时/计数器的中断标志位。

TIFR寄存器:T/C中断标志寄存器

bit 7OCF2:T/C2输出比较匹配标志位。当TCNT2与OCR2匹配时该位置1。当此中断服务程序被执行后,该位自动清零。软件对该位写1会清零此标志位。

bit 6TOV2:T/C2溢出标志位。T/C2溢出时该标志位置1,当此中断服务程序被执行后,该位自动清零。软件对该位写1会清零此标志位。

bit 5-0:暂不介绍。

10.2.2

T/C2的预分频器

ATmega32单片机的T/C2模块具有自己独立的预分频器,其结构如图10-5所示。

T/C2预分频器的输入时钟称为clk SFIOR寄存器。该寄存器是特殊功能IO寄存器,包含了多个与A/D转换、模拟比较器相关的功能控制位。

SFIOR寄存器:特殊功能IO寄存器

bit 7-2:暂不介绍。

bit 1PSR2:T/C2预分频器复位控制位。该位置1时T/C2的预分频器复位,操作完成后该位硬件清零。

bit 0:暂不介绍。

10.3

T/C2的编程应用

T/C2模块的特点是可以使用外接于TOSC1和TOSC2引脚的晶振作为时钟信号,利用这一特点可以使单片机在低功耗模式下维持时钟的运行。以下我们要使用T/C2模块,配合外接的晶振,制作另外一款数显电子钟。打开Atmel Studio 6.1软件,新建名为“TC2RTC”的项目,保存在chapter10文件夹下,软件会将名为TC2RTC.c的源文件自动添加到新建的项目中,编辑TC2RTC.c源文件,具体代码详见代码清单10-1。

代码清单10-1

基于T/C2的实时时钟

/*

*

TC2RTC.c *

TC2

实时时钟+

数码管显示

*

Created: 2013/9/15

21:06:39

*

Author: GAO */

#include 
//
包含AVR 头文件
#include 
//
包含AVR 中断控制头文件
#define F_CPU 16000000UL //
定义系统时钟
#include 
//
包含延时函数头文件
unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f }; //
共阴无点
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed, 0xfd,0x87,0xff,0xef }; //
共阴有点
unsigned int SEC,NUM; //
定义秒变量,显示变量
void display(unsigned int NUM); //
数码管显示函数声明
void TC2_init(void); //
定时器2
初始化函数声明
int main(void)
{
DDRA=0xFF; //
设数码管段驱动端为输出
DDRB=0xF0; //
设数码管位驱动端为输出
TC2_init(); NUM=510; //
设定最初时间为08:30
while(1)
{
display(NUM); }
}
/**********
数码管显示函数**********/
void display(unsigned int NUM)
{
unsigned char NUM4,NUM3,NUM2,NUM1; NUM1=NUM%10; NUM2=NUM%60/10; NUM3=NUM%600/60; NUM4=NUM/600; PORTA=table0[NUM1]; PORTB=0x10; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms PORTA=table0[NUM2]; PORTB=0x20; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms if(SEC%2==1)
//
点闪烁
{
PORTA=table0[NUM3]; PORTB=0x40; _delay_ms(2); //
延时2ms }
else {
PORTA=table1[NUM3]; PORTB=0x40; _delay_ms(2); //
延时2ms }
PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms PORTA=table0[NUM4]; PORTB=0x80; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms }
/**********T/C2
初始化函数**********/
void TC2_init(void)
{
SREG=0x80; TIMSK=0x40; //
开T/C2
溢出中断
TCNT2=(256-128); //
初值128,32768/256=128Hz TCCR2=0x06; //
设定T/C2
普通模式,预分频比1/256
ASSR=0x08; //
开T/C2
异步模式
}
/**********T/C2
中断服务函数**********/
ISR(TIMER2_OVF_vect)
{
TCNT2=(256-128); //
初值128
,周期1S SEC++; if(SEC>=60)
{
SEC=0; NUM++; }
if(NUM>=1440)
{
NUM=0; }
}
/**********
结束**********/
将以上代码编译后,下载到AVR系统板中,程序运行后如图10-6所示。数码管显示当前时间为“08.30”,时与分之间的小数点以秒为周期闪烁,指示时钟正在运行。这里需要特别说明的是,此时T/C2的运行已经不再需要系统时钟的支持了。
通过前面的学习,我们已经掌握了ATmega32单片机定时/计数器的基本用法,这也是学好AVR单片机的关键所在。AVR单片机定时/计数器功能之强大在主流的8位单片机中可谓无出其右,灵活地使用这三个定时/计数器可以帮助你开发出诸如时钟、信号发生器、频率计以及PWM控制器等诸多与时间相关的衍生产品。

 


评论:

AVR单片机基础教程

作者:高显生   共18讲

AVR系列单片机是8位单片机中第一个真正的RISC结构单片机,它采用了大型快速存取寄存器组、快速的单周期指令系统以及单级流水线等诸多先进技术,使得AVR单片机具备了高达1MIPS/MHz的运行处理能力。