首先说明,本人沿用小蜜蜂老师代码风格,练习第14届省赛赛题。
第一感觉难度并不是很大,主要是沉下心写代码。
具体思路是将每个硬件模块先写出来,再去写每个界面的数码管转换,由简入难。
代码注释较少,有兴趣可以一起讨论。
代码功能基本实现,但仍有不足,望批
#include "reg52.h"
#include "ds1302.h"
#include "iic.h"
#include "onewire.h"
sfr P4 = 0xC0;
//频率变量(湿度)
unsigned int f_dat;
unsigned int f_count;
unsigned char t_count;
unsigned char time_count;
unsigned char clean_count;
unsigned char temp_led_count;
float hum_dat;
float get_hum;
unsigned int max_hum;
unsigned int st_hum;
unsigned int sum_hum;
unsigned int old_hum;
//
//ds1302变量
unsigned char code Wirte_DS1302[] = {0x80,0x82,0x84,0x86,0x88,0x8A,0x8C};
unsigned char code Read_DS1302[] = {0x81,0x83,0x85,0x87,0x89,0x8B,0x8D};
//2024年 4月 2日 星期二 13时3分5秒
unsigned char Time[] = {0x05,0x03,0x13,0x02,0x04,0x02,0x24};
unsigned char Triger_Time[]= {0,0};
//
//温度变量
unsigned int temp;
unsigned int get_temp;
unsigned int max_temp;
unsigned int st_temp;
unsigned char set_temp = 30;
unsigned int sum_temp;
unsigned int old_temp;
//
//光敏电阻
unsigned char rd1_dat;
//
//矩阵键盘
sbit H1 = P3^2;
sbit H2 = P3^3;
sbit L1 = P4^4;
sbit L2 = P4^2;
unsigned char Key_Num;
//
unsigned char Triger_Count;//触发次数
unsigned char mode_s4;
unsigned char state;//光敏状态
unsigned char mode_s5;
unsigned char time_state;
unsigned char clean_flag;
unsigned char temp_state_led;
//led状态
unsigned char led_state;
unsigned char SMG_duanma[]={
0xc0,//0
0xf9,//1
0xa4,//2
0xb0,//3
0x99,//4
0x92,//5
0x82,//6
0xf8,//7
0x80,//8
0x90,//9
0x88,//A
0x83,//B
0xc6,//C
0xa1,//D
0x86,//E
0x8e,//F
0xbf,//
0x7f//
};
unsigned char SMG_duanma_Dot[]={
0x40,//0
0x79,//1
0x24,//2
0x30,//3
0x19,//4
0x12,//5
0x02,//6
0x78,//7
0x00,//8
0x10//9
};
void DisPlay_Time();
void DisPlay_Temp();
void DisPlay_Hum();
void DisPlay_Triger_Time();
void DisPlay_Temp_Set();
void Delay(unsigned int t)
{
while(t--);
}
void Select_HC573(unsigned char channel , dat)
{
P0 = dat;
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;
}
P2 = (P2 & 0x1F) | 0x00;
}
//==============数码管显示==================//
void Delay_SMG(unsigned int t)
{
while(t--);
}
void SMG_Bit(unsigned char pos , value)
{
Select_HC573(6 , 0xFF);
Select_HC573(7 , 0xFF);
Select_HC573(6 , 0x01 << pos);
Select_HC573(7 , value);
}
//=======================================//
//=============频率测量=================//
void Init_Timer0()
{
TMOD = 0x16;
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256;
TH0 = 0xFF;
TL0 = 0xFF;
ET0 = 1;
ET1 = 1;
EA = 1;
TR0 = 1;
TR1 = 1;
}
void Service_Timer0() interrupt 1
{
f_count ++;
}
void Service_Timer1() interrupt 3
{
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256;
t_count ++;
if(t_count >= 5)
{
f_dat = f_count * 4;
f_count = 0;
t_count = 0;
}
if(time_state == 1)
{
time_count ++;
if(time_count >= 60)
{
time_state = 0;
time_count = 0;
}
}
if(clean_flag == 1)
{
clean_count ++;
if(clean_count >= 40 && L2 == 0)
{
clean_flag = 0;
clean_count = 0;
max_temp = 0;
st_temp = 0;
sum_temp = 0;
max_hum = 0;
st_hum = 0;
sum_hum = 0;
old_temp = 0;
old_hum = 0;
get_hum = 0;
get_temp = 0;
Triger_Count = 0;
Triger_Time[0] = 0;
Triger_Time[1] = 0;
}
}
if(temp_state_led == 1)
{
temp_led_count ++;
if(temp_led_count >= 2)
{
temp_led_count = 0;
led_state = led_state ^ 0x08;
Select_HC573(4,led_state);
}
}
}
void humidity_update()
{
if(f_dat > 2000)
{
hum_dat = 0xAA;
}
else if(f_dat > 200)
{
hum_dat = (f_dat - 200) * 80.0 / 1800.0 + 10;
}
else if(f_dat > 0)
{
hum_dat = 0xAA;
}
}
//=======================================//
//=============时间======================//
void DS1302_Congfig()
{
char i;
Write_Ds1302(0x8E , 0x00);
for(i = 0;i < 7;i ++)
{
Write_Ds1302(Wirte_DS1302[i] , Time[i]);
}
Write_Ds1302(0x8E , 0x80);
}
void Read_DS1302_Timer()
{
char i;
for(i=0;i<7;i++)
{
Time[i] = Read_Ds1302_Byte(Read_DS1302[i]);
}
}
//=======================================//
//================温度===================//
void Read_DS13B20_Temp()
{
unsigned char LSB , MSB;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
Delay(1000);
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
temp = MSB;
temp = (temp << 8) | LSB;
temp = temp >> 4;//舍去小数
}
//========================================//
//=================光敏电阻====================//
void Read_LR()
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x01);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
rd1_dat = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
if(rd1_dat < 50)
{
state = 1;
}
if(rd1_dat > 150)
{
if(state == 1 && time_state == 0)
{
get_hum = hum_dat;
if(get_hum != 0xAA)
{
Triger_Count ++;
old_hum = get_hum;
old_temp = get_temp;
state = 0;
if(temp > max_temp) //温度
{
max_temp = temp;
}
sum_temp += temp;
st_temp = sum_temp * 10 / Triger_Count ;
get_temp = temp;
if(hum_dat > max_hum) //湿度
{
max_hum = hum_dat;
}
sum_hum += hum_dat;
st_hum = sum_hum * 10 / Triger_Count ;
get_hum = hum_dat;
Triger_Time[0] = Time[1];
Triger_Time[1] = Time[2];
time_state = 1;
led_state |= 0x10;
Select_HC573(4,led_state);
}
else
{
led_state &= 0xEF;
Select_HC573(4,led_state);
}
}
}
}
//=========================================//
//==================矩阵键盘====================//
void Scan_Key()
{
H1 = 0;
H2 = 1;
L1 = L2 = 1;
if(L1 == 0) //5键码
{
if(mode_s5 == 0)
{
mode_s5 = 1;
while(L1 == 0)
{
DisPlay_Hum();
}
}
else if(mode_s5 == 1)
{
mode_s5 = 2;
while(L1 == 0)
{
DisPlay_Triger_Time();
}
}
else if(mode_s5 == 2)
{
mode_s5 = 0;
while(L1 == 0)
{
DisPlay_Temp();
}
}
}
else if(L2 == 0) //9键码
{
if(mode_s4 == 2)
{
set_temp -= 1;
}
if(mode_s5 == 2)
{
clean_flag = 1;
while(L2 == 0);
}
while(L2 == 0)
{
DisPlay_Temp_Set();
}
}
H1 = 1;
H2 = 0;
L1 = L2 = 1;
if(L1 == 0) //4键码
{
Key_Num = 4;
if(mode_s4 == 0)
{
mode_s4 = 1;
while(L1 == 0)
{
DisPlay_Temp();
}
mode_s5 = 0;
}
else if(mode_s4 == 1)
{
mode_s4 = 2;
while(L1 == 0)
{
DisPlay_Temp_Set();
}
}
else if(mode_s4 == 2)
{
mode_s4 = 0;
while(L1 == 0)
{
DisPlay_Time();
}
}
}
else if(L2 == 0) //8键码
{
if(mode_s4 == 2)
{
set_temp += 1;
}
while(L2 == 0)
{
DisPlay_Temp_Set();
}
}
}
void DisPlay_Time()
{
SMG_Bit(0 , SMG_duanma[Time[2] / 16]);
Delay_SMG(500);
SMG_Bit(1 , SMG_duanma[Time[2] % 16]);
Delay_SMG(500);
SMG_Bit(2 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(3 , SMG_duanma[Time[1] / 16]);
Delay_SMG(500);
SMG_Bit(4 , SMG_duanma[Time[1] % 16]);
Delay_SMG(500);
SMG_Bit(5 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(6 , SMG_duanma[Time[0] / 16]);
Delay_SMG(500);
SMG_Bit(7 , SMG_duanma[Time[0] % 16]);
Delay_SMG(500);
SMG_Bit(7 ,0xFF);
Delay_SMG(500);
}
void DisPlay_Temp()
{
SMG_Bit(0 , SMG_duanma[12]);
Delay_SMG(500);
SMG_Bit(1 , 0xFF);
Delay_SMG(500);
SMG_Bit(2 ,SMG_duanma[max_temp / 10]);
Delay_SMG(500);
SMG_Bit(3 ,SMG_duanma[max_temp % 10]);
Delay_SMG(500);
SMG_Bit(4 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(5 ,SMG_duanma[st_temp / 100]);
Delay_SMG(500);
SMG_Bit(6 ,SMG_duanma_Dot[st_temp /10 % 10]);
Delay_SMG(500);
SMG_Bit(7 ,SMG_duanma[st_temp % 10]);
Delay_SMG(500);
SMG_Bit(7 ,0xFF);
Delay_SMG(500);
}
void DisPlay_Hum()
{
SMG_Bit(0 , 0x89);
Delay_SMG(500);
SMG_Bit(1 , 0xFF);
Delay_SMG(500);
SMG_Bit(2 ,SMG_duanma[max_hum / 10]);
Delay_SMG(500);
SMG_Bit(3 ,SMG_duanma[max_hum % 10]);
Delay_SMG(500);
SMG_Bit(4 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(5 ,SMG_duanma[st_hum / 100]);
Delay_SMG(500);
SMG_Bit(6 ,SMG_duanma_Dot[st_hum /10 % 10]);
Delay_SMG(500);
SMG_Bit(7 ,SMG_duanma[st_hum % 10]);
Delay_SMG(500);
SMG_Bit(7 ,0xFF);
Delay_SMG(500);
}
void DisPlay_Triger_Time()
{
SMG_Bit(0 , SMG_duanma[15]);
Delay_SMG(500);
SMG_Bit(1 , SMG_duanma[Triger_Count / 10]);
Delay_SMG(500);
SMG_Bit(2 , SMG_duanma[Triger_Count % 10]);
Delay_SMG(500);
SMG_Bit(3 , SMG_duanma[Triger_Time[1] / 16]);
Delay_SMG(500);
SMG_Bit(4 , SMG_duanma[Triger_Time[1] % 16]);
Delay_SMG(500);
SMG_Bit(5 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(6 ,SMG_duanma[Triger_Time[0] / 16]);
Delay_SMG(500);
SMG_Bit(7 ,SMG_duanma[Triger_Time[0] % 16]);
Delay_SMG(500);
SMG_Bit(7 ,0xFF);
Delay_SMG(500);
}
void DisPlay_TH();
void DisPlay_Temp_Set()
{
SMG_Bit(7 ,SMG_duanma[set_temp % 10]);
Delay_SMG(500);
SMG_Bit(6 ,SMG_duanma[set_temp / 10]);
Delay_SMG(500);
SMG_Bit(0 ,0x8C);
Delay_SMG(500);
SMG_Bit(0 ,0xFF);
Delay_SMG(500);
}
void DisPlay()
{
if(time_state == 1)
{
DisPlay_TH();
}
else
{
if(mode_s4 == 0)
{
DisPlay_Time();
}
else if(mode_s4 == 1)
{
if(mode_s5 == 0)
{
DisPlay_Temp();
}
else if(mode_s5 == 1)
{
DisPlay_Hum();
}
else if(mode_s5 == 2)
{
DisPlay_Triger_Time();
}
}
else if(mode_s4 == 2)
{
DisPlay_Temp_Set();
}
}
}
void DisPlay_TH()
{
SMG_Bit(0 , SMG_duanma[14]);
Delay_SMG(500);
SMG_Bit(1 , 0xFF);
Delay_SMG(500);
SMG_Bit(2 , 0xFF);
Delay_SMG(500);
SMG_Bit(3 , SMG_duanma[get_temp / 10]);
Delay_SMG(500);
SMG_Bit(4 , SMG_duanma[get_temp % 10]);
Delay_SMG(500);
SMG_Bit(5 , SMG_duanma[16]);
Delay_SMG(500);
SMG_Bit(6 ,SMG_duanma[((int)get_hum) /10]);
Delay_SMG(500);
SMG_Bit(7 ,SMG_duanma[((int)get_hum) % 10]);
Delay_SMG(500);
SMG_Bit(7 ,0xFF);
Delay_SMG(500);
}
//=======================================//
void LED_state_led()
{
if(mode_s4 == 0)
{
led_state = (led_state & 0xF8) | ~(0x01);
Select_HC573(4,led_state);
}
else if(mode_s4 == 1)
{
led_state = (led_state & 0xF8) | ~(0x02);
Select_HC573(4,led_state);
}
else if(mode_s4 == 2)
{
led_state = (led_state & 0xF8) | ~(0x04);
Select_HC573(4,led_state);
}
if(get_temp > set_temp)
{
temp_state_led = 1;
}
else
{
temp_state_led = 0;
}
if(get_hum > old_hum && get_temp > old_temp & Triger_Count >= 2)
{
led_state = (led_state & 0xDF);
Select_HC573(4,led_state);
}
else
{
led_state = (led_state | ~(0xDF));
Select_HC573(4,led_state);
}
}
void main()
{
Init_Timer0();
DS1302_Congfig();
while(1)
{
Read_LR();
Read_DS13B20_Temp();
Read_DS1302_Timer();
humidity_update();
Scan_Key();
LED_state_led();
DisPlay();
}
}
评指正。