ATmega16一共配置了2个8位和1个16位,共3个定时计数器,它们是8位的定时计数器T/C0、T/C2和16位的定时计数器T/C1。功能强大,但也非常复杂,不易掌握,欢迎大家讨论:
1、谈谈AVR定时器的学习方法,各定时器的优缺点及最佳使用场合
2、在使用AVR过程中,对AVR定时器的应用,欢迎贴出你的代码
3、你在使用AVR定时器过程中碰到的疑难问题,怎么解决的,或未解决的需要帮忙的
AVR定时器知识要点总结:
1、 定时器数量:分别是T/C0、T/C2、T/C1 ;ATmega16一共配置了2个8位和1个16位,共3个定时计数器,它们是8位的定时计数器T/C0、T/C2和16位的定时计数器T/C1。
2、 定时器中断源:ATmega16共有8个定时中断,分别是TIMER2 COMP、TIMER2 OVF、TIMER1 CAPT、TIMER1 COMPA、TIMER1 COMPB、TIMER1 OVF、TIMER0 OVF、TIMER0 COMP;从表1中可以得出如下结论:
a:定时器中断优先级低于复位中断、外部中断0、外部中断1,见表1;TC2的中断优先级高于TC1,TC1的中断优先级高于TC0;
b:定时器的中断向量号是从4~10,还有一个20(可以这样来记:复位中断是最高的,其次是外部中断,最后是定时中断,外部中断2是个特例,TC0比较匹配也是个特例)
c:定时器的匹配中断优先级高于其溢出中断(TC0是个特例,溢出中断优先级高于匹配中断),事件捕捉中断优先级高于匹配中断!
d:TC1有4个中断,TC0,TC2各有两个中断;
表1 mega16的中断向量区
向量号 Flash空间地址 中断源 中断定义说明
1 $000 RESET 外部引脚电平引发的复位、
上电复位、掉电检测复位、
看门狗复位、JTAG AVR复位
2 $002 INT0 外部中断请求0
3 $004 INT1 外部中断请求1
4 $006 TIMER2 COMP 定时计数器2比较匹配
5 $008 TIMER2 OVF 定时计数器2溢出
6 $00A TIMER1 CAPT 定时计数器1事件捕捉
7 $00C TIMER1 COMPA 定时计数器1比较匹配A
8 $00E TIMER1 COMPB 定时计数器1比较匹配B
9 $010 TIMER1 OVF 定时计数器1溢出
10 $012 TIMER0 OVF 定时计数器0溢出
19 $024 INT2 外部中断请求2
20 $026 TIMER0 COMP 定时计数器0比较匹配
3、 波形发生模式 T/C0、T/C2有4种波形模式,T/C1有16种波形
a:T/C0、T/C2分别由TCCR0中的两位 WGM0[1:0](位3、6)、TCCR2中的两位 WGM2[1:0](位3、6)来控制;
b: T/C1则由TCCR1B中的两位WGM1[3:2](位4、3)和TCCR1A中的两位WGM1[1:0](位1、0)
4、 比较匹配输出方式:T/C0、T/C2有4比较匹配输出模式,T/C1有16种波形
a:T/C0中的COM0[1:0](TCCR0位5,4)控制比较匹配输出模式,非PWM模式WGM = [0,2]有4种输出模式,PWM模式WGM = [1,2]有3种输出模式
b:T/C2中的COM2[1:0](TCCR2位5,4)控制比较匹配输出模式,非PWM模式WGM = [0,2]有4种输出模式,PWM模式WGM = [1,2]有3种输出模式
c:T/C1中的COM1A[1:0](TCCR1A位7,6)控制通道A比较匹配输出模式, T/C1中的COM1B[1:0](TCCR1A位5,4)控制通道B比较匹配输出模式,各有四种输出模式
5、 各定时器的最佳使用场合(不知道,望各位网友讨论补充)
a:TC0
b:TC1
c:TC2
第二部分:定时器0 T/C0
定时器0有两个中断源TIMER0 OVF(溢出中断)和TIMER0 COMP(比较匹配中断),中断向量号分别为10和20;在三个定时器中,T/C0的中断级别最低。(PS:既然TIMER0 OVF(溢出中断)比TIMER0 COMP(比较匹配中断)优先级要高,那么T/C0主要用在计数方面吧?^-^ ^-^)
1、 T/C0的时钟源 T/C0的计数时钟源可由来自外部引脚T0(PB0)的信号提供,也可来自芯片的内部。时钟源的选择由TCCR0中的3个标志位CS0[2:0]确定,共有8种选择:无时钟;内部时钟有5种分频选择(1,8,64,256,1024);外部时钟有2种(下降沿和上升沿)。
a:当定时计数器使用系统内部时钟作为计数源时,通常作为定时器和波形发生器使用。
注意:有5种分频选择(1,8,64,256,1024),同T/C1共用一个预定比例分频器,两者分别使用了CS02 CS01 CS00 和 CS12 CS11 CS10 两组控制逻辑来控制最后输出,互不影响;但有一个特定的情况,预分频器复位将会影响所有与其连接的T/C。
b:当定时计数器使用外部时钟作为计数源时,通常作为计数器使用,用于记录外部脉冲的个数。使用时,需注意以下几点:
A、 由于引脚上同步与边沿监测电路的存在,引脚T0/T1 上的电平变化需要延时2.5 到3.5 个系统时钟周期才能使计数器进行更新;
B、 外部时钟脉冲宽度必须大于一个系统时钟周期;
C、 外部时钟源的最高频率不大于 fclk_I/O/2.5;
D、 外部时钟源不送入预分频。
2、T/C0比较匹配单元 8位比较器持续对TCNT0和输出比较寄存器OCR0进行比较。一旦TCNT0等于OCR0,比较器就给出匹配信号。在匹配发生的下一个定时器时钟周期输出比较标志OCF0 置位。
注意:A、PWM 模式时,使能双缓冲功能,CPU 访问的是OCR0缓冲寄存器;
B、正常工作模式和CTC模式,禁止双缓冲功能时CPU 访问的则是OCR0 本身;
C、 强制输出比较,在非PWM 模式时,可以通过对强制输出比较位FOC0写”1” 的方式来产生比较匹配。强制比较匹配不会置位 OCF0 标志,也不会重载/ 清零定时器,但是OC0 引脚将被更新,好象真的发生了比较匹配一样;
D、 写TCNT0 操作将阻止比较匹配, CPU 对TCNT0 寄存器的写操作会在下一个定时器时钟周期阻止比较匹配的发生;
E、OC0 的设置应该在设置数据方向寄存器之前完成;在使用OC0 功能之前首先要通过数据方向寄存器的DDR_OC0 位将此引脚设置为输出;
PS:双缓冲可以将更新OCR0 寄存器与top 或bottom 时刻同步起来,从而防止产生不对称的PWM 脉冲,消除了干扰脉冲。不理解该段描述含意!
3、工作模式 工作模式- T/C 和输出比较引脚的行为- 由波形发生模式(WGM01:0) 及比较输出模式(COM01:0) 的控制位决定。比较输出模式对计数序列没有影响,而波形产生模式对计数序列则有影响。COM01:0 控制PWM 输出是否为反极性。非PWM 模式时COM01:0 控制输出是否应该在比较匹配发生时置位、清零,或是电平取反
表2.1 T/C0的工作模式
模式 WGM01 WGM00 COM01 COM00 T/C0工作模式 计数上限值 OCR0更新 TOV0置位 说明
0 0 0 0 0 普通模式 0xFF 立即 0xFF PB3为通用I/O引脚
0 0 0 0 1 普通模式 0xFF 立即 0xFF 比较匹配时触发OC0
0 0 0 1 0 普通模式 0xFF 立即 0xFF 比较匹配时清零OC0
0 0 0 1 1 普通模式 0xFF 立即 0xFF 比较匹配时置位OC0
1 0 1 0 0 PWM,相位可调 0xFF 0xFF 0x00 PB3为通用I/O引脚
1 0 1 0 1 PWM,相位可调 0xFF 0xFF 0x00 保留
1 0 1 1 0
PWM,相位可调 0xFF 0xFF 0x00 向上计数过程中比较匹配时清零OC0
向下计数过程中比较匹配时置位OC0
1 0 1 1 1
PWM,相位可调 0xFF 0xFF 0x00 向上计数过程中比较匹配时置位OC0
向下计数过程中比较匹配时清零OC0
2 1 0 0 0 CTC模式 OCR0 立即 0xFF PB3为通用I/O引脚
2 1 0 0 1 CTC模式 OCR0 立即 0xFF 比较匹配时触发OC0
2 1 0 1 0 CTC模式 OCR0 立即 0xFF 比较匹配时清零OC0
2 1 0 1 1 CTC模式 OCR0 立即 0xFF 比较匹配时置位OC0
3 1 1 0 0 快速PWM 0xFF 0xFF 0xFF PB3为通用I/O引脚
3 1 1 0 1 快速PWM 0xFF 0xFF 0xFF 保留
3 1 1 1 0 快速PWM 0xFF 0xFF 0xFF 比较匹配时清OC0,计数值为0xFF
时置位OC0
3 1 1 1 1 快速PWM 0xFF 0xFF 0xFF 比较匹配时置OC0,计数值为0xFF
时清零OC0
4、T/C0相关存储器
========================================================================
发一个跑表程序,该程序用的是T/C0溢住中断,四位数码管动态扫秒,每为显示2MS,显示时时间0~99.99秒,经过测试正确
/************************************************************
ICC-AVR application builder : 2008-4-17 16:11:30
Target : M16
Crystal: 4.0000Mhz
文件:timer_00
设计:raosibin
时间:2008-4-17
版本:ver1.0
功能说明:T/C0中断溢出实验,每10MS中断一次,刷新显示数据;
动态扫描显示方式;
硬件说明:PA0~PA3接数玛管的A,B,C,D;PB0~PB6接a,b,c,d,e,f,g;
**************************************************************/
#include
#include
const unsigned char seg7_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f}; //0,1......9 段码
const unsigned char position_data[]={0xf1,0xf2,0xf4,0xf8}; //0,1,2,3, 位选通
unsigned char timer[4]; // 秒计数单元
unsigned char posit;
volatile char counter;
volatile char flag_10ms;
volatile char flag_2ms;
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
void display(void) // 4位LED数码管动态扫描函数
{
PORTA = 0x00;
PORTB = seg7_data[timer[posit]];
PORTA = position_data[posit];
if (++posit >=4 ) posit = 0;
}
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 2mSec
// actual value: 2.000mSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
//flag_10ms=1;
TCNT0 = 0x83; //reload counter value
flag_2ms=1;
if (++counter >=5)
{
counter=0;
flag_10ms=1;
}
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
timer[0]=0;
timer[1]=0;
timer[2]=0;
timer[3]=0;
init_devices();
/*计数数值调整,显示的范围为99.99S*/
while(1)
{
if (flag_10ms==1)
{
flag_10ms=0;
if (++timer[0]>=10)
{
timer[0]=0;
if (++timer[1]>=10)
{
timer[1]=0;
if (++timer[2]>=10)
{
timer[2]=0;
if (++timer[3]>=10)
{
timer[3]=0;
}
}
}
}
}
if (flag_2ms==1)
{
flag_2ms=0;
display();
}
}
}
http://www.mculover.com/post/51.html
文章评论(0条评论)
登录后参与讨论