ATMEAG16L有两个8位守时/计数器(T/CO、T/C2)和一个16位守时/计数器(T/C1)。每一个计数器都支撑PWM(脉冲宽度调制)输出功用。PWM输出在电机操控、开关电源、信号产生等范畴有着广泛的运用。
ATMEAG16L的守时/计数器时钟是能够挑选的。它的时钟部分包含预分频器和一个多路挑选器。预分频器可被认为是一个有多级输出的分频器。ATMEAG16L用一个10位的计数器把输入时钟分为4种可挑选的分频输出。多路挑选器可设置运用某一个分频输出,或许不运用分频输出和运用外部引脚输入时钟,下图为预分频器的根本结构。
ATMEAG16L守时/计数器的时钟挑选
1.运用体系时钟这种情况下运用体系时钟作为预分频器的输入,不过体系时钟的频率一般比较高,所以一般只能完结比较短的守时。预分频比可经过设置TCCRx的CSx2、CSx1和CSxO来选定下。表给出一个预分频设置值和分频比联系。
2.运用异步时钟ATMEAG16L的T/C2能够运用外部的异步时钟作为时钟源,这时能够在单片机的TOSC1和TOSC2两个引脚之直接一个石英晶体或许陶瓷振荡器,和内部的振荡器连接起来。这个振荡器专门为32.768kHz的挂钟时钟做了优化,这个频率十分适合于实时时钟(RTC)。
这种做法的长处是,在运用高速的体系时钟作处理的一起)能够独立运用别的一个适宜的时钟频率来进行精确的守时。因为T/C2运用的是异步时钟,所以时钟的工作需求被时钟同步。这就需求异步时钟的频率至少比体系时钟低4倍。
3.运用外部时钟T/CO、T/C1能够便用外部时钟。这样就能够在一个很大的规模内挑选外部时钟信号作为计数时钟。这种办法也是同步的,也就是说CPU会查看外部输入引脚的状况给计数器同步供给时钟。CPU的每一个时钟周期的上升沿都会取样外部时钟。CPU至少需求2个时钟才干检测引脚的改动,所以外部时钟的最大频率是CPU时钟的一半。外部时钟的上升沿和下降沿都能作为触发工作,能够经过设置操控寄存器TCCRx来确认。
假如需求关掉守时/计数器,则向操控寄存器的设置预分频比的位写0即可。如TCCR1B=OxOO。计数器的工作ATMEAG16L单片机的守时/计数器能够检测最多3种工作的产生。
1.时钟溢出工作守时/计数器溢出是指计数值到达最大值后会复位为0,而且从头开端计数。计数的最大值与计数的分辨率(位数是8位仍是16位)有关。计数溢出工作会导致守时/计数器中止标志寄存器TIFR的溢出标忘位(TOVx)置1。
2.比较匹配工作假如只是检测计数的;益出中止还不行,则能够运用计数比较中止。输出比较寄存器(OCRx)能够填放一个从O~最大值之间的数值,计数时在每一个守时/计数器时钟周期都会检杏这个数值。当计数值到达了比较数值时,相应TIFR中的计数器比较标志位(OCFx)就会置1。计数器能够设置成在比较匹配时清0,相关的输出引脚能够设置为在比较匹配时主动清0、置1,或许取反。这个特性很适合于产生不同频率的方波信号。计数器的这种功用使得输出的办法能够有很多种或许(比方占空比可变的方波PWM,频率可改动的方波),这样就能够把守时/计数器当作数!模转换器(DAC)来运用。
3.输入捕捉工作咱们还能够把一个输入当作触发输入捕捉工作来运用。这个引脚上的信号改动引起其时的计数值被读取,一起存入输入捕捉寄存器(ICRx)。这时TIFR寄存器的输入捕捉标志位(ICFx)会置1。这个功用对丈量外部输入脉冲的宽度很有用途。一起也能够把比较器的输出作为触发工作。
守时/计数器工作的处理
守时/计数器的运转是独立于程序的履行的。每一个工作都会在TIFR寄存器产生一个相应标志位。工作产生今后需求告诉CPU处理并履行相应操作。有3种处理工作的办法。
1.查询办法CPU不停地查询状况标志、中止标志,然后履行相应代码。这种形式下,主程序不断地查看这些工作是否产生,CPU不能做其它工作,功率很低。
2.中止办法CPU能够装备为在工作产生时就进入中止处理程序,这是遍及运用的办法。与查询办法比较,这种办法的长处是,CPU在平常能够处理其它的工作,而中止产生时才处理中止程序,功率大大提高了。
3.比较匹配输出ATMEAGl6L单片机有彻底不需求程序朴实用硬件完结计数工作处理的才能。完结这种处理需求设置TCCRx中的COMxO和COMx1两位,当比较匹配时,相关的输出可设置为1、清0或许取反。与前面两种处理办法比较,这种办法并行于一般程序履行,不需求处理时刻。
2.守时/计数器0的中止实验之前的数码管扫描都是点亮数码管后再延时一段时刻(如1ms)来完结的,假如CPU要处理的工作很多会形成编程困难或显现闪耀。现在运用守时/计数器0的中止处理来完结数码管的扫描,那么编程会轻松许多。
在我的文档中新建一个acl0的文件夹。树立一个Ac1O.prj的工程项目,最终树立源程序文件ac1O.c。输入下面的程序(程序2)。
编译经往后,将ac1O.hex文件下载到AVR单片机归纳实验板上进行实践演示。留意,标明“LED-MOD-DISP”及“LEDMOD-COM”的双排针应插上短路块。咱们可看到,8个数码管从低位(右)至高位(左)稳定地显现O~9这8个数。
3.4位显现秒表实验 在体育课或田径比赛时,教师常常会运用秒表来记载同学们的成果。这儿,咱们也来做一个秒表的规划实验。咱们运用INTO键进行计时的开端#中止。运用S1键作计时值的铲除。
在我的文档中新建一个ac11的文件夹。树立一个ac11.prj的工程项目,最终树立源程序文件ac11.c。输入下面的程序(程序3)。
编译经往后,将ac11.hex文件下载到AVR单片机归纳实验板上进行实践的操作演示。留意,标明“KEY”、“LEDMOD_DISP”、“LEDMOD_COM”及“INTO”的双排针应插上短路块。接通5V电源后,右边4个数码管显现0000,按动“INTO”键,数码管开端显现添加的计时值。再按一下“INTO”键,数码管显现中止的计时值。此刻按下S1键,可铲除计时值。
DDRA = OxFF;//将 PA端口设为输出
PORTC = OxFF;//PC端口初始化输出 1 1 1 1 1 1 1 1DDRC = OxFF;//将 PC端口设为输出
PORTD = OxFF;//PD 端口初始化输出 1 1 1 1 1 1 1 1DDRD = OxOO;//将 PD 端口设为输入
}
void timerO_init(void)//守时器0初始化子函数{
TCNTO = Ox83;//1 mS 的守时初值
TCCRO = OxO3;//守时器 0的计数预分频取64
}
#pragma interrupt_handler timerO_ovf_isr:1 0//守时器0中止服务子函数
void timer0_ovf_isr(void)
{
SREG=Ox80;//从头敞开总中止,保证计时精确TCNTO = Ox83;//重装 1mS 的守时初值
if(++i》3)i=0;//变量 i的计数规模 O~3
switch(i)//依据 i的值,点亮4个数码管
{
case 0: PORTA= SEG 7 [cnt% 1O]; PORTC= ACT [i];brea k;
case 1 : PORTA= SEG 7 [(cnt/ 10)% 1O]; PORTC= ACT[i]; break;
case 2: PORTA= SEG 7 [(cnt/ 100)% 10];0x80;PORTC= ACT [i]; break:;
case 3: PORTA= SEG 7 [cnt/ 1000]; PORTC= ACT [i];break;
default: break;
}
}
void timer1_init(void)//守时器 1 初始化子函数{
TCNT1H = OxD8;//1OmS 的守时初值
TCNT1L = Ox F0;
#pragma interrupt_handlef timerl_ovf_isr:9//守时器1 中止服务子函数
void timer 1_ovF-isr(void)
{
TCNT川= OxD8;//重装 1OmS 的守时初值
TCNT1L = Ox F0;
if (++cnt》9999)cnt=0;//计时规模 O~9999 ( 即0-99.99S)
}
#pragma interrupLhandlerintO_isr:2//INTO 中止服务子函数
void into-isr(void)
{
if(cnt《1 0)start_flag=Oxff;// 假如计时末开端,则置发动标志为 0xff
else start_flag=OxOO;//假如现已计时,则置发动标志为 OxOO
void init_devices(void)//芯片的初始化子函数{
Port_init();//端口初始化
timerO_init();//守时器0初始化
timer1_init();//守时器 1 初始化
MCUCR = OxO2;//INTO为下降沿触发
GICR = Ox40;//使能 INTO 中止
TIMSK = OxO5;//使能TO、T1 中止
SREG=Ox80;//使能总中止
}
void sCAN_sl(void)//扫描按键S1 子函数
{
if(S1 ==0)cnt=0;//假如S1 键按下,则铲除计时值}
void main(void)//界说主函数
{
init_devices();//芯片的初始化
while(11 //无限循环
{
if(sta rt_flag==0xff)TCCR1 B = OxO2;//假如发动标志为 Oxff,发动守时器 1
if(start_flag== Ox O0){TCCR 1 B = Ox O0; scan_s1 ();}//假如发动标志为 0xOO,
//则封闭守时器 1 再调用
扫描按键S1 的子函数
//无限循环完毕
//主函数完毕
责任编辑;zl