微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > AVR单片机(学习ing)-ATMEGA16的定时/计数器

AVR单片机(学习ing)-ATMEGA16的定时/计数器

时间:11-27 来源:互联网 点击:

5)定时器/ 计数器中断屏蔽寄存器- TIMSK

• Bit 7 – OCIE2: T/C2 输出比较匹配中断使能
当OCIE2 和状态寄存器的全局中断使能位I 都为"1” 时,T/C2 的输出比较匹配A 中断使
能。当T/C2 的比较匹配发生,即TIFR 中的OCF2 置位时,中断服务程序得以执行。
• Bit 6 – TOIE2: T/C2 溢出中断使能
当TOIE2 和状态寄存器的全局中断使能位I 都为"1” 时,T/C2 的溢出中断使能。当T/C2
发生溢出,即TIFR 中的TOV2 位置位时,中断服务程序得以执行。
6)定时器/ 计数器 中断标志寄存器- TIFR



• Bit 7 – OCF2: 输出比较标志 2
当T/C2 与OCR2( 输出比较寄存器2) 的值匹配时,OCF2 置位。此位在中断服务程序里
硬件清零,也可以通过对其写1 来清零。当SREG 中的位I、OCIE2 和OCF2 都置位时,
中断服务程序得到执行。
• Bit 6 – TOV2: T/C2 溢出标志
当T/C2 溢出时, TOV2 置位。执行相应的中断服务程序时此位硬件清零。此外, TOV2
也可以通过写1 来清零。当SREG 中的位I、TOIE2 和TOV2 都置位时,中断服务程序
得到执行。在PWM 模式中,当T/C2 在0x00 改变记数方向时, TOV2 置位。

这里也用到特殊功能寄存器:补充:



好了,现在基本上好了~~累死了

下面就是实验了,哈哈

4位秒表啊~~~吼吼

先贴张图片看看那



然后就是Proteus仿真~~~

出了点问题~~整了半天~~哭

个人认为是个Bug~~你懂得,我以前用51的时候就有这个问题,显示不完整,可能是更新太快了~

初始化:



然后是按下INT0:



最后是按下S1:



基本上就这点吧~~这里边比较难理解的就是那个去取反的重定义!!!!再IAR工具的应用里会有介绍(就是持续更新的那个~~毕竟有很多要更新的~~)

然后就是程序了~~

//------------------------------------------------------------------------------
//4位显示秒表试验
//使用INT0键进行计时的开始和停止,使用S1键作为计时值得清除。定时器T0被用作扫描4
//位数码管(1ms),定时器T1则用来计时(10ms)
#include"ioavr.h"
#include"intrinsics.h"
typedef unsigned char uchar;
typedef unsigned intuint;
__flash uchar seg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71};//共阴极数码管
__flash uchar act[4]={0xfe,0xfd,0xfb,0xf7};
uintcnt;// 全局变量,计时值
uchar flag_start;//全局变量,秒表启动标志
uchar i;//每次进入T0,对第i个数码管刷新
#define CPL_BIT(x,y)(x^=(1//就是将x所对应的第y位取反
#define s1(PIND&0X10)//对S1进行按键检测的时候用到,如果检测到,对cnt清0,你懂得why~~
#define xtal8//由于这里用到的是8MHz的,所以定义为8,写延时函数的时候会用到,回头我会把IAR for AVR的精确延时写到博客上~~
//------------------------------------------------------------------------------
//延时1ms的函数,没有参数传递
voiddelay_1ms()
{
uint i;
for(i=1;i<(uint)(xtal*143-2);i++)
;
}
//------------------------------------------------------------------------------
//延时nms的函数,有参数传递
voiddelay_nms(uint n)
{
uint i=0;
while(i {
delay_1ms();
i++;
}
}
//------------------------------------------------------------------------------
//端口定义函数,用来定义ABCD四个端口的输入输出
voidport_init()
{
DDRA=0XFF;
PORTA=0X00;
DDRC=0XFF;
PORTC=0XFF;
DDRD=0X00;
PORTD=0XFF;
}
//------------------------------------------------------------------------------
//T0的初始化定义
voidtimer0_init()
{
TCNT0=0X83;//1ms的定时初值
TCCR0=0X03;//T0的计数预分频取64,这就打开了T0的计数功能
}
//------------------------------------------------------------------------------
//T1的初始化函数
voidtimer1_init()
{
TCNT1H=0XD8;//10ms的定时初值
TCNT1L=0XF0;
}
//------------------------------------------------------------------------------
//按键检测函数
voidscan_s1()
{
if(s1==0)
{
delay_nms(10);
if(s1==0)
cnt=0;
}
}
//------------------------------------------------------------------------------
//芯片初始化函数,包含上面的所有初始化,以及没有涉及的
void device_init()
{
__disable_interrupt();//disable all interrupts,呵呵,不解释都知道,SREG?这个我不知道在不在里面,从下面的来看应该在,回头会具体分析的~~哈
port_init();
timer0_init();
timer1_init();
MCUCR=0X00;//INT0为低电平时产生中断请求
GICR=0X40;//使能INT0
TIMSK=0X05;//使能T0和T1溢出中断
__enable_interrupt();//re-enable interrupts
}
//------------------------------------------------------------------------------
//main
voidmain()
{
device_init();
while(1)
{
if(flag_start==0x01)
TCCR1B=0X02;//如果启动标志位为1,则启动T1,计数预分频取8
if(flag_start==0x00)
{
TCCR1B=0X00;//相反,定时器标志位为0,则关闭T1,停止计数,检测S1,如果按下,对cnt清0
scan_s1();
}
}
}
//------------------------------------------------------------------------------
//INT0
#pragma vector=INT0_vect
__interrupt voidint0()
{
CPL_BIT(flag_start,0);//取反启动标志,这里对第0位取反
delay_nms(10);
}
//------------------------------------------------------------------------------
//TIMER0_OVF
#pragma vector=TIMER0_OVF_vect
__interrupt voidtimer0_ovf()
{
SREG=0X80;
TCNT0=0X83;
if(++i>3)
i=0;
switch(i)
{
case 0: PORTA=seg[cnt];PORTC=act[i];break;
case 1: PORTA=seg[cnt0/10];PORTC=act[i];break;
case 2: PORTA=seg[cnt00/100];PORTC=act[i];break;
case 3: PORTA=seg[cnt/1000];PORTC=act[i];break;
default: break;
}
}
//------------------------------------------------------------------------------
//TIMER1_OVF
#pragma vector=TIMER1_OVF_vect
__interrupt voidtimer1_ovf()
{
TCNT1H=0XD8;
TCNT1L=0XF0;
if(++cnt>999)
cnt=0;
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top