如需代码,请自行提取:
链接:https://pan.quark.cn/s/47819f80b290
提取码:feWn
main.c
#include <REGX52.H>
#include <stdio.H>
#include <iic.H>
#include <onewire.H>
#include <intrins.H>
#define u8 unsigned char
#define u16 unsigned int
#define LED(X) {hc573(0); P0 = X; hc573(4); hc573(0);}
#define BUZ(X) {hc573(0); P0 = X; hc573(5); hc573(0);}
#define COM(X) {hc573(0); P0 = X; hc573(6); hc573(0);}
#define SMG(X) {hc573(0); P0 = X; hc573(7); hc573(0);}
sfr P4 = 0xc0;
sfr AUXR = 0x8e;
sbit R1 = P3^5;
sbit R2 = P4^4;
sbit C1 = P3^2;
sbit C2 = P3^3;
code u8 Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1};//10:熄灭 11:U
u8 tab[8]={10},flag_smg,flag_key,keyvalue,keystatus;
u16 temp,U,flag_collect;
u8 ui,PC,PC1,flag_led,flag_L3,flag,flag_BUZ;
bit flag_dsp;
float UART_U,UART_TEMP;
u8 led=0xff,dot;
//==========================函数声明区====================
void hc573(u8 channel);
void Timer0_Init(void); //1毫秒@12.000MHz
void display();
void Nixie(u8 loc,num);
void Set_tab();
void InitSys();
void Collect();
void KeyScan();
void UartInit(void);
void taskKey();
void SendByte(float date);
void SendString(u8 *s);
//========================================================
void Delay850ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 39;
j = 195;
k = 2;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void hc573(u8 channel)
{
switch(channel)
{
case 4: P2 = (P2&0x1f)|0x80;break;
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 Timer0_Isr(void) interrupt 1
{
display();
if(flag_smg<20) flag_smg++;
if(flag_key<20) flag_key++;
if(flag_collect<200) flag_collect++;
if(flag_led<20) flag_led++;
if(flag_L3<100) flag_L3++;
if(flag_BUZ<100) flag_BUZ++;
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
void display()
{
static u8 i;
SMG(0xff);
COM(0x01<<i);
if((i+1)!=dot) {SMG(Seg_Table[tab[i]]);}
else SMG(Seg_Table[tab[i]]&0x7f);
i = (i+1)%8;
}
void Set_tab()
{
if(flag_smg<20) return;
flag_smg = 0;
switch(ui)
{
case 0:
dot = 7;
tab[0] = 11;
tab[1] = 1;
tab[2] = 10;
tab[3] = 10;
tab[4] = 10;
tab[5] = temp/100;
tab[6] = temp%100/10;
tab[7] = temp%10;
break;
case 1:
dot = 6;
tab[0] = 11;
tab[1] = 2;
tab[2] = 10;
tab[3] = 10;
tab[4] = 10;
tab[5] = U/100;
tab[6] = U%100/10;
tab[7] = U%10;
}
}
void Collect()
{
if(flag_collect<200) return;
flag_collect = 0;
U = PCF_Read();
temp = Read_temp();
}
void KeyScan()
{
if(flag_key<20) return;
flag_key = 0;
switch(keystatus)
{
case 0:
R2 = 0;C1 = C2 = R1 = 1;
if(C1 == 0||C2 == 0) //S4或者S5按下
{
keystatus = 1;
break;
}
R1 = 0;C1 = C2 = R2 = 1;
if(C2 == 0) //S12按下
{
keystatus = 2;
break;
}
break;
case 1:
if(C1 == 0) keyvalue = 5;
if(C2 == 0) keyvalue = 4;
keystatus = 3;
break;
case 2:
if(C2 == 0) keyvalue = 12;
keystatus = 3;
break;
case 3:
if(C1 == 1&&C2 == 1) keystatus = 0;
break;
}
}
void taskKey()
{
switch(keyvalue)
{
case 4: if(flag == 0) flag = 1 ; //串口通信关闭
led|=0x04;
keyvalue = 0; break;
case 5: if(flag == 1) flag = 0; //串口通信解锁
led|=0x04; LED(led);
keyvalue = 0; break;
case 12:
ES = 0;
if(flag_dsp == 1)
{
UART_U = ((float)U)/100;
printf("Voltage:%.2f",UART_U);
}
if(flag_dsp == 0)
{
UART_TEMP = ((float)temp)/10;
printf("TEMP:%.1fV",UART_TEMP);
}
keyvalue = 0; ES = 1;break;
default :keyvalue = 0; break;
}
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
EA = 1;
ES = 1;
}
void SendByte(float date)
{
SBUF = date;
while(TI == 0);
TI = 0;
}
char putchar(char c)
{
SendByte(c);
return c;
}
void UART() interrupt 4
{
if(RI==1&&flag==0)
{
RI = 0;
PC = SBUF;
if(PC =='A')
{
ui = 0;
flag_dsp = 0; //温度显示界面
}
if(PC =='B')
{
ui = 1;
flag_dsp = 1; //电压显示界面
}
}
else
{
PC1= SBUF;
RI = 0;
}
}
void LED_control()
{
if(flag_led<20) return;
flag_led = 0;
if(flag_dsp == 0) led&=~0x01;
else led |= 0x01;
if(flag_dsp == 1) led&=~0x02;
else led |= 0x02;
LED(led);
}
void LED_L3()
{
if(flag == 1)
{
if(flag_L3 < 100) return;
flag_L3 = 0;
led^=0x04;
LED(led);
}
}
void InitSys()
{
BUZ(0x00);
LED(0xff);
}
void BUZ_C()
{
static buz = 0x00;
if(flag_BUZ < 100) return;
flag_BUZ = 0;
if(temp/10>=28) buz |= 0x10;
else buz &=~0x10;
if(U/10>=36&&U%10!=0&&flag==0) buz |= 0x40;
else buz &=~0x40;
BUZ(buz);
}
void main()
{
temp = Read_temp();
Delay850ms();
temp = Read_temp();
InitSys();
UartInit();
Timer0_Init();
while(1)
{
Set_tab();
Collect();
KeyScan();
taskKey();
LED_control();
LED_L3();
BUZ_C();
}
}
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);
}
unsigned int PCF_Read()
{
unsigned int U;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
U = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
U = U * 100 /51;
return U;
}
iic.h
#ifndef __iic_H__
#define __iic_H__
unsigned int PCF_Read();
#endif
onewire.c
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
unsigned int Read_temp()
{
unsigned char LSB,MSB;
unsigned int temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Delay_OneWire(500);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8) | LSB ;
temp = temp*0.0625*10;
return temp;
}
onewire.h
#ifndef __onewire_H__
#define __onewire_H__
unsigned int Read_temp();
#endif