//AVR单片机课程设计程序
//名称:频率计
//硬件:ATMEGA16_FHz-QLD100623产品 8MHz 晶振 三位数码管显示
//程序说明:程序初调阶段,可测频率范围1Hz--65KHz 自动换档显示
//编写人:李春起
//编写时间:2010。06。17
//修改日志:
#include<iom16v.h>
#include <macros.h>
//-------------位拉高--------------------------------------------
#define LED1_H PORTD|=BIT(PD4)
#define LED2_H PORTD|=BIT(PD5)
#define LED3_H PORTD|=BIT(PD6)
#define AT1_H PORTA|=BIT(PA0)
#define AT2_H PORTA|=BIT(PA1)
#define AT3_H PORTA|=BIT(PA2)
//-------------位拉低--------------------------------------------
#define LED1_L PORTD&=~BIT(PD4)
#define LED2_L PORTD&=~BIT(PD5)
#define LED3_L PORTD&=~BIT(PD6)
#define AT1_L PORTA&=~BIT(PA0)
#define AT2_L PORTA&=~BIT(PA1)
#define AT3_L PORTA&=~BIT(PA2)
#define NOP() asm("nop")
#define uchar unsigned char
#define uint unsigned int
//==================声明全局变量====================================
uint data,F_data=0,F_data10K=0;F_data1M=0;//频率分段储存
uint decimal1,decimal2,decimal3;
//===================数据表==============================================
__flash uchar SEG[]={0X03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
//==================mS延时子程序=========================================
void delayms(uint m)
{
uint i,j;
for(i=0;i<m;i++)
{
for(j=0;j<1141;j++);
}
}
//==================IO口初始化=======================================
void IO_init(void)
{
DDRA = 0XFF;
DDRB = 0X00;//PB0为频率输入,其它为按键
DDRC = 0XFF;
DDRD = 0XFF;
}
//====================定时器T0初始化===================================
void timer0_init(void)
{
TCCR0 = 0x0F; //T0上升沿触发CTC模式
TCNT0 = 0x00; //计数器清0
OCR0 = 255; //计数值达100中断
TIMSK |=0x02; //使能OCIE0
TIFR |=0x02; //清OCIF0中断标识位
}
//====================定时器T1初始化============================================
void timer1_Init(void)//用于产生标准1S时间
{
TCCR1A=0x00; //WGM1[3:0]=0100,OCR1A
TCCR1B=0x0c; //256 division,8M/256,CTC Mode
TCNT1=0X00; //Clear Counter
OCR1A=31250; //31250*256/8M=1S
TIMSK|=0X10; //比较匹配A中断使能
TIFR |=0X10; //中断标志写1清0
}
//=====================使能全局中断===========================================
void Interrupt_init(void)
{
SREG|=0x80;
}
//====================MCU初始化==========================================
void MCU_init(void)
{
IO_init();
timer0_init();
timer1_Init();
Interrupt_init();
}
//=============================================================
//-------------------------------------------------------------
//---------------主函数----------------------------------------
//-------------------------------------------------------------
void main(void)
{
MCU_init();
PORTD=0XFF;
while(1)
{
PORTC=(SEG[(data%10)]-decimal1);
AT3_H;
delayms(5);
AT3_L;
PORTC=(SEG[(data/10)%10]-decimal3);
AT2_H;
delayms(5);
AT2_L;
PORTC=(SEG[(data/100)%10]-decimal2);
AT1_H;
delayms(5);
AT1_L;
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
//==============================================================
//====================定时器T0中断服务子程序===================================
#pragma interrupt_handler Timer0_Interrupt:20
void Timer0_Interrupt(void)
{
TCNT0 = 0X00;//计数器清0
if(++F_data10K>=65535)
{
F_data10K=0;
if(++F_data1M>=65535)
{
F_data1M=0;
}
}
}
//=====================定时器T1中断服务=========================================
#pragma interrupt_handler Timer1_Interrupt:7
void Timer1_Interrupt(void)
{
TCNT1 = 0X00;//计数数清0
F_data = TCNT0;
F_data |= F_data10K<<8;
TCNT0 = 0X00;
F_data10K = 0;
if(F_data<1000){decimal3=0;decimal2=0;decimal1=1;
data=F_data;LED1_L;LED2_H;LED3_H;}
if(F_data>=1000){decimal3=0;decimal2=1;decimal1=0;
data=(F_data/10);LED1_H;LED2_L;LED3_H;}
if(F_data>=10000){decimal3=1;decimal2=0;decimal1=0;
data=(F_data/100);}
//if(F_data>=65534){F_data = (F_data>>8);F_data |= F_data1M<<8;
// F_data=(F_data/1000);}
}