📄 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 + -