//包含所需頭文件
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
/*------宏定義------*/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//數碼管字型表,對應0, 1, 2, 3, 4, 5, 6, 7, 8, 9//
uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar Data[4]={0,0,0,0}; //顯示初始值:0 0 0 0
uint data=0;
uint CNT=0;
uchar fanwei=1;
unsigned long Load;
//延時函數
void delay_us( int t) //us
{
do
t--;
while(t>1);
}
void delay_ms(unsigned int t) //ms
{
while(t!=0)
{
delay_us(1142);
t--;
}
}
//動態顯示函數
void Display(uchar *p) //參數p為待顯示的數組名
{uchar i,sel=0x01;
for(i=0;i<4;i++)
{
PORTA=Table[p[i]]; //送字型碼
PORTD=~sel;
delay_us(500); //顯示延時
sel=sel<<1; //移位以顯示前一位
}
}
//計數值處理函數
void Process(unsigned long i,uchar *p)
{
if(fanwei==2)
i=i/1000;
if(fanwei==1)
{
if(i>9999)
i=9999;
}
p[0]=i/1000;
i=i%1000;
p[1]=i/100;
i=i%100;
p[2]=i/10;
p[3]=i%10;
}
void xuanze (void)
{
if((PINB&0X10)==0)
fanwei=1; //單位為1Hz
if((PINB&0X20)==0)
fanwei=2; //單位為1KHz
if(fanwei==1)
PORTC=0X01;
if(fanwei==2)
PORTC=0X02;
}
//端口初始化
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0xFF;
PORTB = 0xFF;
DDRB = 0x00;
PORTC = 0xFF;
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0xFF;
}
//定時T1初始化
void timer1_init(void)
{
TCCR1B = 0x00;//停止定時器
TIMSK |= 0x04;//中斷允許
TCNT1H = 0x00;
TCNT1L = 0x00;//初始值
OCR1AH = 0xFF;
OCR1AL = 0xFF;//匹配A值
OCR1BH = 0xFF;
OCR1BL = 0xFF;//匹配B值
ICR1H = 0xFF;
ICR1L = 0xFF;//輸入捕捉匹配值
TCCR1A = 0x00;
TCCR1B = 0x07;//啟動定時器
}
//定時器T1溢出中斷服務程序
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
CNT++;
TCNT1H = 0x00; //重裝值高位
TCNT1L = 0x00; //重裝值低位
}
//定時器T2初始化
void timer2_init(void)
{
PORTC =0X01;
TCCR2 = 0x00;//停止定時器
ASSR = 0x08;//異步時鐘模式 AS2=1
TCNT2 = 0xFF;//初始值
OCR2 = 0xFE;//匹配值
TIMSK |= 0x40;//中斷允許
TCCR2 = 0x05;//啟動定時器 PCK/128
}
//T2溢出中斷服務程序
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
PORTC=0X02;
TCCR1B = 0x00; //關閉計數
//讀取計數值
Load=CNT*65536+TCNT1; //計算頻率值
TCNT1 = 0X00; //清除計數值
CNT=0;
TCCR1B = 0x07; //開始計數
}
void init_devices(void)
{
cli(); //禁止所有中斷
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer1_init();
timer2_init();
sei();//開全局中斷
}
//主函數
void main(void)
{
init_devices();
while(1)
{
xuanze();
Process(Load,Data); //計數值處理
Display(Data); //動態掃描顯示
}
}
|