⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qiangdaxitong.c

📁 基于AT89S52的智能抢答系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -