若代码有误,欢迎在评论区批评指正!
main.c
#include <REGX52.H>
#include <iic.H>
#define uchar unsigned char
#define uint unsigned int
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
code uchar Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1,0xc8,0xbf}; //16:U,17N,18 -
code uchar Seg_Table_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
uchar flag_S4,flag_S5,count,count_ms,flag_LED = 1;
uint count_f,dat_f,U,T,U_ROM,dat_f_ROM,U1,U3;
//=================================函数声明命区================================
void hc573(uchar channel);
void delay_s(uint t);
void delay_l(uint xms);
void Nixie(uchar loc,num);
void Nixie_dot(uchar loc,num);
void Init_System();
void display();
void InitTimer();
void LED();
//=============================================================================
void hc573(uchar channel)
{
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;
}
}
//==================================短延时==========================================
void delay_s(uint t)
{
while(t--);
}
//==================================长延时===========================================
void delay_l(uint xms)
{
unsigned char i, j;
while(xms--)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
//==============================不带小数点的数码管基础显示==================================
void Nixie(uchar loc,num)
{
hc573(0);
P0 = 0x01<<(loc-1);
hc573(6);
hc573(0);
P0 = Seg_Table[num];
hc573(7);
delay_s(700);
P0 = 0xff;
hc573(0);
}
//==============================带小数点的数码管基础显示==================================
void Nixie_dot(uchar loc,num)
{
hc573(0);
P0 = 0x01<<(loc-1);
hc573(6);
hc573(0);
P0 = Seg_Table_dot[num];
hc573(7);
delay_s(500);
P0 = 0xff;
hc573(0);
}
//==================================系统初始化=============================
void Init_System()
{
hc573(0);
P0 = 0x00;
hc573(5);
hc573(0);
P0 = 0xff;
hc573(4);
hc573(0);
}
//====================================独立键盘检测=======================
void KeyScan()
{
if(S4==0||S5==0||S6==0||S7==0)
{
display();
if(S4 == 0)
{
flag_S4 = (flag_S4 + 1)%3;
if(flag_S4 == 2) flag_S5 = 0;
U3 = Read_PCF(0x03);
while(S4 == 0)
{
display();
LED();
U1 = Read_PCF(0x01);
U3 = Read_PCF(0x03);
}
}
if(S5 == 0)
{
flag_S5 = (flag_S5 + 1)%2;
U3 = Read_PCF(0x03);
while(S5 == 0)
{
display();
LED();
U1 = Read_PCF(0x01);
U3 = Read_PCF(0x03);
}
}
if(S6 == 0)
{
Write_ROM(0x01,U3/256); delay_l(2);
Write_ROM(0x02,U3%255); delay_l(2);
U_ROM = (Read_ROM(0x01)<<8)|Read_ROM(0x02);
while(S6 == 0)
{
display();
LED();
U1 = Read_PCF(0x01);
U3 = Read_PCF(0x03);
}
}
if(S7 == 0)
{
count_ms = 0;
while(S7 == 0)
{
if(count_ms>=20) count_ms = 21;
display();
LED();
U1 = Read_PCF(0x01);
U3 = Read_PCF(0x03);
}
if(count_ms>=20) flag_LED = 1 - flag_LED;
else
{
Write_ROM(0x03,dat_f/256); delay_l(2);
Write_ROM(0x04,dat_f%256); delay_l(2);
dat_f_ROM = (Read_ROM(0x03)<<8)|Read_ROM(0x04);
}
}
}
}
//===============================数码管显示==========================
void display()
{
if(flag_S4 == 0)
{
Nixie(1,15);
if(dat_f>9999) Nixie(4,dat_f/10000);
if(dat_f>999) Nixie(5,dat_f/1000%10);
if(dat_f>99) Nixie(6,dat_f/100%10);
if(dat_f>9) Nixie(7,dat_f/10%10);
if(dat_f) Nixie(8,dat_f%10);
}
if(flag_S4 == 1)
{
Nixie(1,17);
T = 1000000/dat_f;
if(T>9999) Nixie(4,T/10000);
if(T>999) Nixie(5,T/1000%10);
if(T>99) Nixie(6,T/100%10);
if(T>9) Nixie(7,T/10%10);
if(T) Nixie(8,T%10);
}
if(flag_S4 == 2)
{
Nixie(1,16);
Nixie(2,18);
if(flag_S5 == 0)
{
Nixie(3,1);
Nixie_dot(6,U1/100);
Nixie(7,U1/10%10);
Nixie(8,U1%10);
}
if(flag_S5 == 1)
{
Nixie(3,3);
Nixie_dot(6,U3/100);
Nixie(7,U3/10%10);
Nixie(8,U3%10);
}
}
}
//=====================定时器0和定时器1的初始化=====================
void InitTimer()
{
TMOD = 0x06;
TL0 = 0xff;
TH0 = 0xff;
TL1 = (65535 - 50000) % 256;
TH1 = (65535 - 50000) / 256; //0.05ms
TR0 = 1;
TR1 = 1;
EA = 1;
ET0 = 1;
ET1 = 1;
}
//===============================定时器0的中断服务函数============================
void Timer0_Isr(void) interrupt 1
{
count_f++;
}
void Timer1_Isr(void) interrupt 3
{
count++;
count_ms++;
if(count == 10)
{
dat_f = count_f*2;
count_f = 0;
count = 0;
}
}
//================================LED显示=============================
void LED()
{
hc573(0);
if(flag_LED == 1)
{
if(U3 > U_ROM) L1 = 0;
else L1 = 1;
if(dat_f > dat_f_ROM) L2 = 0;
else L2 = 1;
if(flag_S4 == 0) L3 = 0;
if(flag_S4 == 1) L4 = 0;
if(flag_S4 == 2) L5 = 0;
}
else P0 = 0xff;
hc573(4);
hc573(0);
}
void main()
{
Init_System();
InitTimer();
delay_l(400);
Write_ROM(0x01,255); delay_l(10);
Write_ROM(0x02,255); delay_l(10);
Write_ROM(0x03,255); delay_l(10);
Write_ROM(0x04,255); delay_l(10);
U_ROM = (Read_ROM(0x01)<<8)|Read_ROM(0x02);
dat_f_ROM = (Read_ROM(0x03)<<8)|Read_ROM(0x04);
while(1)
{
KeyScan();
display();
LED();
U1 = Read_PCF(0x01);
U3 = Read_PCF(0x03);
}
}
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
#include <intrins.H>
#define DELAY_TIME 5
sbit scl = P2^0;
sbit sda = P2^1;
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
void delay(unsigned int t)
{
while(t--);
}
unsigned int Read_PCF(unsigned char addr) //0x03为Rb2 0x01为光敏电阻
{
unsigned char i;
unsigned int dat;
for(i=0;i<=1;i++)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
dat = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
dat = dat * 100 / 51;
}
delay(1000);
return dat;
}
void Write_ROM(unsigned char addr,dat)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char Read_ROM(unsigned char addr)
{
unsigned char dat;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
dat = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return dat;
}
iic.h
#ifndef __iic_h__
#define __iic_h__
unsigned int Read_PCF(unsigned char addr);
void Write_ROM(unsigned char addr,dat);
unsigned char Read_ROM(unsigned char addr);
#endif