|
发表于 2007-8-16 08:45:38
|
显示全部楼层
我之前写的一个例子,还请大家点评
/*****************************************************
www.avrdiy.com
CodeWizardAVR V1.25.6 Professional
Chip type : ATmega48
Clock frequency : 7.372800 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
功能:LED每秒钟闪烁一次(或者驱动蜂鸣器),要求时间要精确
计算: 1秒 = 时钟 / ( 分频 * 计数 )
假设时钟 = 7372800 Hz 那么: 1秒 = 7372800 / ( 分频 * 计数 )
得: 计数 =7372800/分频
由于分频只有 1/8/32/64/128/256/1024 供我们选择,而计数最高只有8位(255)
为了不占用资源,中断次数尽量少一点比较好,并且中断服务程序运行时间越短越好
所以我们可以选择 计数TOP = 时钟7372800 / 分频1024 / 每秒30次中断 = 240
那么 时间 = 时钟7372800 / 1024分频 / 每秒30次中断 / TOP 240 = 1秒
*****************************************************/
#include <mega48.h>
unsigned char TC2A=0;
interrupt [TIM2_COMPA] void timer2_compa_isr(void)
{
TC2A++;
if(TC2A>=30) TC2A=0;
if(TC2A>25) PORTD.3=1; else PORTD.3=0;
//在这里还可以插入如数码管的动态扫描/键盘扫描等代码
//注意,中断运行时间必须小于 1秒 / 30次中断 = 33ms
}
void main(void)
{
TCCR2A|=2; //工作于CTC模式(比较匹配时计数器TCNT2清零)
OCR2A=240; //设置TOP的值(计数器TCNT2的计数上限值)
TCCR2B|=7; //取系统时钟1024分频作为T/C2时钟
TIMSK2=2; //使能计数器的值达到TOP时产生中断
DDRD.3=1; //使用PD3每秒驱动蜂鸣器"嘀"一次
#asm("sei") //插入汇编语句,打开全局中断
while (1)
{
#asm("nop") //空操作的汇编代码,等待中断发生
};
}
/****************************************************
假设程序还有一个3位数码管动态扫描任务,这时我们就可以这样计算
1:数码管的扫描频率在75-85Hz比较合适,太低会闪烁,太高占用资源
2:每扫描一次就必须分3次显示,分别是个位/十位/百位
3:这时我们可以计数出显示频率是225-255Hz(中断频率),在这里假设=240Hz
4:这时我们就可以顺便使用这个T/C2定数中断来保证扫描的可靠运行了***/ |
|