AVR_Timer

AVR定时/计数器的结构与应用

一、定时/计数器的结构

1.1 学习和使用定时/计数器,需要注意的基本要素

  • 定时/计数器的长度
    • 一般为8位(1字节)和16字节(2字节)
    • 其中TC0/TC2为8位,TC1为16位
  • 脉冲信号源
    • 可以由单片机外部提供,也可以由单片机内部提供
  • 计数器类型
    • 加1(减1)计数器
    • 单向计数器
    • 双向计数器
  • 计数器上限
    • 计数器的下限是0
    • 计数器上限为计数器的最大值,即255(8位),65535(16位)
  • 计数器的事件
    • 计数器的事件是指计数器处于某种状态时的输入信号,该信号可以向MCU申请中断。例如,当计数器达到上限值255时,产生溢出中断信号,向MCU申请中断
  • 需要使用中断程序,中断详见我之前发表的关于AVR中断的博客,里面有详细介绍和使用方法。

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

  • 1、ATMega16中有两个8位计数器:T/C0和T/C2,他们都是通用多功能定时/计数器,其主要特点如下:
    • 单通道计数器
    • 比较匹配清 0 计数器(自动重装特性
    • 可产生无抖动的,相位可调的脉宽调制(PWM)信号输出
    • 频率发生器
    • 外部事件计数器(仅 T/C0
    • 10位时钟预分配器
    • 溢出和比较匹配中断源(TOV0、OCF0和TOV2、OCF2)
    • 允许使用外部引脚的32768HZ晶体作为独立的计数时钟源(仅T/C2)
  • 2、T/C0的组成结构
    • T/C0中,有两个8位寄存器:
      • 计数寄存器TCNT0
      • 输出比较寄存器OCR0
    • 其他相关的寄存器有:
      • T/C0 控制寄存器TCCR0
      • T/C0 中断标志寄存器TIFR
      • T/C0 定时器中断屏蔽寄存器TIMSK
    • T/C0 的计数器事件输出信号有两个:
      • 计数器计数溢出TOV0
      • 比较匹配相等OCF0
  • 3、T/C0的时钟源
    • 信号可以来自外部也可以来自内部
    • 时钟源的选择
      • T/C0的时钟源选择由T/C0的控制寄存器TCCR0中的三个标志位 CS0[2:0] 确定,共有8中选择。详见后。
  • 4、T/C0的计数单元
    • T/C0的计数单元是一个可编程的8位双向计数器
      • 计数:TCNT0 加 1 或者是 减 1
      • 方向:加或减的控制
      • 清除:清 0 TCNT0
      • 计数时钟源:C/T0时钟源
      • 顶部值:表示TCNT0的计数上限
      • 底部值:表示TCNT0的计数下限

1.3 与8位 T/C0 相关的寄存器

  • 1)T/C0计数寄存器TCNT0
    • TCNT0是T/C0的计数值寄存器,可以被 MCU 直接访问
    • 设置初值之后,在默认情况下,在满足加减条件时,该寄存器会自动计数并保存计数值
76543210
$32($0052)
读/写R/WR/WR/WR/WR/WR/WR/WR/W
初始化值00000000
  • 2)输出比较寄存器OCR0
    • 8位寄存器OCR0中的数据用于与寄存器TCNT0中的计数值相比较,在T/C0运行期间,比较匹配单元将会一直将寄存器TCNT0和寄存器OCR0的内容相比较。
    • 一旦匹配,则会输出一个T/C0匹配中断的请求,或改变OC0的输出逻辑电平
76543210
$3C($005C)
读/写R/WR/WR/WR/WR/WR/WR/WR/W
初始化值00000000
  • 3)定时/计数中断屏蔽寄存器TIMSK
    • 位7(位1)——OCIE2(OCIE0):T/C2(T/C0)输出比较匹配中断允许标志位
    • 位6(位0)——TOIE2(TOIE0):T/C2(T/C0)溢出中断允许标志位
76543210
$39($0059)OCIE2TOIE2TICIE1OCIE1AOCIE1BTOIE1OCIE0TOIE0
读/写R/WR/WR/WR/WR/WR/WR/WR/W
初始化值00000000
  • 4)定时/计数中断标志寄存器TIFR
    • 位7(位1)——OCF2(OCF0):T/C2(T/C0)输出比较匹配中断标志位
    • 位6(位0)——TOV2(TOV0):T/C2(T/C0)溢出中断标志位
    • 写入一个逻辑“1”到OCF2(OCIE2)和OCF0(OCIE0),将该标志位清“0”。
    • 写入一个逻辑“1”到TOIE2(TOV2)和TOIE0(TOV0),将该标志位清“0”。
76543210
$38($0058)OCF2TOV2ICF1OCF1AOCF1BTOV1OCF0TOV0
读/写R/WR/WR/WR/WR/WR/WR/WR/W
初始化值00000000
  • 5)T/C0控制寄存器TCCR0(特别注意!!!!)
    • 位7——FOC0:强制输出比较位。
      • 只在T/C0设置为非PWM模式下工作才有效
      • 在PWM模式下写TCCR0寄存器时,该位必须清 0
      • 当将一个逻辑“1”写到FOC0位时,会强加在波形发生器上一个比较匹配成功信号,使波形发生器依据COM[1:0]的设置改变OC0的输出状态
    • 位[3:6]——WGM[1:0]:波形发生模式位。模式设置详见表格。(需要特别注意这两位在寄存器中的位置!!!!)
    • 位[5:4]——COM[1:0]:比较匹配输出方式位。详细设置请参照表格。
      • 在普通模式和非PWM模式(CTC模式)下(WGM0 = 0、2)时的COM[1:0]位功能定义。
      • 在快速模式下(WGM0 = 3)时的COM[1:0]位功能定义。
      • 相位可调PWM模式(WGM0 = 1)时的COM[1:0]位功能定义。
    • 位[2:0]——CS0[2:0]:T/C0时钟源选择。
76543210
$38($0058)FOC0WGM00COM01COM00WGM01CS02CS01CS00
读/写R/WR/WR/WR/WR/WR/WR/WR/W
初始化值00000000

T/C0的波形产生模式:

模式WGM01WGM00T/C0工作模式计数上限值OCR0更新TOV0置位
000普通模式0xFF立即0xFF
101PWM相位可调0xFF0xFF0x00
210CTC模式OCR0立即0xFF
311快速PWM0xFF0xFF0xFF

在普通模式和非PWM模式(CTC模式)下(WGM0 = 0、2)时的COM[1:0]位功能定义(此模式使用最多!!)

COM01COM00说明
00PB3为通用 I / O 引脚(OC0与引脚不连接)
01比较匹配时,触发OC0(OC0为原OC0的取反)
10比较匹配时,清零OC0
11比较匹配时,置位OC0

在快速PWM模式下(WGM0 = 3)时的COM[1:0]位功能定义。

COM01COM00说明
00PB3为通用 I / O 引脚(OC0与引脚不连接)
01保留
10比较匹配时,清零OC0;计数值为0xFF时,置位OC0
11比较匹配时,置位OC0;计数值为0xFF时,清零OC0

相位可调PWM模式(WGM0 = 1)时的COM[1:0]位功能定义。

COM01COM00说明
00PB3为通用 I / O 引脚(OC0与引脚不连接)
01保留
10向上计数过程中比较匹配时,清零OC0;向下计数过程中比较匹配时,置位OC0
11向上计数过程中比较匹配时,置位OC0;向下计数过程中比较匹配时,清零OC0

T/C0的时钟源选择

CS02CS01CS00说明
000无时钟源(停止T / C0)
001CLKt0s(不经过分频器)
010CLKt0s / 8(来自预分频器)
011CLKt0s / 64(来自预分频器)
100CLKt0s / 256(来自预分频器)
101CLKt0s / 1024(来自预分频器)
110外部T0引脚,下降沿驱动
111外部T0引脚,上升沿驱动

1.4 8位T / C0的工作模式

  • T /C0的控制寄存器TCCR0的标志位WGM[1:0]和COM[1:0]组成了 T / C0 的 4 种工作模式,以及OC0的不同方式的输出。
  • 1)普通模式(WGM[1:0] = 0):这是 T / C0 最简单、最基本的一种工作方式。
    • 在普通模式下,T / C0为单向加 1 计数器。一旦寄存器 TCNT0 的值达到了0XFF(上限值),在下一个脉冲到来的时候便恢复为 0x00 ,并继续加 1 计数。
    • 因为在溢出的时候,TCNT0 变为 0x00 ,溢出标志位TOV0变为 1 ,因此溢出标志位TOV0可以作为计数器的第九位使用,需要配合软件。
    • 用户可以随时改变计数寄存器 TCNT0 的值
  • 2)比较匹配清 0 计数器 CTC 模式(WGM[1:0] = 2):
    • T / C0在 CTC 模式下,计数器为单向加 1 计数器,一旦寄存器 TCNT0 的值和 OCR0 的设定值相等(此时寄存器 OCR0 为计数的上限),就将 TCNT0 清0,继续加 1 计数,输出比较匹配, OCF0 的值设置为 1 ,申请中断。
    • OC0输出波形的最高频率为 foc0 = fclk / 2 ,(OCR0 = 0X00)
      • 下式中 N 的取值为 1 , 8 , 64 , 256 , 1024

fco0=fclk2N(1+OCR0)

  • 3)快速PWM模式(WGM[1:0] = 3):
    • T / C0工作在快速PWM模式下可以产生较高频率的PWM波形
    • 计数器为单向加 1 计数器。从 0x00 加到 0xff ,下一个脉冲置为 0x00。
    • 快速PWM模式采用单程计数,因此可以产生比相位可调PWM模式高 1 倍频率的PWM波
    • OC0输出的PWM波形频率输出由下式决定:
      • 下式中 N 的取值为 1 , 8 , 64 , 256 , 1024

fco0pwm=fclk256N

  • 4) 相位可调PWM模式(WGM[1:0] = 1):
    • 相位可调PWM模式可以产生高精度的相位可调的PWM波形
    • 计数器为双程计数器
    • 先从0x00到0xff向上加 1 ,再下一次脉冲到来的时候改变计数方向,从0xff到0x00向下减 1 。在COM[1:0] = 2时,向上计数过程中比较匹配时,清零OC0;向下计数过程中比较匹配时,置位OC0;在COM[1:0] = 3时,向上计数过程中比较匹配时,置位OC0;向下计数过程中比较匹配时,清零OC0。
    • 在相位可调PWM模式下, OC0输出的PWM波形频率输出由下式决定:
      • 下式中 N 的取值为 1 , 8 , 64 , 256 , 1024

fco0pcpwm=fclk510N

二、8位定时/计数器的简单应用

  • WINAVR平台
/**
*作者:Dandri
*时间:2017/02/01
*MCU:ATMega16
*频率:8MHz
*功能:LED灯不断亮灭,每次亮灭间隔时间为1S
*/

#include <avr/io.h>
#include <avr/interrupt.h>

unsigned char flag = 0;         //等待1ms完成标志

//端口初始化
void port_init()
{
   PORTA = 0X00;
   DDRA = 0X01;
}

//tc0相关寄存器初始化
void tc0_init()
{
   TCNT0 = 0X00;            //计数寄存器清0
   TIMSK = 0X02;            //T/C0比较匹配允许
   TCCR0 = 0X0B;            //0000 1011 CTC模式,OC0不接PB3,64分频
   OCR0 = 0X7D;             //晶振8M,64分频,延时1ms需要计数8000000/(1000*64) = 125次
}

//中断向量区程序
#pragma interrupt_handler tc0_isr:20   //首先使用#pragma interrupt_handler int0_isr:20声明中断,20表示中断向量号
void tc0_isr(void)
{
   flag = 1;
}

//延时函数,延时1ms
void delay(long c)
{
   for (;c > 0;c--)
   {
      flag = 0; 
      TCNT0 = 0X00;         //计数寄存器清0
      while(!flag)
     asm("nop");
   }
}

//亮灯程序
void led(void) 
{
   PORTA = 0X01;
   delay(1000);
   PORTA = 0X00;
   delay(1000);
}

int main()
{ 
   port_init();
   tc0_init();

   while (1)
      led();

   return 0;
}

三、PWM脉宽调制波

3.1 PWM脉宽调制波

  • PWM实际上是脉宽调制的简称。*PWM也是一个连续的方波,但是,在一个周期中,其高电平和低电平的占空比是不同的。*
  • 如图:T 是 PWM 波的周期,T1 是高电平的宽度,Vcc是高电平值。当PWM波通过一个积分器(低通滤波器)之后,可以得到平均的输出电压为:
    • T1 / T 为 PWM 波的占空比。调节 T1 的宽度可以改变 PWM 的不同占空比,得到不同的平均输出电压值。
      • 实现D/A转换
      • 调节电压或电流控制电机转速
      • 实现变频控制

V=VccT1T

  • 一个PWM方波的参数有:频率,占空比为主要因素,相位为次要因素
  • 根据PWM的特点,在使用AVR定时/计数器的时候应该注意以下几点:
    • 根据实际情况,确定 PWM 的频率范围
    • 考虑占空比的调节精度
    • 因为PWM本身还是数字脉冲波,则需要一个好的积分电路,将高频有效的成分去掉,从而获得较好的模拟信号
  • ATMega16 的 T / C0 和 T / C2 都可以产生PWM波,因为计数器是8位的,所以是固定 8 位精度的PWM波发生器。

  • 快速 PWM 波模式:可以得到频率较高,相位固定的PWM输出,适合一些要求输出PWM频率较高、频率相位固定的应用中

    • 其频率计算公式为:

    PWM=256

  • 相位可调PWM模式:此时计数器工作在双向计数方式,适用于 PWM 频率较低,频率固定的应用中。

    • 其频率计算公式为:

    PWM=510

  • T / C0 和 T / C2 两种PWM模式都输出固定8位的PWM波,计数器 TCNTn 的上限值为固定的0XFF,而比较寄存器 OCRn 的值与计数器上限值之比即为占空比!!!

4.2 PWM 应用实例

  • WINAVR 平台:
/**
*作者:Dandri
*时间:2017/02/01
*MCU:ATMega16
*频率:8MHz
*功能:在 PB3 引脚输出频率为1000HZ的正弦波模拟信号
*/

#include <avr\io.h> 

#pragma data:code 
// 128点正弦波样本表 
const unsigned char auc_SinParam[128] = { 
64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,109,111,113,115,117,118,120,121, 
123,124,125,126,126,127,127,127,127,127,127,127,126,126,125,124,123,121,120,118, 
117,115,113,111,109,106,104,102,99,96,94,91,88,85,82,79,76,73,70,67,64,60,57,54,51,48, 
45,42,39,36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,1,0,0,0,0,0,0,0,1,1,2,3,4,6, 
7,9,10,12,14,16,18,21,23,25,28,31,33,36,39,42,45,48,51,54,57,60}; 
#pragma data:data 

unsigned char x_SW = 8,X_LUT = 0; 

#pragma interrupt_handler timer0_ovf_isr:17 
void timer0_ovf_isr(void) 
{ 
   X_LUT += x_SW; // 新样点指针 
   if (X_LUT > 127) X_LUT -= 128; // 样点指针调整 
   OCR0 = auc_SinParam[X_LUT]; // 取样点指针到比较匹配寄存器 
} 

void main(void) 
{ 
   DDRB |= 0x08; // PB3(OC0)输出 
   TCCR0 = 0x71; // 相位调整PWM模式,分频系数=1,正向控制OC0 
   TIMSK = 0x01; // T/C0溢出中断允许 
   asm("SEI"); // 使能全局中断 
   while(1) 
      asm("nop"); 
} 

四、16位定时/计数器 T / C1

4.1 16位定时/计数器 T / C1的主要特点

  • 真正 16 位设计
  • 2 个独立的输出比较匹配单元
  • 双缓冲输出比较寄存器
  • 1 个输入捕捉单元
  • 比较匹配清 0 计数器(自动重装特性)
  • 可产生无抖动的、相位可调的脉宽调制信号(PWM)输出
  • 周期可调的 PWM 波形输出
  • 频率发生器
  • 外部事件计数器
  • 10 位时钟预分频器
  • 4 个独立的中断源(TOCV1 , OCFIA , OCFIB , ICF1)

4.2 16位定时/计数器 T / C1增强功能介绍

  • 是十六位计数器,配合一个独立的十位预定比例分频器,在系统时钟为 4 MHz 的条件下,精度可达0.25us,最长时间宽度为16.777216 s(精度为256us)
  • 十六位寄存器 TCNT1 实际上是由 2 个 8 位寄存器 TCNT1H 和 TCNT1L 组成的
  • 16位定时/计数器 T / C1的读/写操作
    • 读操作:
      • 读取 16 位寄存器低 8 位时,16 位寄存器低 8 位被送到 MCU ,高 8 位放到临时辅助寄存器 TEMP 中;读取高 8 位时,读到的是 TEMP 中的内容。因此,同步读取 16 位寄存器,应该先读取低字节,再读取高字节!!!
    • 写操作:
      • 当 MCU 写入数据到 16 位寄存器的高字节时,数据先写入 TEMP ;当 MCU 写入数据到 16 位寄存器的低字节时,写入的 8 位数据与 TEMP 中的 8 位数据组合为一个 16 位数据。,因此,要同步写入 16 位寄存器,应该先写入该寄存器的高位字节,再写入低位字节!!!

4.3 输入捕捉功能

  • T / C1的输入捕捉功能是 AVR 定时/计数器特有的功能。可用于精确捕捉一个外部事件的发生。记录事件发生的时间印记。捕捉信号由引脚 ICP1 输入,或者由模拟比较器的 AC0 单元的输出信号也可作为外部事件捕获的触发信号。
  • 当一个捕捉事件发生时, T / C1 的计数器 TCNT1 中的计数值被写入输入捕捉寄存器 ICR1 中,并置位输入捕获标志位 ICF1 ,产生中断申请。
  • 输入捕捉可用于频率和周期的精确测量!
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值