蓝桥杯第五届省赛题-简易温度采集与控制装置
#include "reg52.h"
#include "onewire.h"
#include "intrins.h"
/*####################################################
Date:2022-1-22
Author:小殷同学
#####################################################*/
sfr P4 = 0xC0;
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;
sbit Led1 = P0^0;
sbit Led2 = P0^1;
unsigned char clr = 0,key_value = 0; //清除标志位和键值
unsigned char Current_Temp = 0,T_Max = 30,T_Min = 20; //分别记录当前温度和默认最大值与最小值温度
unsigned char setmode = 0; //温度显示模式和设置模式标志
unsigned char T_Mode = 0 ;// 温度模式
unsigned char t_count = 0; //计时用于Led的不同闪烁时间
unsigned char flag = 0,Led_flag; //按键按下标志位 和led闪烁标志
unsigned char yi,er,san,si,wu,liu,qi,ba; //数码管位
//0-9 0xbf代表 -
unsigned char code SMG_Duan_num[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};
//-----------------------------简单延时-----------------------------
void Delay_ms(unsigned char t) //@11.0592MHz
{
while(t--);
}
//--------------------------------74HC138初始化-------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;//Y4
case 5:P2 = (P2 & 0x1f) | 0xa0;break;//Y5
case 6:P2 = (P2 & 0x1f) | 0xc0;break;//Y6
case 7:P2 = (P2 & 0x1f) | 0xe0;break;//Y7
case 0:P2 = (P2 & 0x1f) | 0x00;break;//关闭
}
}
//--------------------------------系统初始化----------------------------
void InitSystem(void)
{
//关闭Led
Init_74HC138(4);
P0 = 0xff;
//关闭继电器和蜂鸣器
Init_74HC138(5);
P0 = 0x00;
}
//---------------------------------数码管安位显示-------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
Init_74HC138(6); //Y6
P0 = (0x01 << pos);
Init_74HC138(7);//Y7
P0 = dat;
}
//---------------------------------关闭所有数码管--------------------------
void SMG_Close(unsigned char dat)
{
Init_74HC138(6);
P0 = 0xff; //全部选通
Init_74HC138(7);
P0 = dat;
}
//------------------------------------设置温度界面显示---------------------
void Display1(unsigned char yi,unsigned char er)
{
SMG_DisplayBit(0,SMG_Duan_num[yi]); //-
Delay_ms(100);
SMG_DisplayBit(1,SMG_Duan_num[er]); //
Delay_ms(100);
}
void Display2(unsigned char san,unsigned char si)
{
SMG_DisplayBit(2,SMG_Duan_num[san]); //-
Delay_ms(100);
SMG_DisplayBit(3,SMG_Duan_num[si]); //
Delay_ms(100);
}
void Display3(unsigned char wu,unsigned char liu)
{
SMG_DisplayBit(4,SMG_Duan_num[wu]); //-
Delay_ms(100);
SMG_DisplayBit(5,SMG_Duan_num[liu]); //
Delay_ms(100);
}
void Display4(unsigned char qi,unsigned char ba)
{
SMG_DisplayBit(6,SMG_Duan_num[qi]); //-
Delay_ms(100);
SMG_DisplayBit(7,SMG_Duan_num[ba]); //
Delay_ms(100);
}
//---------------------------------按键初始化-------------------------------
void Init_Keys(void)
{
H1 = 0;
H2 = H3 = H4 = 1;
L1 = L2 = L3 = L4 = 1;
if(L2 == 0)
{
Delay_ms(20);
if(L2 == 0)
{
while(L2 == 0);
key_value = 2;
// S15_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
else if(L3 == 0)
{
Delay_ms(20);
if(L3 == 0)
{
while(L3 == 0);
key_value = 1;
// S11_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
else if(L4 == 0)
{
Delay_ms(20);
if(L4 == 0)
{
while(L4 == 0);
key_value = 0;
//S7_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
H2 = 0;
H1 = H3 = H4 = 1;
L1 = L2 = L3 = L4 = 1;
if(L2 == 0)
{
Delay_ms(20);
if(L2 == 0)
{
while(L2 == 0);
key_value = 5;
//S15_Flag = 14;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
else if(L3 == 0)
{
Delay_ms(20);
if(L3 == 0)
{
while(L3 == 0);
key_value = 4;
//S10_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
else if(L4 == 0)
{
Delay_ms(20);
if(L4 == 0)
{
while(L4 == 0);
key_value = 3;
//S6_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
H3 = 0;
H2 = H1 = H4 = 1;
L1 = L2 = L3 = L4 = 1;
if(L2 == 0)
{
Delay_ms(20);
if(L2 == 0)
{
while(L2 == 0);
key_value = 8;
//S13_Flag = 1;
flag = 1;
//SMG_DisplayBit(0,SMG_Duan_num[key_value]);
}
}
else if(L3 == 0)
{
Delay_ms(20);
if(L3 == 0)
{
while(L3 == 0);
key_value = 7;
//S9_Flag = 1;
flag = 1;
}
}
else if(L4 == 0)
{
Delay_ms(20);
if(L4 == 0)
{
while(L4 == 0);
key_value= 6 ;
//S5_Flag = 1;
flag = 1;
}
}
H4 = 0;
H2 = H3 = H1 = 1;
L1 = L2 = L3 = L4 = 1;
if(L2 == 0)
{
Delay_ms(20);
if(L2 == 0)
{
while(L2 == 0)
{
if(clr == 0)
{
clr = 1;
yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
}
else if(clr == 1)
{
clr = 0;
yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi = 11,ba = 11;
}
}
//SMG_DisplayBit(0,SMG_Duan_num[clr]);
}
}
else if(L3 == 0)
{
Delay_ms(20);
if(L3 == 0)
{
// S8_Flag = 1;
if(setmode == 0)
{
setmode = 1; //按键按下进入温度设置界面
Init_74HC138(5);
P0 = 0x00; //设置界面下时关闭继电器
//yi = 10,er = T_Max/10,san = T_Max%10,si = 11,wu = 11,liu = 10,qi =T_Min/10,ba = T_Min%10;
yi = 10,er = 11,san = 11,si = 11,wu = 11,liu = 10,qi =11,ba = 11;
}
else if(setmode == 1)
{
setmode == 0; //按键按下进入温度显示界面
EA = 1,ET0 = 1;
// yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
}
}
}
else if(L4 == 0)
{
Delay_ms(20);
if(L4 == 0)
{
while(L4 == 0);
key_value = 9;
// S9_Flag = 1;
flag = 1;
}
}
}
//--------------------------------------温度获取-----------------------------
void Read_DS18B20_T(void)
{
unsigned char LSB ,MSB; //分别存储低第0字节和第一字节
init_ds18b20(); //DS18B20复位初始化
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0x44); //开始温度转换
Delay_ms(800); //延时700-900ms
init_ds18b20(); //DS18B20复位初始化
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0xBE); //读取高速暂存器
LSB = Read_DS18B20(); //暂存器第0字节
MSB = Read_DS18B20();//暂存器第1字节
Current_Temp = MSB;
Current_Temp = (Current_Temp << 8) | LSB; //整体16字节数据
Current_Temp = Current_Temp >> 4; //移除小数部分
//下面为显示小数处理
/*
if((temp & 0xf800) == 0x0000)
{
temp >>= 4; //将小数移除
temp = temp *10;
temp = temp + (LSB & 0x0f)*0.625;
}
*/
if(Current_Temp < T_Min ) //温度区间0 继电器关闭
{
T_Mode = 0;
Init_74HC138(5); //选通Y5控制继电器
P0 = 0x00;//关闭继电器
}
//温度区间1 继电器关闭
else if(Current_Temp >= T_Min && Current_Temp <= T_Max)
{
T_Mode = 1;
Init_74HC138(5); //选通Y5控制继电器
P0 = 0x00;//关闭继电器
}
//温度区间2 继电器打开
else if(Current_Temp > T_Max)
{
T_Mode = 2;
Init_74HC138(5); //选通Y5控制继电器
P0 = 0x10;//打开继电器
}
}
//------------------------------定时器初始化----------------------------
void Init_Timer0(void)
{
TMOD = 0x01;
TH0 = (65535-20000)/256;
TL0 = (65535-20000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//-------------------------------主函数--------------------------------
void main(void)
{
InitSystem();
Init_Timer0();
yi = 1,er = 2,san = 3,si = 4,wu = 5,liu = 6,qi = 7,ba = 8;//检测数码管是否正常
while(1)
{
Init_Keys();
if(setmode == 0) //非设置模式 显示实时温度
{
//温度获取
Read_DS18B20_T();
Delay_ms(20);
yi = 10,er = T_Mode,san = 10,si = 11,wu = 11,liu = 11,qi = Current_Temp/10,ba = Current_Temp%10;
}
else if(setmode == 1) //判断是否在设置状态下
{
EA = 0,ET0 = 0;
if (er == 11 && flag == 1)
{
flag = 0;
er = key_value;
}
else if(san == 11 && flag == 1)
{
san = key_value;
flag = 0;
}
else if(qi == 11 && flag == 1)
{
qi = key_value;
flag = 0;
}
else if(ba == 11 && flag == 1)
{
ba = key_value;
flag = 0;
if((er * 10 + san) < (qi * 10 + ba))//最大值小于最小值L2点亮
{
Init_74HC138(4);
P0 = 0xfd;
}
else if((er * 10 + san) >= (qi * 10 + ba))
{
T_Max = (er * 10 + san);
T_Min = (qi * 10 + ba);
Init_74HC138(4);
P0 = 0xff;
}
}
}
Display1(yi,er);
Display2(san,si);
Display3(wu,liu);
Display4(qi,ba);
}
}
//-----------------------------中断服务函数-------------------------------
void Server_Timer0() interrupt 1
{
TH0 = (65535-20000)/256; //20ms
TL0 = (65535-20000)%256;
t_count++;
if(t_count == 40 && T_Mode == 0)//温度区间0,继电器关闭,指示灯L1以0.8秒为间隔闪烁
{
t_count = 0;
if(Led_flag == 0)
{
Led_flag = 1;
Init_74HC138(4); //选通Y4控制Led
P0 = 0xfe;
}
else if(Led_flag == 1)
{
Led_flag = 0;
Init_74HC138(4);
P0 = 0xff;
}
}
//温度区间1,继电器关闭,指示灯L1以0.4秒为间隔闪烁;
else if(t_count == 20 && T_Mode == 1)
{
t_count = 0;
if(Led_flag == 0)
{
Led_flag = 1;
Init_74HC138(4);
P0 = 0xfe;
}
else if(Led_flag == 1)
{
Led_flag = 0;
Init_74HC138(4);
P0 = 0xff;
}
}
//温度区间2,继电器打开,指示灯L1以0.2秒为间隔闪烁。
else if(t_count == 10 && T_Mode == 2)
{
t_count = 0;
if(Led_flag == 0)
{
Led_flag = 1;
Init_74HC138(4);
P0 = 0xfe;
}
else if(Led_flag == 1)
{
Led_flag = 0;
Init_74HC138(4);
P0 = 0xff;
}
}
}