1、自己写过程中遇到的问题及解决:
①上电后:温度显示00(会延迟好几秒才会显示正常的环境温度)
升温过程:温度变化不灵敏(时间比较长,温度跨度变化大)17℃——24℃(中 间隔好几秒才变)
②矩阵键盘按键不灵敏:按好几遍可能才会变化
解决:DS18B20 温度读取函数中涉及到延时,在前面模块化学习过程中延时700~900ms:
将延时减短,问题解决!(同时发现:此时延时可以不用动态扫描数码管),如下:
/*================DS18B20温度传感器============================================
=============================================================================*/
void Delay(unsigned int t)
{
while(t--);
// {
// ShowSMG();//检测发现:去掉动态扫描,效果更好一些
// }
}
void Read_DS18B20_temp()
{
unsigned char LSB, MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(200);//********按键不灵敏、温度读取不灵敏:延时时间缩短一点!!***********
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();//读低8位
MSB = Read_DS18B20();//读高8位
init_ds18b20();
temp = MSB;
temp <<= 8;
temp = temp | LSB;
temp >>= 4;//移除小数位
}
③灯闪烁的时候灭得非常快,一亮就灭:
LED熄灭应该写在按键里——就熄灭一次(不能循环!!!)
参考代码:
#include "reg52.h"
#include "onewire.h"
sfr P4 = 0xc0;
unsigned char code SMG_duanma[19] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9 A10 B11 C12 D13 E14 F15
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -16 .17
0xbf,0x7f,0xff}; //共阳数码管
unsigned char yi, er, san, si, wu, liu, qi, ba;
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;//行
sbit L1 = P4^4;
sbit L2 = P4^2;
sbit L3 = P3^5;//列
unsigned char led = 0;//灭
unsigned int temp;//温度(问题:温度为0??)temp16位!!用int!!!!
unsigned char Tmax = 30;//温度上限
unsigned char Tmin = 20;//温度下限
unsigned char qujian = 0;//0:T<tmin / 1:tmin<= t <=tmax / 2:t>tmax
unsigned char set = 0;//设置键
unsigned char clear = 0;//清除键
unsigned char key = 0;//按键标志位
unsigned char shu;//按键值
void InitHC138(unsigned char n)
{
switch(n)
{
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 Delayms(unsigned int ms)//延时 ms
{
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 845; j > 0;j--);
}
/*================系统初始化===================================================
关闭LED、蜂鸣器与继电器
=============================================================================*/
void InitSystem()
{
InitHC138(4);
P0 = 0xff;
InitHC138(5);
P0 = 0x00;
}
/*===============数码管========================================================
=============================================================================*/
void SMG_Bit(unsigned pos, unsigned char dat)
{
InitHC138(6);
P0 = 0x01 << pos;
InitHC138(7);
P0 = dat;
}
void SMG_All(unsigned char dat)
{
InitHC138(6);
P0 = 0xff;
InitHC138(7);
P0 = dat;
}
void ShowSMG()
{
SMG_Bit(0, SMG_duanma[yi]);
Delayms(1);
SMG_Bit(1, SMG_duanma[er]);
Delayms(1);
SMG_Bit(2, SMG_duanma[san]);
Delayms(1);
SMG_Bit(3, SMG_duanma[si]);
Delayms(1);
SMG_Bit(4, SMG_duanma[wu]);
Delayms(1);
SMG_Bit(5, SMG_duanma[liu]);
Delayms(1);
SMG_Bit(6, SMG_duanma[qi]);
Delayms(1);
SMG_Bit(7, SMG_duanma[ba]);
Delayms(1);
SMG_All(0xff);//防止最后一位数码管过亮
}
/*================3X4矩阵按键==================================================
=============================================================================*/
void ScanKeys()
{
//第一行:
H1 = 0; H2 = H3 = H4 = 1;
L1 = L2 = L3 = 1;
if (L1 == 0)
{
Delayms(5);
if (L1 == 0)
{
shu = 0;
key = 1;
}
while(!L1)
{
ShowSMG();
}
}
else if (L2 == 0)
{
Delayms(5);
if (L2 == 0)
{
shu = 1;
key = 1;
}
while(!L2)
{
ShowSMG();
}
}
else if (L3 == 0)
{
Delayms(5);
if (L3 == 0)
{
shu = 2;
key = 1;
}
while(!L3)
{
ShowSMG();
}
}
//第二行:
H2 = 0; H1 = H3 = H4 = 1;
L1 = L2 = L3 = 1;
if (L1 == 0)
{
Delayms(5);
if (L1 == 0)
{
shu = 3;
key = 1;
}
while(!L1)
{
ShowSMG();
}
}
else if (L2 == 0)
{
Delayms(5);
if (L2 == 0)
{
shu = 4;
key = 1;
}
while(!L2)
{
ShowSMG();
}
}
else if (L3 == 0)
{
Delayms(5);
if (L3 == 0)
{
shu = 5;
key = 1;
}
while(!L3)
{
ShowSMG();
}
}
//第三行:
H3 = 0; H2 = H1 = H4 = 1;
L1 = L2 = L3 = 1;
if (L1 == 0)
{
Delayms(5);
if (L1 == 0)
{
shu = 6;
key = 1;
}
while(!L1)
{
ShowSMG();
}
}
else if (L2 == 0)
{
Delayms(5);
if (L2 == 0)
{
shu = 7;
key = 1;
}
while(!L2)
{
ShowSMG();
}
}
else if (L3 == 0)
{
Delayms(5);
if (L3 == 0)
{
shu = 8;
key = 1;
}
while(!L3)
{
ShowSMG();
}
}
//第四行:
H4 = 0; H2 = H3 = H1 = 1;
L1 = L2 = L3 = 1;
if (L1 == 0)
{
Delayms(5);
if (L1 == 0)
{
shu = 9;
key = 1;
}
while(!L1)
{
ShowSMG();
}
}
else if (L2 == 0)//设置键:按下进入设置界面;再次按下保存数据
{
Delayms(5);
if (L2 == 0)
{
if (set == 0)
{
set = 1;//进入界面
yi = 16; er = 18; san = 18; si = 18; wu = 18;
liu = 16; qi = 18; ba = 18;//Tmax/Tmin:进入界面为熄灭状态
InitHC138(4);//设置的时候把LED、蜂鸣器继电器关闭(题目没有要求)
P0 = 0xff;
InitHC138(5);
P0 = 0x00;
}
else if (set == 1)
{
set = 0;//保存数据
InitHC138(4);
P0 = 0xff;//修正错误并保存数据后,L2熄灭
}
}
while(!L2);
}
else if (L3 == 0)//清除键
{
Delayms(5);
if (L3 == 0)
{
if (clear == 0)
{
clear = 1;//按下清除(所有数据)
}
while(!L3)
{
ShowSMG();
}
}
}
}
/*================DS18B20温度传感器============================================
=============================================================================*/
void Delay(unsigned int t)
{
while(t--);
// {
// ShowSMG();//检测发现:去掉动态扫描,效果更好一些
// }
}
void Read_DS18B20_temp()
{
unsigned char LSB, MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(200);//********按键不灵敏、温度读取不灵敏:延时时间缩短一点!!***********
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();//读低8位
MSB = Read_DS18B20();//读高8位
init_ds18b20();
temp = MSB;
temp <<= 8;
temp = temp | LSB;
temp >>= 4;//移除小数位
}
/*==================定时器T0===================================================
0:继电器关闭,L1 0.8秒闪烁 160
1:继电器关闭,L1 0.4秒闪烁 80
2:继电器打开,L1 0.2秒闪烁 40
0.2s = 200ms = 20 0000us = 40*5000us
=============================================================================*/
unsigned char count = 0;
void Init_Timer0()//定时器中断函数
{
TMOD = 0x01;
TH0 = (65535 - 5000) / 256;
TL0 = (65535 - 5000) % 256;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void ServiceTimer0() interrupt 1 //中断服务函数
{
TH0 = (65535 - 5000) / 256;
TL0 = (65535 - 5000) % 256;//非自动重装模式
if (set == 0)//非设置模式的时候 L1才闪烁
{
count++;
if (qujian == 0)//区间0:继电器关闭,L1 0.8s闪烁
{
if (count == 160)
{
count = 0;
if (led == 0)//0.8s L1闪烁
{
led = 1;
InitHC138(4);
P0 = 0xfe;
}
else if (led == 1)
{
led = 0;
InitHC138(4);
P0 = 0xff;
}
}
}
else if (qujian == 1)//区间1:继电器关闭,L1 0.4s闪烁
{
if (count == 80)
{
count = 0;
if (led == 0)
{
led = 1;
InitHC138(4);
P0 = 0xfe;
}
else if (led == 1)
{
led = 0;
InitHC138(4);
P0 = 0xff;
}
}
}
else if (qujian == 2)//区间2:继电器打开,L1 0.2s闪烁
{
if (count == 40)
{
count = 0;
if (led == 0)
{
led = 1;
InitHC138(4);
P0 = 0xfe;
}
else if (led == 1)
{
led = 0;
InitHC138(4);
P0 = 0xff;
}
}
}
}
}
//*****************主函数******************************************************
void main()
{
InitSystem();
Init_Timer0();
yi = 16; er = qujian; san = 16; si = 18; wu = 18; liu = 18;
qi = temp/10; ba = temp%10;//一定要写初始化 不然上电的时候数码管全是0000 0000
while(1)
{
ShowSMG();
ScanKeys();
Read_DS18B20_temp();
if (set == 0)//没设置的时候(保存数据)
{
if (temp < Tmin)
{
qujian = 0;//区间0:继电器关闭
InitHC138(5);
P0 = 0x00;
}
else if ((temp >= Tmin) && (temp <= Tmax))
{
qujian = 1;//区间1:继电器关闭
InitHC138(5);
P0 = 0x00;
}
else if (temp > Tmax)
{
qujian = 2;//区间2:打开继电器
InitHC138(5);
P0 = 0x10;
}
yi = 16; er = qujian; san = 16; si = 18; wu = 18; liu = 18;
qi = temp/10; ba = temp%10;
}
else if (set == 1)//设置
{
if (clear == 1)//清除键
{
clear = 0;//释放状态
yi = 16; er = 18; san = 18; si = 18; wu = 18;
liu = 16; qi = 18; ba = 18;//所有数据清除
}
if ((er == 18) && (key == 1))//key=1,按键按下
{
key = 0;//释放状态
er = shu;
}
else if ((san == 18) && (key == 1))
{
key = 0;
san = shu;
}
else if ((qi == 18) && (key == 1))
{
key = 0;
qi = shu;
}
else if ((ba == 18) && (key == 1))
{
key = 0;
ba = shu;
Tmax = er*10 + san;
Tmin = qi*10 + ba;
if (Tmin > Tmax)//设置错误(L2亮 数据清除(清除后也亮?))
{
InitHC138(4);
P0 = 0xfd;//L2亮
yi = 16; er = 18; san = 18; si = 18; wu = 18;
liu = 16; qi = 18; ba = 18;//数据全部清除
}
}
}
}
}