ATmega16单片机定时器停止不了
这个问题纠结我好长时间。前段时间想用ATmega16单片机的定时器1做个99秒倒计时的装置。发现时间到0后定时器关闭不了。用的8MHz晶振,数码管显示。编译器是iccav...
这个问题纠结我好长时间。
前段时间想用ATmega16单片机的定时器1做个99秒倒计时的装置。发现时间到0后定时器关闭不了。
用的8MHz晶振,数码管显示。编译器是iccavr v6.31a,程序中定义char time=99;来计时。
定时器初始化函数如下:
void T1_init()
{
TCCR1B=0X04;
TCNT1H=0X85;
TCNT1L=0XED;
TIMSK |= BIT(2);
SREG |= BIT(7);
}
定时器的中断服务程序如下:
#pragma interrupt_handler T1:9
void T1()
{
TCNT1H=0X85;
TCNT1L=0XED;
time--;
if (time <= 0)
TIMSK &= ~BIT(2);
}
这样发现时间到0后,定时器没能停止,不过继续显示的是乱码。
如果把中断服务程序里判断时间是否为零的语句改成if (time ==0)定时器就可以正常停止。这是为啥啊?哪位大师指点一下小弟? 展开
前段时间想用ATmega16单片机的定时器1做个99秒倒计时的装置。发现时间到0后定时器关闭不了。
用的8MHz晶振,数码管显示。编译器是iccavr v6.31a,程序中定义char time=99;来计时。
定时器初始化函数如下:
void T1_init()
{
TCCR1B=0X04;
TCNT1H=0X85;
TCNT1L=0XED;
TIMSK |= BIT(2);
SREG |= BIT(7);
}
定时器的中断服务程序如下:
#pragma interrupt_handler T1:9
void T1()
{
TCNT1H=0X85;
TCNT1L=0XED;
time--;
if (time <= 0)
TIMSK &= ~BIT(2);
}
这样发现时间到0后,定时器没能停止,不过继续显示的是乱码。
如果把中断服务程序里判断时间是否为零的语句改成if (time ==0)定时器就可以正常停止。这是为啥啊?哪位大师指点一下小弟? 展开
2013-12-09
展开全部
if (time <= 0)你的time 是全局变量,char型(-128~127)??那么time可以为负了,应该是if (time == 0)表示倒计时结束,为了可循环,可以做以下调整if (time <= 0){
TIMSK &= ~BIT(2); time=99;//重新赋值
} 上一个我写的代码 #include<iom16v.h>
#include"MacroAndConst.h"//自定义函数
#include<Macros.h>
int8 count;
int8 ge;
int8 shi;
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0X7d,0X07,0x7f,0x6f};
/*软件延时函数定义*/
void delay(uint ms) //误差 -0.651041666667us
{
int8 a,b,i;
for(i=0;i<ms;i++)
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
/*T/C1定时初始化设置*/
void Timer1_init(void)
{
TCCR1B=0X04;//256分频
TCNT1H=0X85;//1s
TCNT1L=0Xee;
TIMSK|=BIT(2);//T/C1 interrupt
SREG|=BIT(7);
}
/*端口初始化设置*/
void Port_Init(void)
{
DDRA=0XFF;
PORTA=0XFF;
DDRB=0XFF;
PORTB=0XFF;
DDRC=0XFF;
PORTC=0XFF;
DDRD=0XFF;
PORTD=0XFF;
}
/*数码管显示程序*/
void display(int8 wela,int8 dula)
{
PORTB=table[dula];//send dula
PORTC&=~BIT(wela);//开启显示的位
delay(10);
PORTC|=BIT(wela);//开启显示的位
}
/******************************************
作者: prodigal功能介绍:用T/C1普通模式实现秒表程序,并用
数码管显示出来。
创作日期:20110809
版本�0.01
******************************************/
void main()
{
Port_Init();
Timer1_init();
while(1)
{
display(1,shi);
display(2,ge);
}
}
/*中断服务程序*/
#pragma interrupt_handler timer1_isr:9
void timer1_isr(void)
{
count++;
if(count==60)count=0;
shi=count/10;
ge =count%10;
TCNT1H=0X85;
TCNT1L=0Xee;
} 直奔→嵌入式团员为你解答,希望能帮助到你
TIMSK &= ~BIT(2); time=99;//重新赋值
} 上一个我写的代码 #include<iom16v.h>
#include"MacroAndConst.h"//自定义函数
#include<Macros.h>
int8 count;
int8 ge;
int8 shi;
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0X7d,0X07,0x7f,0x6f};
/*软件延时函数定义*/
void delay(uint ms) //误差 -0.651041666667us
{
int8 a,b,i;
for(i=0;i<ms;i++)
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
/*T/C1定时初始化设置*/
void Timer1_init(void)
{
TCCR1B=0X04;//256分频
TCNT1H=0X85;//1s
TCNT1L=0Xee;
TIMSK|=BIT(2);//T/C1 interrupt
SREG|=BIT(7);
}
/*端口初始化设置*/
void Port_Init(void)
{
DDRA=0XFF;
PORTA=0XFF;
DDRB=0XFF;
PORTB=0XFF;
DDRC=0XFF;
PORTC=0XFF;
DDRD=0XFF;
PORTD=0XFF;
}
/*数码管显示程序*/
void display(int8 wela,int8 dula)
{
PORTB=table[dula];//send dula
PORTC&=~BIT(wela);//开启显示的位
delay(10);
PORTC|=BIT(wela);//开启显示的位
}
/******************************************
作者: prodigal功能介绍:用T/C1普通模式实现秒表程序,并用
数码管显示出来。
创作日期:20110809
版本�0.01
******************************************/
void main()
{
Port_Init();
Timer1_init();
while(1)
{
display(1,shi);
display(2,ge);
}
}
/*中断服务程序*/
#pragma interrupt_handler timer1_isr:9
void timer1_isr(void)
{
count++;
if(count==60)count=0;
shi=count/10;
ge =count%10;
TCNT1H=0X85;
TCNT1L=0Xee;
} 直奔→嵌入式团员为你解答,希望能帮助到你
意法半导体(中国)投资有限公司
2023-06-12 广告
2023-06-12 广告
STM32F103是一款高性能的嵌入式芯片,由意法半导体(STMicroelectronics)公司生产。它是STM32系列芯片之一,具有紧凑、低功耗、高性能等特点,被广泛应用于嵌入式系统中。STM32F103的主要特点包括:1. 集成了A...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
2013-12-09
展开全部
我不用这款编译器,我建议你看下反汇编的代码,看看编译器是怎么处理的。
如果是我,我会写成if (!time) 这样效率高。
如果是我,我会写成if (!time) 这样效率高。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2013-12-09
展开全部
还是用51的方法啊,呵呵可以试试把TIMSK &= ~BIT(2);修改成TCCR1B &= ~0X04; 要定时器停止是CS2~CS0都写成0,你那个是关中断欢迎追问
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
atmega的单片机没有运行控制位,停止不了,不像51,可以给一个TR0=0就可以停止了!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询