AVR_Timer
来源:互联网 发布:访问网络电脑需要密码 编辑:程序博客网 时间:2024/05/17 05:15
AVR定时/计数器的结构与应用
一、定时/计数器的结构
1.1 学习和使用定时/计数器,需要注意的基本要素
- 定时/计数器的长度
- 一般为8位(1字节)和16字节(2字节)
- 其中TC0/TC2为8位,TC1为16位
- 脉冲信号源
- 可以由单片机外部提供,也可以由单片机内部提供
- 计数器类型
- 加1(减1)计数器
- 单向计数器
- 双向计数器
- 计数器上限
- 计数器的下限是0
- 计数器上限为计数器的最大值,即255(8位),65535(16位)
- 计数器的事件
- 计数器的事件是指计数器处于某种状态时的输入信号,该信号可以向MCU申请中断。例如,当计数器达到上限值255时,产生溢出中断信号,向MCU申请中断
- 需要使用中断程序,中断详见我之前发表的关于AVR中断的博客,里面有详细介绍和使用方法。
- http://blog.csdn.net/dandri/article/details/54799300
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
- T/C0中,有两个8位寄存器:
- 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的计数下限
- T/C0的计数单元是一个可编程的8位双向计数器
1.3 与8位 T/C0 相关的寄存器
- 1)T/C0计数寄存器TCNT0
- TCNT0是T/C0的计数值寄存器,可以被 MCU 直接访问
- 设置初值之后,在默认情况下,在满足加减条件时,该寄存器会自动计数并保存计数值
- 2)输出比较寄存器OCR0
- 8位寄存器OCR0中的数据用于与寄存器TCNT0中的计数值相比较,在T/C0运行期间,比较匹配单元将会一直将寄存器TCNT0和寄存器OCR0的内容相比较。
- 一旦匹配,则会输出一个T/C0匹配中断的请求,或改变OC0的输出逻辑电平
- 3)定时/计数中断屏蔽寄存器TIMSK
- 位7(位1)——OCIE2(OCIE0):T/C2(T/C0)输出比较匹配中断允许标志位
- 位6(位0)——TOIE2(TOIE0):T/C2(T/C0)溢出中断允许标志位
- 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”。
- 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时钟源选择。
- 位7——FOC0:强制输出比较位。
T/C0的波形产生模式:
在普通模式和非PWM模式(CTC模式)下(WGM0 = 0、2)时的COM[1:0]位功能定义(此模式使用最多!!):
在快速PWM模式下(WGM0 = 3)时的COM[1:0]位功能定义。
相位可调PWM模式(WGM0 = 1)时的COM[1:0]位功能定义。
T/C0的时钟源选择
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
- 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
- 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
二、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;}//延时函数,延时1msvoid 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转换
- 调节电压或电流控制电机转速
- 实现变频控制
- T1 / T 为 PWM 波的占空比。调节 T1 的宽度可以改变 PWM 的不同占空比,得到不同的平均输出电压值。
- 一个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 0
- AVR_Timer
- 2.3链表的补充
- Java-面向对象编程-三大特性之多态
- [玲珑杯#Round8] XJT Love Strings KMP+树上倍增
- java web给手机端写接口HttpServletRequest ,HttpServletResponse
- Arpa's weak amphitheater and Mehrdad's valuable Hoses CodeForces - 742D
- AVR_Timer
- Python基础_1
- leetcode reorder-list(java实现)
- 重点:linux执行操作命令
- 欢迎使用CSDN-markdown编辑器
- redis 管理工具
- 后缀数组
- Android之使用JavaWeb项目作为后台的实现
- 关于linux-Centos 7下mysql 5.7.9的rpm包的安装方式