<>【蓝桥杯第十二届省赛】
#include "reg52.h" #include "onewire.h" #include "iic.h"
/*============================================ 第十二届蓝桥杯单片机 Date:2022.2.4
Author:小殷同学 Version:1.0 =============================================*/ 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; unsigned char Temperature
= 25; unsigned char Temperature_Param = 25;//温度参数设置 unsigned int voltage = 325;
//电压 扩大100倍方便计算显示 unsigned char interface_mode = 0,work_mode = 1; //界面切换 工作模式
unsigned char Temperature_start = 0,DAC_start = 0,count = 0;// 温度 DAC刷新标志 计时
unsigned char code SMG_duama[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 Delay(
unsigned int t) { while(t--); }
//-------------------------74HC138初始化------------------------- void Init_74HC138
(unsigned char n) { switch(n) { case 0:P2 = (P2 & 0x1f) | 0x00;break; 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; } }
//---------------------------系统初始化-------------------------- void Init_System(
void) { Init_74HC138(4); P0 = 0xff; Init_74HC138(5); P0 = 0x00; Init_74HC138(0);
} //--------------------------------数码管安位显示----------------- void SMG_DisplayBit
(unsigned char pos,unsigned char dat) { Init_74HC138(6); P0 = (0x01 << pos);
Init_74HC138(7); P0 = dat; }
//------------------------------数码管显示---------------------- void SMG_Close(void)
{ Init_74HC138(6); P0 = 0xff; Init_74HC138(7); P0 = 0xff; } void
SMG_Display_Volate(void) { SMG_DisplayBit(0,SMG_duama[10]); Delay(200);
SMG_DisplayBit(1,0xff); Delay(200); SMG_DisplayBit(2,0xff); Delay(200);
SMG_DisplayBit(3,0xff); Delay(200); SMG_DisplayBit(4,0xff); Delay(200);
SMG_DisplayBit(5,SMG_DOT[voltage/100]); Delay(200); SMG_DisplayBit(6,SMG_duama[
voltage/10%10]); Delay(200); SMG_DisplayBit(7,SMG_duama[voltage%10]); Delay(200)
; SMG_Close(); Delay(200); } void SMG_Display_Temperature(void) { SMG_DisplayBit
(0,SMG_duama[12]); Delay(200); SMG_DisplayBit(1,0xff); Delay(200);
SMG_DisplayBit(2,0xff); Delay(200); SMG_DisplayBit(3,0xff); Delay(200);
SMG_DisplayBit(4,SMG_duama[Temperature*100/1000]); Delay(200); SMG_DisplayBit(5,
SMG_DOT[Temperature*100/100%10]); Delay(200); SMG_DisplayBit(6,SMG_duama[
Temperature*100/10%10]); Delay(200); SMG_DisplayBit(7,SMG_duama[Temperature*100/
10%10]); Delay(200); SMG_Close(); Delay(200); } void SMG_Set_Temperature(void) {
//P 0011 0001 0X8C SMG_DisplayBit(0,0X8c); Delay(200); SMG_DisplayBit(1,0xff);
Delay(200); SMG_DisplayBit(2,0xff); Delay(200); SMG_DisplayBit(3,0xff); Delay(
200); SMG_DisplayBit(4,0xff); Delay(200); SMG_DisplayBit(5,0xff); Delay(200);
SMG_DisplayBit(6,SMG_duama[Temperature_Param/10]); Delay(200); SMG_DisplayBit(7,
SMG_duama[Temperature_Param%10]); Delay(200); SMG_Close(); Delay(200); }
//--------------------------------DS18B20------------------------ void
Read_Temperature(void) { unsigned char LSB,MSB; init_ds18b20(); Write_DS18B20(
0xcc); Write_DS18B20(0x44); Delay(500); init_ds18b20(); Write_DS18B20(0xcc);
Write_DS18B20(0xbe); LSB = Read_DS18B20(); MSB = Read_DS18B20(); init_ds18b20();
Temperature= (MSB << 8) | LSB; if(Temperature & 0xf800 == 0x0000) { Temperature
= Temperature >> 4; Temperature *= 10; Temperature = Temperature + (LSB & 0x0f)*
0.625; } } //---------------------------------PCF8591---------------------- void
Read_Rd2_DAC(float dat) { IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck();
IIC_SendByte(0x40); IIC_WaitAck(); IIC_SendByte(dat); IIC_WaitAck(); IIC_Stop();
} //----------------------------------矩阵键盘-------------------- void Matrix_Key(
void) { H3 = 0; H1 = H2 = H4 = 1; L1 = L2 = L3 = L4 = 1; //s9
在参数界面下按下S9按键,温度参数加1 if(L3 == 0) { Delay(20); if(L3 == 0) { while(L3 == 0) {
SMG_Set_Temperature(); //温度设置界面 } if(interface_mode == 1) //在温度界面下进行温度加一 {
Temperature_Param++; } } } //S5 定义为“模式”切换按键。 /* 模式1:DAC输出电压与温度相关。
通过DS18B20采集到的实时温度小于温度参数时,DAC输出0V, 否则,DAC输出5V。 模式2:DAC按照图7给出的关系输出电压。 */ if(L4 ==
0) { Delay(20); if(L4 == 0) { while(L4 == 0) { SMG_Display_Volate(); } if(
work_mode== 1) { if(Temperature < Temperature_Param) { Read_Rd2_DAC(0);
//实时温度小于温度参数时,DAC输出0V, voltage = 0; } else { Read_Rd2_DAC(255); //DAC输出5V
voltage= 500; //5v 扩大100 倍 方便计算 } work_mode = 2; } else if(work_mode == 2) {
work_mode= 0; if(Temperature <= 20) { //5/255 = 1/x x->255/5 Read_Rd2_DAC(51);
voltage= 100; //1v } else if(Temperature > 40) { //5/255 = 4/x x-> 204
Read_Rd2_DAC(204); voltage = 400; //4v } //关系式输出 else if(Temperature > 20 &&
Temperature< 40) { Read_Rd2_DAC((0.15*Temperature-2)*51.0); voltage = (0.15*
Temperature-2)*100; //扩大100倍方便计算 } work_mode = 1; } } } H4 = 0; H1 = H2 = H3 = 1
; L1 = L2 = L3 = L4 = 1; //s8 定义为“减”按键 参数界面下按下S8按键,温度参数减1 if(L3 == 0) { Delay(20
); if(L3 == 0) { while(L3 == 0) { SMG_Set_Temperature(); //温度设置界面 } if(
interface_mode== 1) //在温度界面下进行温度减一 { Temperature_Param--; } } } //S4
定义为“界面”按键,按下S4按键,切换温度显示界面、参数设置界面和DAC输出界面, if(L4 == 0) { Delay(20); if(L4 == 0) {
while(L4 == 0) { if(interface_mode == 0) { interface_mode = 1;
SMG_Display_Temperature(); //温度显示界面 } else if(interface_mode == 1) {
interface_mode= 2; SMG_Set_Temperature(); //温度设置界面 } else if(interface_mode == 2
) { interface_mode = 0; SMG_Display_Volate(); //电压显示界面 } } } } }
//--------------------------------LED功能处理------------------- void Led_Running(
void) { //当前处于模式1状态,指示灯L1点亮,否则熄灭 Init_74HC138(4); if(work_mode == 1) { P0 = 0x7f
; //0111 1111 } switch(interface_mode) { case 0:P0 = 0xfd;break;
//当前处于温度显示界面,指示灯L2点亮,否则熄灭 case 1:P0 = 0xfb;break;//当前处于参数设置界面,指示灯L3点亮,否则熄灭。 case
2:P0 = 0xf7;break; //当前处于DAC输出界面,指示灯L4点亮,否则熄灭 } /* if(interface_mode == 0) { P0
= 0xfd; //1011 1111 } //当前处于参数设置界面,指示灯L3点亮,否则熄灭。 if(interface_mode == 1) { P0 =
0xfb; //1101 1111 } //当前处于DAC输出界面,指示灯L4点亮,否则熄灭 if(interface_mode == 2) { P0 =
0xf7; //1110 1111 } */ }
//--------------------------------定时器初始化------------------- void Init_Timer(void
) { TMOD = 0x01; TH0 = (65535-50000)/256; //50MS TL0 = (65535-50000)%256; ET0 =
1; TR0 = 1; EA = 1; }
//----------------------------主函数----------------------------- void main(void) {
Init_System(); Init_Timer(); while(1) { Matrix_Key(); Read_Temperature(); switch
(interface_mode) { case 0:SMG_Display_Temperature();break; case 1:
SMG_Set_Temperature();break; case 2:SMG_Display_Volate(); break; } Led_Running()
; } } //----------------------------------中断服务函数---------------- //温度数据刷新时间:≤1秒。
//DAC输出电压刷新时间:≤0.5秒 void Server_Timer0() interrupt 1 { TH0 = (65535-50000)/256;
TL0= (65535-50000)%256; count++; if(count == 10) //0.5s { if(DAC_start == 0 )
//DAC刷新标志 { DAC_start = 1; } else if(DAC_start == 1) { DAC_start = 0; } } if(
count== 20)// 1s { if(Temperature_start == 0) //温度刷新标志 { Temperature_start = 1;
} else if(Temperature_start == 1) { Temperature_start = 0; } count = 0; } }