?? clock.c
字號:
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#include<avr/interrupt.h>
#include<inttypes.h>
#include<util/delay.h>
#include<avr/io.h>
uint8_t Second=50, Minute=59, Hour=20;
uint8_t key;
uint8_t AMinute=0, AHour=0, AE=0, telltime=0, Hour_format=0;
uint8_t dis[]=
{ 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
uint8_t disp[6];
void dispro(uint8_t s) //計算每個數碼管所顯示的數值
{
uint8_t Hour_D;
Hour_D=Hour;
if ((Hour_format==1)&(Hour_D>=12)) // 時制轉換
{
switch (Hour_D)
{
case 12:
Hour_D=12;
break;
case 24:
Hour_D=0;
break; //鬧鐘時顯示
default:
{
Hour_D-=12;
}
break;
}
}
if (s==0) // 正常時間
{
disp[0]=Hour_D/10;
disp[1]=Hour_D-disp[0]*10;
disp[2]=Minute/10;
disp[3]=Minute-disp[2]*10;
disp[4]=Second/10;
disp[5]=Second-disp[4]*10;
}
if (s==1) // 鬧鐘時間
{
disp[0]=AHour/10;
disp[1]=AHour-disp[0]*10;
disp[2]=AMinute/10;
disp[3]=AMinute-disp[2]*10;
disp[4]=0;
disp[5]=AE;
}
}
void delay(uint8_t m) //延時子函數
{
uint16_t j;
for (; m!=0; m--)
{
for (j=8000; j!=0; j--)
{
;
}
}
}
void display(uint8_t a, uint8_t b, uint8_t c, uint8_t d) //顯示函數
{
dispro(d);
uint8_t i, sel;
sel=c;
for (i=a; i<b; i++)
{
PORTA=0x00;
PORTC=~sel;
PORTA=dis[disp[i]];
_delay_us(100);
sel=sel<<1; //移位,掃描下一個數碼管
}
}
void getkey(uint8_t n) //獲取鍵盤輸入
{
uint8_t qut=0;
key=0;
while (qut==0)
{
if ((PINB&0xA0)!=0xA0)
_delay_ms(8);
if ((PINB&0xA0)!=0xA0)
{
switch ((PINB&0xA0))
//讀端口電平,并忽略鬧鐘口
{
case 0x80:
key=5;
while ((PINB&0xA0)==0x80)
;
qut=1;
break;
case 0x20:
key=7;
while ((PINB&0xA0)==0x20)
;
qut=1;
break;
default:
{
}
break;
}
}
switch (n)
{
case 0:
display(0, 2, 0x01, 0);
break; //時顯示
case 2:
display(0, 2, 0x01, 1);
break; //鬧鐘時顯示
case 1:
display(2, 4, 0x04, 0);
break; //分顯示
case 3:
display(2, 4, 0x04, 1);
break; //鬧鐘分顯示
case 4:
display(4, 6, 0x10, 1);
break; //鬧鐘使能顯示
default:
{
}
break;
}
}
}
SIGNAL(SIG_OVERFLOW1)
//一秒基準與時分進位,未完成
{
TCNT1H=0Xfc;
TCNT1L=0X30;
if (Second==59)
{
Second=0;
if (Minute==59)
{
Minute=0;
if(Hour==23) Hour=0;
else Hour++;
telltime=1;
}
else Minute++;
}
else Second++;
if ((Hour==AHour)&(Minute==AMinute)&(AE==1)) // 判斷是否鬧鐘時刻
sbi (PORTB,3); //如果鬧鐘時刻,響一分鐘
else
cbi (PORTB,3);
if (telltime==1)
{
sbi (PORTB,3);
if ((Second>3))
{
cbi (PORTB,3);
telltime=0;
}
}
}
void Init_Device(void) //初始化函數
{
DDRB=0x0F; //B口前四位輸出,后四位輸入
DDRC=0xFF; //C口輸出
PORTC=0xFF;
DDRA=0xFF; //A口輸出
//DDRD=0xFF; //D口輸出
//PORTD=0xFF;
TCCR1A=0;
TCCR1B=5;
TCNT1H=0Xfc;
TCNT1L=0X30;
TIMSK=(1<<TOIE1); //開中斷
MCUCSR |= (1<<7);
MCUCSR |= (1<<7);
}
void adjtime(void) //調時子函數
{
TIMSK=(0<<TOIE1); //停止計時中斷
getkey(0);
while (key==7)
{
if (Hour==23)
Hour=0;
else
Hour++;
getkey(0);
}
getkey(1);
while (key==7)
{
if (Minute==59)
Minute=0;
else
Minute++;
getkey(1);
}
Second=0;
TIMSK=(1<<TOIE1); //重新開始計時
}
void adjalm(void) //調鬧鐘
{
getkey(2);
while (key==7)
{
if (AHour==23)
AHour=0;
else
AHour++;
getkey(2);
}
getkey(3);
while (key==7)
{
if (AMinute==59)
AMinute=0;
else
AMinute++;
getkey(3);
}
getkey(4);
while (key==7)
{
if (AE==1)
AE=0; //AE為鬧鐘使能(alarm enable)
else
AE++;
getkey(4);
}
}
int main(void)
{
Init_Device();
sei ();
for(;;)
{
display (0,6,0x01,0);
key=0;
if ((PINB&0xF0)!=0xF0)
_delay_ms(8);
if ((PINB&0xF0)!=0xF0)
{
switch ((PINB&0xF0))
{
case 0xE0: key=4;break;
case 0xB0: key=6;break;
case 0x70: key=7;while ((PINB&0xF0)==0x70);break;
default :
{}break;
}
}
if (key==4)
adjtime();
if (key==6)
adjalm();
if (key==7)
Hour_format=!Hour_format;
}
}
/*#include <avr/io.h>
#include <util/delay.h>
int main (void)
{
DDRA=0xFF;
DDRC=0xFF;
while(1)
{
uint8_t i, sel=0x01;
for (i=0; i<5; i++)
{
PORTA=0x00;
PORTC=~sel;
PORTA=0x06;
_delay_us(100);
sel=sel<<1; //移位,掃描下一個數碼管
}
}
}*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -