//有兩個按鍵,其中一個接INT0,另一個接PD7
//啟動時,數碼管顯示00.00 ,按下INT0 ,開始計時
//再按下INT0,計時停止。
//無論何時,按下PD7,計時清零。
//問題在于:時間不準,比1秒慢。時間轉過一分鐘,計時只有36秒。此時熔絲位為
#include<iom16v.h> const unsigned char duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; const unsigned char weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char shu[8]; unsigned int aa; unsigned int cnt; /**************************************** 延時函數 ****************************************/ void delay(unsigned char t) { unsigned char x,y; for(x=t;x>0;x--) for(y=100;y>0;y--); } /**************************************** 顯示函數 ****************************************/ void display(void) { unsigned char i; for(i=0;i<4;i++) { PORTB =0X00; PORTA|=0X01; PORTA&=0XFE; PORTB =weima[i]; PORTA|=0x02; PORTA&=0XFD; PORTB=shu[i]; PORTA|=0X01; PORTA&=0XFE; delay(3); } } /*************************************** 數據轉換子函數 ***************************************/ void change(unsigned int i) { shu[0]=duanma[i/1000]; shu[1]=duanma[i/100%10]|0x80; shu[2]=duanma[i%100/10]; shu[3]=duanma[i%10]; } /*************************************** 端口初始化 ***************************************/ void init_port(void) { PORTA=0XFF; DDRA=0XFF; PORTB=0XFF; DDRB=0XFF; PORTD=0XFF; DDRD=0X7B; // 0111 1011 } /*************************************** 按鍵檢測 ***************************************/ void keyscan(void) { if((PIND&0X80)!=0X80) { change(cnt); display(); //延時 display(); if((PIND&0X80)!=0X80) { cnt=0; //按鍵按下 計數清零 } } } /*************************************** 定時器1初始化 ***************************************/ void timer1_init(void) { TCNT1H=0xd8; //裝10ms的定時器初值 TCNT1L=0xf0; } /*************************************** 定時器1服務函數 ***************************************/ #pragma interrupt_handler timer1_ovf_isr:9 void timer1_ovf_isr(void) { TCNT1H=0XD8; //重裝10ms的定時器初值 TCNT1L=0XF0; if(++cnt>9999) cnt=0; } /*************************************** INT0中斷服務子函數 ***************************************/ #pragma interrupt_handler int0_isr:2 void int0_isr(void) { if(cnt<10) TCCR1B=0x02; //啟動定時器1 else TCCR1B=0x00; //關閉定時器1 } /*************************************** IO及中斷初始化 ***************************************/ void init_interrupt(void) { init_port(); //IO初始化 timer1_init(); //定時器1初始化 MCUCR=0X02; //INT0下降沿觸發 GICR=0X40; //使能INT0 TIMSK=0X04; //使能T1中斷 SREG=0X80; //使能總中斷 } /*************************************** MAIN ***************************************/ void main(void) { init_interrupt(); while(1) { change(cnt); display(); keyscan(); } }