|
/*****************************************************************
程序功能:實現59分59秒的正跑表,定時器0實現每一秒中斷
實現59分59秒的反跑表,定時器0實現每一秒中斷
定時器1實現每40ms刷新數碼管一次
每計時一分鐘蜂蜜器響一次,包括反跑的時候
用外部中斷INT0、INT1實現按鍵掃描,正啟動跑表或反啟動跑表
無按鍵時實現正跑表
時鐘:11.0592MHz,KEIL編程環境
開發日期:2010年6月25日
*****************************************************************/
#include<reg52.h>
#include<absacc.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED_COM1 = P1^4; //the 4 8_segment LEDs common control port.
sbit LED_COM2 = P1^5;
sbit LED_COM3 = P1^6;
sbit LED_COM4 = P1^7;
sbit INT0_E=P3^2;
sbit INT1_E=P3^3;
#define LCD_273 XBYTE[0xfe00]
uchar timer0_interrupt_counter=0; //中斷記錄次數
uchar timer1_interrupt_counter=0;
uchar NUM_miao=0,NUM_fen=0; //記錄秒和分
uchar INT0_flag=0;
uchar INT1_flag=0;
uchar table[10]={0x0C0,0x0F9,0x0A4 ,0x0B0,0x99,0x92, 0x82,0x0F8,0x80,0x90 }; //開發板為共陽的
void TIME_init()
{
TMOD=0x11;//定時器0和定時器1工作于方式1
ET0=1; //開定時器/計數器0允許
TR0=1; //中斷定時器0開通
EA=1; //開總中斷
ET1=1;//開定時器/計數器1允許
TR1=1;//中斷定時器1開通
/***************外部中斷0**********************/
IT0=0; //跳沿觸發
EX0=1;//允許外部中斷0產生中斷
IT1=0; //跳沿觸發
EX1=1; //允許外部中斷1產生中斷
/*******************優先級設置******************************/
PX0=1;
PX1=1;
PT0=0;
PT1=0;
}
/*************************************************************************************************/
void delay(uint time) //延時函數
{
uint i=0,j=0;
for(i=time;i>0;i--);
}
void display(uchar i,uchar com_counter ) // i表示亮的數,j表示第幾個數碼管亮
{
LCD_273=table;
if(com_counter == 1)
{
LED_COM1 = 0;
LED_COM2 = 1;
LED_COM3 = 1;
LED_COM4 = 1;
}
if(com_counter == 2)
{
LED_COM1 = 1;
LED_COM2 = 0;
LED_COM3 = 1;
LED_COM4 = 1;
}
if(com_counter == 3)
{
LED_COM1 = 1;
LED_COM2 = 1;
LED_COM3 = 0;
LED_COM4 = 1;
}
if(com_counter == 4)
{
LED_COM1 = 1;
LED_COM2 = 1;
LED_COM3 = 1;
LED_COM4 = 0;
}
com_counter += 1;
if(com_counter >= 4)
com_counter = 0;
}
/*******************************************************************************
函數:定時器0中斷服務程序,產生20*50ms=1s的延時
介紹:每1s計時
********************************************************************************/
void timer0_ISR(void) interrupt 1
{
TH0=0x4B; //給予初值在11.0592MHZ下定時50ms:0x4BEC
TL0=0xEC;
timer0_interrupt_counter+=1;
if(timer0_interrupt_counter==20) //20 times interrupt about 50ms.
{
timer0_interrupt_counter=0; // set interrupt counter as 0
if(INT0_flag==1)
{
//INT0_flag=0;
NUM_miao++;
if(NUM_miao==60)
{
P1&=0xF7; //每計時到一分鐘蜂鳴器響一次
delay(100);
P1|=0x08; //停止蜂鳴器響
NUM_miao=0;
NUM_fen++;
if(NUM_fen==60){INT0_flag=0;NUM_fen=0;}
}
}
if(INT1_flag==1)
{
// NUM_miao=60;
// NUM_fen=60;
//INT1_flag=0;
NUM_miao--;
if(NUM_miao==0)
{
P1&=0xF7; //每計時到一分鐘蜂鳴器響一次
delay(100);
P1|=0x08; //停止蜂鳴器響
NUM_miao=60;
NUM_fen--;
if(NUM_fen==0){INT1_flag=0;NUM_fen=60;}
}
}
else
{
NUM_miao++;
if(NUM_miao==60)
{
P1&=0xF7; //每計時到一分鐘蜂鳴器響一次
delay(100);
P1|=0x08; //停止蜂鳴器響
NUM_miao=0;
NUM_fen++;
if(NUM_fen==60)NUM_fen=0;
}
}
}
}
/*******************************************************************************
函數:定時器1中斷服務程序,產生20ms*2=40ms延時
介紹:每50msms刷新數碼管
********************************************************************************/
void timer1_ISR(void) interrupt 3 //動態掃描中斷 每位40ms
{
TH1=0xFC; //給予初值在11.0592MHZ下定時20ms:0xB802
TL1=0x78;
timer1_interrupt_counter+=1;
if(timer1_interrupt_counter==1)
{
display(NUM_fen/10,1); //顯示分的十位 P1^4
}
if(timer1_interrupt_counter==2)
{
display(NUM_fen%10,2);
}
if(timer1_interrupt_counter==3)
{
display(NUM_miao/10,3); //顯示秒的十位 P1^6
}
if(timer1_interrupt_counter==4)
{
display(NUM_miao%10,4); //顯示秒的個位 P1^7
}
if(timer1_interrupt_counter>5)timer1_interrupt_counter=0;
}
/**************************************************************
函數:外部中斷0服務程序
介紹:觸發按鍵KEY1,實現秒表正跑
**************************************************************/
void INT0_ISR(void) interrupt 0
{
INT1_flag=0; //清零反跑標志
INT0_flag=1;
NUM_miao=0; //重裝正跑數據
NUM_fen=0;
//INT0_E=1; //中斷后對應的INT0引腳設置為高電平
//IE0=0;
}
/**************************************************************
函數:外部中斷1服務程序
介紹:觸發按鍵KEY2 ,實現秒表反跑
**************************************************************/
void INT1_ISR(void) interrupt 2
{
INT0_flag=0; //清零正跑標志
NUM_miao=60; //重裝反跑數據
NUM_fen=59;
INT1_flag=1;
//INT1_E=1; //中斷后對應的INT1引腳設置為高電平
//IE1=0;
}
void main()
{
TIME_init();
P1=0x08; //因為51單片機上電復位后I/0口是高電平
P3=0xff;
while(1)
{
;
}
|
|