T/C0 是一个八位定时器,主要有定时、外部事件计数、产生PWM 波形这几个功能,我们在使用这些功能之前,首先要设置T/C0 工作在合适的工作模式下。T/C0 有四种工作模式,分别是普通模式、CTC 模式、快速PWM、相位可调的PWM 模式四种。模式设置通过T/C0 的控制寄存器TCCR0 来完成。
1.普通模式
在此模式下,T/C0 的计数寄存器TCNT0 在时钟的驱动下不停累加。当计满后(计数值达到最大,8 位寄存器最大计数值为0xff),由于数值的溢出寄存器清零重新开始累加。当计数器溢出后,TIFR 中的溢出标志位TOV0 会置位,也可触发中断。所以我们可以通过查询或中断的方式得知定时器的溢出从而进行相关处理。此模式适合定时与计数。关于定时和计数,这里的定时功能是T/C0 在对时钟计数达到一定的值后引发中断,达到了定时功能,
然而本质的过程是计数工作。那么这里所说的计数功能是外部事件计数。
实例:T/C0 定时实验,将T/C0 设置为普通模式,对1024 分频的系统时钟进行计数,计满发生中断,40 次中断
递增一个计数用的变量,主函数则不停显示这个变量。
第一步:开总中断,SREG |= 0X80;
第二步:开T/C0 溢出中断
第三步:模式设置、分频设置、匹配输出模式设置
T/C0 控制寄存器用于设置工作模式,时钟分频和波形输出模式。这里T/C0 设置为普通模式,WGM00-WGM01设置为00。此模式下定时器的TOP 值,也就是能够达到的最大计数值为0xFF。TOV0 在计数器计满后置位,也就是计到MAX,八位的定时器计数达到255 为计满。
低三位设置定时器时钟。T/C0 在系统时钟的分频或外部时钟的驱动下递增或递减。系统时钟也就是晶振的大小是11.0592MHZ。此实验中,设置为1024 分频。11.0592MHZ 的周期是其倒数,那么1024 分频后的时钟周期就是1024*(1/11.0592),大约等于92.6。单位是微秒,一秒等于十的六次方微秒。定时器在此时钟的一个周期内增一,也就是92.6us 增加一次,计满需要255 个时钟周期,也就是说计满需要23613us 左右,从而定时器中断一次时间为23ms 左右。时钟也可以从T0 引脚输入,T0 为PB0 第二功能,此情况一般用于外部事件计数。
匹配输出模式:
T/C0 可以用作波形输出,那么OC0 就是其波形输出引脚,是PB3 引脚第二功能。波形输出功能可以使用芯片成为波形发生器,可以驱动外围部件,比如常用的电机的驱动,也可以作为外部器件的时钟。普通模式下一般不使用此功能,效率不是很高,所以这里不使用此功能,设置为COM01-COM00 为00。
综上所述:TCCR0 的设置为0B00000101,也就是0x05,FOC0 为强制匹配位,仅在非PWM 模式下有效,也就是CTC 模式和普通模式,定时器在工作时,对该位写‘1’会产生匹配,但是这种匹配只更新OC0 引脚的输出。
PWM 模式下写TCCR0 时,为了保证与未来器件兼容,要对其写0。关于匹配的概念,会在CTC 模式中讲解,在讲解普通模式和CTC 模式时,强制匹配功能都未使用,设置控制寄存器时也应写入0。
#include "avr16.h"
unsigned int num_a;
unsigned int num_b;
void Display(short int num);
#pragma interrupt_handler fun_timer0_ov:10
(中断号可以从中断一章的图中查询)
void fun_timer0_ov(void)
{
if(num_a++ > 40)
{
num_a=0;
num_b++;
if(num_b==20) (20s后显示清零,重新开始)
num_b=0;
}
}
void main()
{
num_a=0;
num_b=0;
DDRB = 0XFF;
DDRD = 0XFF; //设置为输出
CLR_PORTD(BUZZER); //关蜂鸣器
SREG|=0X80; //开总中断
TIMSK|=0x01; //开溢出中断
TCCR0 = 0X05; //普通模式/1024分频/OC0不连接
while(TRUE)
{
Display(num_b);
}
}
2.CTC 模式
此模式下,TCNT0 计数达到匹配寄存器OCR0 设置的值后清零,匹配就是说两者值相等。可以看出,和普通模式的区别就是计数能够达到的最大值可以改变,注意不是上限值。这种模式便于我们控制输出波形的频率。匹配后TIFR 寄存器的匹配标志位OCF0 置位,可以通过中断或查询的方法得知匹配事件发生,从而进行相关处理。
实例:T/C0 定时器CTC 模式实验
这个例子和上一小节的实验没有多大出入,只是采用了OCR0 匹配,匹配值120,num_a 上限改成100,也是秒计数器。
第一步:开总中断
第二步:开匹配中断
此模式下,通常设置的匹配值是小于计数上限的,就无法产生溢出中断,所以要使用匹配中断。
TIMSK|=(1<<1);
第三步:模式设置、时钟设置、匹配输出模式设置
模式设置:设置为CTC 模式,此模式下TOP 值为OCR0 的值,TOV0 在计数达到MAX 置位。OCR0 立即更新,意思是在定时器工作过程中我们修改了OCR0 的值,OCR0 就会立即更新。通常在中断程序中更新这个值,建议不要将此值更新为和BOTTOM 接近的值,BOTTOM 是寄存器能够达到的最小值,一般为0。如果更新的值过于接近BOTTOM,有可能写入的OCR0 的值小于当前TCNT0 的值,这样将失去一次匹配机会,定时器将计满后
清零,然而在PWM 模式下可以不关心这一点,因为PWM 模式下OCR0 是双缓冲。
时钟设置:1024 分频
匹配输出模式:
COM01-COM00 位可以设置当匹配发生时管脚OC0 的动作,从而在OC0 上产生特定的波形。
要使用波形输出,首先将OC0 端口的方向设置为输出。
#include "avr16.h"
unsigned int num_a;
unsigned int num_b;
//动态显示函数
void Display(short int num);
#pragma interrupt_handler fun_timer0_ov:20
(中断号可在中断一章的图中查询)
void fun_timer0_ov(void)
{
if(num_a++ > 100)
{
num_a=0;
num_b++;
if(num_b==20)
num_b=0;
}
}
void main()
{
num_a=0;
num_b=0;
DDRB = 0XFF;
DDRD = 0XFF; //设置为输出
CLR_PORTD(BUZZER); //关蜂鸣器
SREG|=0X80; //开总中断
TIMSK|=(1<<1); //开匹配中断
OCR0 = 0x78; //十进制120
TCCR0 = 0X0D; //CTC模式/1024分频/OC0不连接
while(TRUE)
{
Display(num_b);
}
}
3.快速PWM 模式
PWM,Pulse Width Modulation,意即脉冲宽度可调。此模式下可输出脉宽可调的波形,占空比可调。定时器从BOTTOM 开始计数,通常是0,然后计满后清零重新开始。通过设置匹配输出模式,当定时器与OCR0 匹配时,OC0 管脚发生相应变化。
这种模式采用的是单斜坡工作方式,因为定时器从0 开始计数,计满后一下回到0。
快速PWM 模式的OCR0 不会立即更新,因为它采用的是双缓冲,我们可以随时修改OCR0,修改OCR0 的时候只是将值保存在了缓冲用的OCR0 中,这样可以避免输出错误的波形。输出波形频率公式:
F=Fclk/(n*256)
n 是变频因子,另外在使用OC0 作为波形输出时,首先要设置其方向为输出。
设置OC0 管脚为输出。
4.相位修正的PWM 模式
此模式下定时器重复得从BOTTOM 计数达到MAX,然后又从MAX 倒退返回到BOTTOM。那么OC0 的输出将在第一个上升斜坡匹配时变化一次,在第二个下降斜坡匹配时变化一次。
此模式也是使用双缓冲的OCR0。可以看出相位修正模式和快速PWM 模式在相同的时钟驱动下,相位修正模式输出的波形频率更低一些。因为快速PWM 模式下,一个时钟周期内OC0 可以发生两次电平变化,而相位修正模式只能变化一次。此模式下也可以使用溢出中断与匹配中断,相关实验代码大家可参考上一小节的参考代码进行修改。
关于T/C0 定时器的四种模式就介绍到这里,最后还要注意一些地方。CPU 对读写TCNT0 有较高的优先级,在任何模式下写TCNT0 都会在下一个时钟周期内阻止比较匹配,所以将TCNTO 设置为与0CR0 相等的值,都会失去一次匹配的机会,造成不正确的波形。
上一篇:ATmega16开发板仿真教程——前言
下一篇:AVR单片机中断实现 ATmega16 INT ISR(INT0_vect)
推荐阅读最新更新时间:2024-11-10 11:04
推荐帖子
- 出 j-link , u-link, 无线路由器, STM32 开发板 ,wifi模块 以及其他杂物
- 1.J-LINK35元出2.u-LINK全新70元出3.无线路由器,86面板,就是像墙上的插座的那个80元出,带POE转换器4.射频卡读写模块30元5.430的书5元出6.cortexM4开发板70元出,基本全新7.汉枫电子的WIFI转串,全新50元出8.原装诺基亚充电线3元9.串口转排针线2元一个10.iTOP-4412开发板,三星cortexA9开发板,四核,1.5GHZ.500元,全新,包装齐全以上物品,有些是全新的,没标注
- 2638823746 淘e淘
- Wince 6.0导出SDK成功,新建应用程序却找不到该SDK。
- 我使用的TQ2440定制WINCE6.0,镜像生成成功,导出SDK都是没有问题,我没有添加MFC的支持,安装SDK也没有问题,但是在新建的工程里面却找不到,只有一个PLATFORMBUILDER(_TGTCPU),如下图:后来我发现在OSDesign里面的配置管理器也是这样的:以下是我的SDK属性页设置:我不知道这应该怎么设置才对,而且活动平台配置管理器的新建点击以后没有反应。希望高手解答~Wince6.0导出SDK成功,新建应用程序却找不到该SDK。MARK,
- zjuxuliyan WindowsCE
- AD9837 DIY信号发生器如何!
- 大家一起看看AD9837,他最高输出频率可以到多少,可是输出3种波形的价格1.7$AD9837DIY信号发生器如何!
- 蓝雨夜 模拟电子
- P8xC591 微控制器在CAN 中的应用
- 该手册覆盖了P8XC591与CAN相关的应用项目,想要应用并且理解该该文档中的应用实际例子,读者必须熟悉P8XC591的数据手册/P8xC591微控制器在CAN中的应用
- rain 工控电子
- Python现在正式成为第二流行的编程语言
- 来自:https://techdator.net/python-is-now-officially-the-second-most-popular-programming-language/根据最新的TIOBE索引,Python已超过Java成为第二流行的编程语言。Python现在落后于C,这已经有近20年的历史了。其他排名门户网站(例如RedMonk)也显示了相同的信息。专家揭示了多种原因,例如Python简单易用并在当今不断增长的应用程序中得到广泛使用,从而获得了如此多的
- dcexpert MicroPython开源版块
- 焊贴片芯片的问题
- 我看焊接视频教程,先固定,在一边堆锡,烙铁沾松香,刮锡,很容易就焊好了。我自己焊怎么就不灵呢?刮不掉。是不是要用烙铁头是刀头的那种,尖的不好刮。请高手指教,谢谢焊贴片芯片的问题就像看做菜视频,一看就会,一做就费,是一个道理,多失败几次就会了有引脚芯片(如SOP)可以先固定两个对角,然后用焊丝给所有引脚搪锡,再涂助焊剂,最后用电烙铁刮走多余焊锡,烙铁头最好用刀头;无引脚芯片(如QFN)要先给焊盘搪锡,然后涂助焊剂,放好芯片后用热风枪均匀加热,芯片本体PAD和PCB焊盘在熔
- chenbingjy 模拟电子
设计资源 培训 开发板 精华推荐
- 用于视频/成像的差分放大器
- M2 1216 无线网卡转PCI-e
- DC910A,使用 LT5557EUF、400MHz 至 3.8GHz 下混频器、1.95GHz、240MHz 分立匹配 IF 的演示板
- 【锁相环】MB1504调频发射机
- 用于汽车应用的 LTC3642EDD 5V、50mA 稳压器的典型应用电路
- LT1618、DC/DC 转换器从各种电源驱动 Lumileds 白光 LED
- 使用 Panasonic 的 AN30888A 的参考设计
- 使用 MaxLinear, Inc 的 SPX1587T-3.3-TR 的参考设计
- AD5318 八通道、10 位数模转换器的典型应用
- 具有关断功能的 LT1117CM-3.3 5V 稳压器的典型应用