?? qiangdaxitong.c
字號:
#include<reg52.h>
unsigned char code LED_table[]={
0xc0, //"0"
0xf9, //"1"
0xa4, //"2" AAAA
0xb0, //"3" F B
0x99, //"4" F B
0x92, //"5" GGGG
0x82, //"6" E C
0xf8, //"7" E C
0x80, //"8" DDDD H
0x90, //"9"
0xff //black
};
#define black 10 // 空白
#define BEEP_ON 0x80 //蜂鳴器(小數點)的亮滅
#define BEEP_OFF 0x00
#define WriteDeviceAddress 0xa0 //定義器件在IIC總線中的地址
#define ReadDviceAddress 0xa1
#define UP KEY1 //功能按鍵
#define DOWN KEY2
#define SURE KEY3
#define CANCEL KEY4
#define NOW_NO_ 0x00 //24C02存儲地址
#define GROUP_1 0x01 //各組最終分數
#define GROUP_2 0x02
#define GROUP_3 0x03
#define GROUP_4 0x04
#define NOWgroup 0x05 //進程存儲
#define NOWmark 0x06
#define NOWtime_m 0x07
#define NOWtime_s 0x08
#define NOWsave 0x09
#define NOWcancel 0x10
#define SAVEbegin 0x11 //分數存儲入口
#define Aon() A1=A2=1 //數碼管選通函數
#define Aoff() A1=A2=0
#define ALLon() A1=A2=B1=B2=B3=B4=C=1
#define NONE() A1=A2=B1=B2=B3=B4=C=0
// 定義全局變量
//===========================================================================
unsigned char LED=1,Beep,tt_1,tt_2,count,Time_temp=20;
unsigned char Number_A1[2],Number_A2[2],Number_C[2];
unsigned char Number_B1[2],Number_B2[2],Number_B3[2],Number_B4[2];
unsigned char Result[4],Mark,Time_m,Time_s,No_,Group,Save_NOW,Cancel_NOW;
unsigned int tt;
bit A1,A2,B1,B2,B3,B4,C; //位變量,控制數碼管選通
// 定義通信端口
//==========================================================================
sbit LED1=P2^7; //主控制顯示
sbit LED2=P2^6;
sbit LED3=P2^5;
sbit LED4=P2^4;
sbit LED5=P1^6; //各組分數顯示
sbit LED6=P1^7;
sbit LED7=P1^4;
sbit LED8=P1^5;
sbit LED9=P1^2;
sbit LED10=P1^3;
sbit LED11=P1^0;
sbit LED12=P1^1;
sbit LED13=P3^1; //倒計時顯示
sbit LED14=P3^0;
sbit KEY1=P2^3; //鍵盤
sbit KEY2=P2^2;
sbit KEY3=P2^1;
sbit KEY4=P2^0;
sbit SCL=P3^4; //I2C接口
sbit SDA=P3^5;
sbit BEEP=P0^7; //蜂鳴器接口
sbit KEYCHOOSE_1=P3^3; //功能按鍵 (鍵盤狀態選擇)
sbit KEYCHOOSE_2=P3^2; //搶答按鍵
//===========================================================================
/****************************************************************************
* 名 稱:Sys_Init()
* 功 能:初始化
* 入口參數:無
* 出口參數:無
****************************************************************************/
void Sys_Init()
{
TMOD=0x11; //定時器/計數器0為定時器方式 16位工作模式
TH0=(65536-1000)/256; //初始時間常數
TL0=(65536-1000)%256; //1.0ms
TH1=(65536-50000)/256; //初始時間常數
TL1=(65536-50000)%256; //50ms
ET0=1; //定時器/計數器0中斷允許
ET1=1; //定時器/計數器1中斷允許
EA=1; //總中斷允許
TR0=1; //啟動定時器/計數器開始工作
TR1=1; //啟動定時器/計數器開始工作
}
/****************************************************************************
* 名 稱:DisplayNumber()
* 功 能:在數碼管上顯示數字
* 入口參數:Num: 顯示數值 (0~99) xx:數碼管數組
* 出口參數:無
****************************************************************************/
void DisplayNumber(unsigned char Num,unsigned char xx[2])
{
EA=0; //禁止總中斷
xx[0]=Num/10; //拆分數字
xx[1]=Num%10;
if(xx[0]==0) xx[0]=black; //消隱無效"0"
EA=1; //總中斷允許
}
/****************************************************************************
* 名 稱:Display_Scan()
* 功 能:數碼管選通掃描
* 入口參數:無
* 出口參數:無
****************************************************************************/
void Display_Scan() interrupt 1 //中斷服務程序,數碼管選通掃描
{
TR0=0;
TH0=(65536-1000)/256; //高8位和低8位時間常數
TL0=(65536-1000)%256;
TR0=1; //啟動定時器0
if(LED>14) LED=1;
LED1=LED2=LED3=LED4=LED5=LED6=LED7=LED8=LED9=LED10=LED11=LED12=LED13=LED14=1; //全置暗
if(A1) switch(LED) //單數碼管控制
{
case 1: P0=LED_table[Number_A1[0]]; LED1=0; break; //分別選通LED1、LED2 低電平有效
case 2: P0=LED_table[Number_A1[1]]-Beep; LED2=0; break;
}
if(A2) switch(LED)
{
case 3: P0=LED_table[Number_A2[0]]; LED3=0; break; //分別選通LED3、LED4 低電平有效
case 4: P0=LED_table[Number_A2[1]]-Beep; LED4=0; break;
}
if(B1) switch(LED)
{
case 5: P0=LED_table[Number_B1[0]]; LED5=0; break;
case 6: P0=LED_table[Number_B1[1]]-Beep; LED6=0; break;
}
if(B2) switch(LED)
{
case 7: P0=LED_table[Number_B2[0]]; LED7=0; break;
case 8: P0=LED_table[Number_B2[1]]-Beep; LED8=0; break;
}
if(B3) switch(LED)
{
case 9: P0=LED_table[Number_B3[0]]; LED9=0; break;
case 10: P0=LED_table[Number_B3[1]]-Beep; LED10=0; break;
}
if(B4) switch(LED)
{
case 11: P0=LED_table[Number_B4[0]]; LED11=0; break;
case 12: P0=LED_table[Number_B4[1]]-Beep; LED12=0; break;
}
if(C) switch(LED)
{
case 13: P0=LED_table[Number_C[0]]; LED13=0; break;
case 14: P0=LED_table[Number_C[1]]-Beep; LED14=0; break;
}
LED++;
}
/****************************************************************************
* 名 稱:Time_Count()
* 功 能:后臺定時,通過“Time_temp”控制定時時長
* 入口參數:無
* 出口參數:無
*****************************************************************************/
void Time_Count() interrupt 3
{
TR1=0;
TH1=(65536-50000)/256; //高8位和低8位時間常數
TL1=(65536-50000)%256;
TR1=1; //啟動定時器0
if(tt_1>=Time_temp) {tt++;tt_1=0;}
else tt_1++;
if(tt_2>=8) {count++;tt_2=0;}
else tt_2++;
if(count>4) count=1;
}
/****************************************************************************
* 名 稱:delayms()
* 功 能:延遲X毫秒
* 入口參數:ms: 延遲毫秒數
* 出口參數:無
* 說 明: 12MHz條件下
*****************************************************************************/
void delayms(int ms)
{
unsigned int i;
for(;ms>0;ms--)
{
for(i=0;i<123;i++);
}
}
/****************************************************************************
* 名 稱:KEYchooose()
* 功 能:功能按鍵的選擇
* 入口參數:0、1
* 出口參數:無
*****************************************************************************/
void KEYchoose(unsigned char x)
{
if(x) {KEYCHOOSE_1=0;KEYCHOOSE_2=1; } //選功能按鍵
else {KEYCHOOSE_2=0;KEYCHOOSE_1=1;} //選搶答按鍵
KEY1=KEY2=KEY3=KEY4=1; //全置高
}
/****************************************************************************
* 名 稱:Beeper()
* 功 能:蜂鳴器選通
* 入口參數:鳴響次數 n
* 出口參數:無
*****************************************************************************/
void Beeper(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
Beep=BEEP_ON;
delayms(300);
Beep=BEEP_OFF;
delayms(100);
}
}
//================================== I2C ====================================
/****************************************************************************
* 名 稱:I2C
* 功 能:外存儲器
* 入口參數:存儲數據、存儲地址;讀取地址
* 出口參數:無
****************************************************************************/
void Start() //開始總線
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;
}
void Stop() //結束總線
{
SCL=0;
SDA=0;
SCL=1;
SDA=1;
}
void NoAck() //發ACK0
{
SDA=1;
SCL=1;
SCL=0;
}
bit TestAck() //測試ACK
{
bit ErrorBit;
SDA=1;
SCL=1;
ErrorBit=SDA;
SCL=0;
return(ErrorBit);
}
Write8Bit(unsigned char input) //寫入8個bit到24c02
{
unsigned char temp;
for(temp=8;temp!=0;temp--)
{
SDA=(bit)(input&0x80);
SCL=1;
SCL=0;
input=input<<1;
}
}
void Write24c02(unsigned char ch,unsigned char address) //寫入一個字節到24c02
{
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Write8Bit(ch);
TestAck();
Stop();
delayms(10);
}
unsigned char Read8Bit() //從24c02中讀出8個bit
{
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--)
{
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
}
unsigned char Read24c02(unsigned char address) //從24c02中讀出1個字節
{
unsigned char ch;
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Start();
Write8Bit(ReadDviceAddress);
TestAck();
ch=Read8Bit();
NoAck();
Stop();
return(ch);
}
/****************************************************************************
* 名 稱:SetMark()
* 功 能:設定分數,0~9之間
* 入口參數:無
* 出口參數:無
* 顯示描述:只有A1亮且閃
*****************************************************************************/
void SetMark()
{
A2=0; //關閉A2
tt=0;
while(tt<=3) //在3秒內設定
{
if(CANCEL==0) {delayms(150);if(CANCEL==0) break;} //跳出
else if(UP==0){delayms(150);if(UP==0){tt=0;if(Mark>=9)Mark=0;else Mark+=2;}}
else if(DOWN==0){delayms(150);if(DOWN==0){tt=0;if(Mark==0)Mark=0;else Mark--;}}
else if(SURE==0){delayms(150); break;} //跳出
DisplayNumber(Mark,Number_A1);
if(count%2) A1=~A1; //閃爍
}
DisplayNumber(Mark,Number_A1); //顯示以及存儲
Write24c02(Mark,NOWmark);
A2=1; //開A2
}
/****************************************************************************
* 名 稱:SetTime()
* 功 能:設定分數,0~10之間
* 入口參數:無
* 出口參數:無
* 顯示描述:兩管皆亮且A2閃
*****************************************************************************/
void SetTime()
{
tt=0;
while(tt<=3) //在3秒內設定
{
DisplayNumber(Time_m,Number_A1);
DisplayNumber(Time_s,Number_A2);
if(CANCEL==0) {delayms(150);if(CANCEL==0) break;}
if(UP==0){delayms(150);if(UP==0){tt=0;if(Time_m>=10) ime_m=0;else Time_m++;}}
else if(DOWN==0) {delayms(150);if(DOWN==0){tt=0;
if(Time_s==0&&Time_m>=1) {Time_s=30;Time_m--;}else Time_s=0;}}
else if(SURE==0) {delayms(150); break; }
if(count%2) A2=~A2; //閃爍
}
DisplayNumber(Time_m,Number_A1); //顯示以及存儲
DisplayNumber(Time_s,Number_A2);
Write24c02(Time_m,NOWtime_m);
Write24c02(Time_s,NOWtime_s);
}
/****************************************************************************
* 名 稱:Count_Down()
* 功 能:倒計時,按“SURE”、“CANCEL”跳出
* 入口參數:無
* 出口參數:1和0 (沒用)
* 顯示描述:A1、A2、C共同顯示,完成后回復原來數據,到秒提醒
*****************************************************************************/
bit Count_Down()
{
char mm;
unsigned char ss,x;
if(SURE==0) x=1; //判斷用SURE或CANCEL跳出
else x=0;
KEYCHOOSE_1=0;
Time_temp=20; //準確一秒定時
if(!Time_s&&Time_m) {mm=Time_m-1;ss=60;} //判斷分的顯示
else {mm=Time_m; ss=30;}
do
{
for(tt=0;tt<ss;) //循環ss秒
{
DisplayNumber(mm,Number_A1);
DisplayNumber(ss-tt,Number_A2);
if(mm&&!(tt%3)) DisplayNumber(mm,Number_C); //協調C中分和秒的顯示
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -