若代码有误,欢迎在评论区批评指正!
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 unsigned char Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1}; //16:U
code unsigned char Seg_Table_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
uchar flag_S4,flag_S5,flag_S6,flag_S7;
uint U,count_f,dat_f,count;
//=======================函数声明区================================
void hc573(uchar channel);
void delay_s(uint t);
void delay_l(uint xms);
void Nixie_dot(uchar loc,num);
void Nixie(uchar loc,num);
void Init_System();
void KeyScan();
void display();
void DAC_S6();
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(500);
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)
{
delay_s(100);
{
if(S4 == 0) //S4按下
{
flag_S4 = (flag_S4+1)%2;
while(S4 == 0)
{
display();
U = Read_PCF();
DAC_S6();
LED();
}
}
if(S5 == 0) //S5按下
{
flag_S5 = (flag_S5+1)%2;
while(S5 == 0)
{
display();
U = Read_PCF();
DAC_S6();
LED();
}
}
if(S6 == 0) //S5按下
{
flag_S6 = (flag_S6+1)%2;
while(S6 == 0)
{
display();
U = Read_PCF();
DAC_S6();
LED();
}
}
if(S7 == 0) //S5按下
{
flag_S7 = (flag_S7+1)%2;
while(S7 == 0)
{
display();
U = Read_PCF();
DAC_S6();
LED();
}
}
}
}
}
//================定时器初始化================================
void Init_Timer()
{
TMOD =0x16; // 计数器0 8位自动重装 定时器1 16位自动重载
TL1 = (65535 - 50000) % 256;
TH1 = (65536 - 50000) / 256;
TL0 = 0xff;
TH0 = 0xff;
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
}
//================定时器0的中端服务函数============================
void Timer0_Isr(void) interrupt 1 //计数器0
{
count_f++;
}
//================定时器1的中端服务函数============================
void Timer1_Isr(void) interrupt 3//定时器1
{
TL1 = (65535 - 50000) % 256;
TH1 = (65536 - 50000) / 256;
count++;
if(count == 10)
{
dat_f = count_f;
dat_f *=2;
count_f = 0;
count = 0;
}
}
//======================所有的数码管显示=========================================
void display()
{
if(flag_S7 == 0)
{
if(flag_S4==0) // 电压显示界面
{
Nixie(1,16);
Nixie_dot(6,U/100);
Nixie(7,U%100/10);
Nixie(8,U%10);
}
if(flag_S4==1) //频率显示界面
{
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);
}
}
else
{
hc573(0);
P0 = 0xff;
hc573(6);
hc573(0);
P0 = 0xff;
hc573(7);
hc573(0);
}
}
//===============S5控制的电压输出=================================
void DAC_S6()
{
if(flag_S5 == 0) Write_PCF(102);
else Write_PCF(U*51/100);
}
//===================S6控制下的LED显示============================
void LED()
{
hc573(0);
if(flag_S6 == 0)
{
if(flag_S4==0) L1 = 0;
if(flag_S4==1) L2 = 0;
if(U<150||(U>=250&&U<350)) L3 = 1;
if(U>=350||(U>=150&&U<250)) L3 = 0;
if(dat_f<1000||(dat_f>=5000&&dat_f<10000)) L4 = 1;
if(dat_f>=10000||(dat_f>=1000&&dat_f<5000)) L4 = 0;
if(flag_S5 == 0) L5 = 1;
if(flag_S5 == 1) L5 = 0;
}
else P0 = 0xff;
hc573(4);
hc573(0);
}
void main()
{
Init_System();
Init_Timer();
while(1)
{
KeyScan();
display();
U = Read_PCF();
DAC_S6();
LED();
}
}
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
#include <intrins.H>
#define DELAY_TIME 5
sbit sda = P2^1;
sbit scl = P2^0;
//
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 xms)
{
unsigned char i, j;
while(xms--)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
unsigned int Read_PCF()
{
unsigned int U;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
U = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
U = U*100/51;
delay(10);
return U;
}
void Write_PCF(unsigned char dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
iic.h
#ifndef __iic_h__
#define __iic_h__
unsigned int Read_PCF();
void Write_PCF(unsigned char dat);
#endif