#include "reg52.h"
#include "iic.h"
sbit R1=P3^2;
sbit R2=P3^3;
sbit C2=P3^4;
sbit C1=P3^5;
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
unsigned char SMG_stat=0;//0是数据显示界面//1是参数显示界面//2是计数显示界面
unsigned int Vp=0;//电压阈值参数
unsigned long int times=0;//计数
bit flag=0;//L1点亮标志位
bit L1_k=0;//L1开关标志位
unsigned char invalid_key=0;//无效按键次数
unsigned char code SMG_duanma[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char code SMG_dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void selectHC573(unsigned char channel,unsigned char dat)
{
P2 = (P2 & 0x1f) | 0x00; //赋值之前,关闭所有锁存器,防止冲突
P0 = dat; //设置待赋值数据
switch(channel)
{
case 4:P2=(P2&0x1f)|0x80; break; //控制LED灯
case 5:P2=(P2&0x1f)|0xa0; break; //控制蜂鸣器继电器
case 6:P2=(P2&0x1f)|0xc0; break; //控制数码管显示位置
case 7:P2=(P2&0x1f)|0xe0; break; //控制数码管显示数字
case 0:P2=(P2&0x1f)|0x00; break; //不选择锁存器
}
P2 = (P2 & 0x1f) | 0x00; //赋值完成后,关闭所有锁存器
}
void delay(unsigned int t)
{
while(t--);
}
void delay_key(unsigned char t)
{
while(t--);
}
void DisSMG();
void Write_24C02(unsigned char add,unsigned char dat);
//=======================电压读取==========================================
unsigned int VANI3=0;
void Read_VANI3()
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CStop();
DisSMG();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
VANI3=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
}
//=======================================================================
//=======================数码管显示========================================
void DisSMG_bit(unsigned char dat,unsigned char pos)
{
selectHC573(6,0x01<<pos); //数码管位选
selectHC573(7,dat); //数码管内容
delay(500); //数码管动态显示需要的延迟函数
selectHC573(0,0xff);
}
void DisSMG_all(unsigned char dat)
{
selectHC573(6,0xff); //数码管位选
selectHC573(7,dat); //数码管内容
selectHC573(0,0xff);
}
void DisSMG()
{
if(SMG_stat==0)//数据显示
{
DisSMG_bit(0xc1,0);
DisSMG_bit(SMG_dot[VANI3/100],5);
DisSMG_bit(SMG_duanma[(VANI3/10)%10],6);
DisSMG_bit(SMG_duanma[VANI3%10],7);
}
else if(SMG_stat==1)//参数显示
{
DisSMG_bit(0x8c,0);
DisSMG_bit(SMG_dot[Vp/100],5);
DisSMG_bit(SMG_duanma[(Vp/10)%10],6);
DisSMG_bit(SMG_duanma[Vp%10],7);
}
else if(SMG_stat==2)//计数显示
{
DisSMG_bit(0x89,0);
if(times>99)
{
DisSMG_bit(SMG_duanma[(times/100)%10],5);
}
if(times>9)
{
DisSMG_bit(SMG_duanma[(times/10)%10],6);
}
DisSMG_bit(SMG_duanma[times%10],7);
}
DisSMG_all(0xff);
}
//=======================================================================
//========================定时器====================================
void Init_T0()
{
TMOD=0x01; //也就是二进制0001,定时器0定时功能,16位模式
TH0=(65535-10000)/256; //0.01秒
TL0=(65535-10000)%256;
EA=1; //总中断打开
ET0=1; //定时中断使能
}
unsigned char count=0;//计数
void Service_T0() interrupt 1
{
TH0=(65535-10000)/256;//0.01s
TL0=(65535-10000)%256;
count++;
if(count>=500)
{
count=0;
TR0=0;
L1_k=1;
}
}
//=======================================================================
//========================存储器====================================
void Write_24C02(unsigned char add,unsigned char dat)
{
I2CStart(); //IIC总线起始信号
I2CSendByte(0xa0); //24C02的写设备地址,写操作地址则为:0xa0
I2CWaitAck(); //等待从机应答
I2CSendByte(add); //内存字节字节
I2CWaitAck(); //等待从机应答
I2CSendByte(dat); //写入目标数据
I2CWaitAck(); //等待从机应答
I2CStop(); //IIC总线停止信号
}
unsigned char Read_24C02(unsigned char add)
{
unsigned char temp; //进行一个伪写操作
I2CStart(); //IIC总线起始信号
I2CSendByte(0xa0); //24C02写设备地址
I2CWaitAck(); //等待从机应答
I2CSendByte(add); //内存自己地址
I2CWaitAck(); //等待从机应答
//进行字节读操作
I2CStart(); //IIC总线起始信号
I2CSendByte(0xa1); //24C02读设备地址
I2CWaitAck(); //等待从机应答
temp = I2CReceiveByte(); //读取目标数据
I2CSendAck(1); //产生非应答信号
I2CStop(); //IIC总线停止信号
return temp;
}
//=======================================================================
//========================矩阵按键====================================
void scankey()
{
R1=0;
R2=1;
C1=C2=1;
if(C1==0)//S13
{
delay_key(100);
if(C1==0)
{
while(C1==0);
{
DisSMG();
}
if(SMG_stat==2)
{
times=0;
DisSMG();
invalid_key=0;
}
else
{
invalid_key++;
}
}
}
else if(C2==0)//S17
{
delay_key(100);
if(C2==0)
{
while(C2==0)
{
DisSMG();
}
if(SMG_stat==1)
{
Vp=Vp+50;
if(Vp>500)
{
Vp=0;
}
invalid_key=0;
}
else
{
invalid_key++;
}
}
}
R2=0;
R1=1;
C1=C2=1;
if(C1==0)//S12
{
delay_key(100);
if(C1==0)
{
while(C1==0)
{
DisSMG();
}
if(SMG_stat==0)
{
SMG_stat=1;
}
else if(SMG_stat==1)
{
SMG_stat=2;
Write_24C02(0x00,Vp/10);
delay(1000);
}
else if(SMG_stat==2)
{
SMG_stat=0;
}
invalid_key=0;
}
}
else if(C2==0)//S16
{
delay_key(100);
if(C2==0)
{
while(C2==0)
{
DisSMG();
}
if(SMG_stat==1)
{
Vp=Vp-50;
if(Vp<0)
{
Vp=500;
}
invalid_key=0;
}
else
{
invalid_key++;
}
}
}
}
//=======================================================================
//========================LED显示====================================
void LEDrunning()
{
if(VANI3<Vp)
{
TR0=1;
}
else
{
TR0=0;
count=0;
L1_k=0;
}
if(L1_k==1)
{
selectHC573(4,0xfe);
}
else
{
selectHC573(4,0xff);
}
if(times>0)
{
if(times%2==0)
{
selectHC573(4,0xfd);
}
else
{
selectHC573(4,0xff);
}
}
if(invalid_key>=3)
{
selectHC573(4,0xfb);
}
else
{
selectHC573(4,0xff);
}
}
//=======================================================================
void Init_system()
{
selectHC573(0,0x00); //关闭所有锁存器
selectHC573(5,0x00); //关闭蜂鸣器和继电器
selectHC573(4,0xff); //关闭全部LED灯
}
void main()
{
Init_system();
Init_T0();
Vp=Read_24C02(0x00)*10;
while(1)
{
Read_VANI3();
VANI3=VANI3*1.961;
if(VANI3>Vp)
{
flag=1;
}
else if(VANI3<=Vp)
{
if(flag==1)
{
times++;
flag=0;
}
}
DisSMG();
scankey();
LEDrunning();
}
}
第十一届第一次蓝桥杯单片机组省赛程序代码
于 2024-03-09 21:45:25 首次发布