单片机小项目——基于51单片机的温度报警器
项目功能介绍
- 编程语言:C语言。
- 开发环境:keil。
- 主要功能:1602屏显示时间和温度,当温度超过预定值时蜂鸣器工作报警。
- 此项目只是作为单片机初学者的一个小测验。
- 1602屏——P0,P2^7,P2^5,P2^6。
- 串口——P2^0,P2^1。
- 传感器——DS18B20 P3^7;DS1302 P3^4,P3^5,P3^6。
- 蜂鸣器——P1^6。
#ifndef __LCD1602_H_
#define __LCD1602_H_
#include//重定义关键字
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif//定义端口
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;
//函数声明
void Lcd1602_Delay1ms(uint c);
//延时函数
void LcdWriteCom(uchar com);
//写入命令
void LcdWriteData(uchar dat);
//写入数据
void LcdInit();
//LCD初始化子程序#endif
在LCD1602.c文件中写入时序和命令等函数代码:
#include "LCD1602.h"/***************************延时函数**************************/
void Lcd1602_Delay1ms(uint c)//误差 0us
{
uchar a,b;
for (;
c>0;
c--)
{
for (b=199;
b>0;
b--)
{
for(a=1;
a>0;
a--);
}
}}
/***************************底层函数**************************/
void LcdWriteCom(uchar com)//写入命令
{
LCD1602_E = 0;
//使能
LCD1602_RS = 0;
//选择发送命令
LCD1602_RW = 0;
//选择写入LCD1602_DATAPINS = com;
//放入命令
Lcd1602_Delay1ms(1);
//等待数据稳定LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;
}void LcdWriteData(uchar dat)//写入数据
{
LCD1602_E = 0;
//使能清零
LCD1602_RS = 1;
//选择输入数据
LCD1602_RW = 0;
//选择写入LCD1602_DATAPINS = dat;
//写入数据
Lcd1602_Delay1ms(1);
LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;
}void LcdInit()//LCD初始化子程序
{
LcdWriteCom(0x38);
//开显示
LcdWriteCom(0x0c);
//开显示不显示光标
LcdWriteCom(0x06);
//写一个指针加1
LcdWriteCom(0x01);
//清屏
LcdWriteCom(0x80);
//设置数据指针起点
}
【单片机小项目——基于51单片机的温度报警器】在main.c文件中运用:(这里先让显示屏显示自定义的内容,稍后再做更改)
#include "reg52.h"
#include "LCD1602.h"unsigned char Disp[]=" Pechin Science ";
void main()
{
unsigned char i=0;
LcdInit();
for(i=0;
i<16;
i++)
{
LcdWriteData(Disp[i]);
}
while(1)
{}
}
DS18B20温度传感器配置(并将其与LCD协同使用) 在DS18B20.c文件中写入相关函数:
#include "DS18B20.h"/***************************延时函数**************************/
void Delay1ms(unsigned int y)
{
unsigned int x;
for( ;
y>0;
y--)
{
for(x=110;
x>0;
x--);
}
}/***************************底层函数**************************/unsigned char Ds18b20Init()//初始化函数
{
unsigned char i;
DSPORT = 0;
//将总线拉低480us~960us
i = 70;
while(i--);
//延时642us
DSPORT = 1;
//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i = 0;
while(DSPORT)//等待DS18B20拉低总线
{
Delay1ms(1);
i++;
if(i>5)//等待>5MS
{
return 0;
//初始化失败
}}
return 1;
//初始化成功
}void Ds18b20WriteByte(unsigned char dat)//写入一个字节
{
unsigned int i, j;
for(j=0;
j<8;
j++)
{
DSPORT = 0;
//每写入一位数据之前先把总线拉低1us
i++;
DSPORT = dat & 0x01;
//然后写入一个数据,从最低位开始
i=6;
while(i--);
//延时68us,持续时间最少60us
DSPORT = 1;
//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
dat >>= 1;
}
}unsigned char Ds18b20ReadByte()//读取一个字节
{
unsigned char byte, bi;
unsigned int i, j;
for(j=8;
j>0;
j--)
{
DSPORT = 0;
//先将总线拉低1us
i++;
DSPORT = 1;
//然后释放总线
i++;
i++;
//延时6us等待数据稳定
bi = DSPORT;
//读取数据,从最低位开始读取
/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
byte = (byte >> 1) | (bi << 7);
i = 4;
//读取完之后等待48us再接着读取下一个数
while(i--);
}
return byte;
}/***************************高层函数**************************/voidDs18b20ChangTemp()//DS18B20转换温度
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);
//跳过ROM操作命令
Ds18b20WriteByte(0x44);
//温度转换命令
//Delay1ms(100);
//等待转换成功,而如果你是一直刷着的话,就不用这个延时了}voidDs18b20ReadTempCom()//发送读取温度命令
{Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);
//跳过ROM操作命令
Ds18b20WriteByte(0xbe);
//发送读取温度命令
}int Ds18b20ReadTemp()//读取温度
{
unsigned int temp = 0;
unsigned char tmh, tml;
Ds18b20ChangTemp();
//先写入转换命令
Ds18b20ReadTempCom();
//然后等待转换完后发送读取温度命令
tml = Ds18b20ReadByte();
//读取温度值共16位,先读低字节
tmh = Ds18b20ReadByte();
//再读高字节
temp = tmh;
temp <<= 8;
temp |= tml;
return temp;
}void dataprosTemp(unsigned int temp)//温度读取处理转换函
{
float tp;
DisplayTemp[0] = '+';
//因为测量温度为正,所以使开头为+;
tp=temp;
//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。DisplayTemp[1] = temp / 1000;
DisplayTemp[2] = temp % 1000 / 100;
DisplayTemp[3] = '.';
DisplayTemp[4] = temp % 100 / 10;
DisplayTemp[5] = temp % 10;
}
在DS18B20.h文件中声明:
#ifndef __DS18B20_H_
#define __DS18B20_H_
#include//定义使用的IO口
sbit DSPORT=P3^7;
//声明全局函数
void Delay1ms(unsigned int);
unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
voidDs18b20ChangTemp();
voidDs18b20ReadTempCom();
int Ds18b20ReadTemp();
void dataprosTemp(unsigned int temp);
//声明全局变量
extern unsigned char DisplayTemp[8];
#endif
在main.c函数中运用:
1 #include "reg52.h"
2 #include "LCD1602.h"
3 #include "DS18B20.h"
4
5
6
7 void main()
8 {
9unsigned int i;
10
11
12while(1)
13{
14LcdInit();
15
16dataprosTemp(Ds18b20ReadTemp());
//数据处理函数
17for(i=0;
i<6;
i++)
18{
19LcdWriteData(DisplayTemp[i]);
20}
21Delay1ms(100);
22}
23 }
遇到的问题及解决方法:
- 第一个问题:原本打算将函数 void datapros(unsigned int temp) 写在DS18B20.c文件中然后再在DS18B20.h文件中声明,但是该函数使用到数组 unsigned int DisplayData[8]; 且此数组在main.c文件中有所使用,但是在DS18B20.h文件中声明时,出现未知错误,无警告无错误但就是不能运行,所以将该函数直接写在main.c文件中。问题得到解决。
- 接上一个问题:数组unsigned int DisplayData[8]; 在DS18B20.h文件中无法定义情况。并不是无法定义,是因为缺少关键词extern。
- 第二个问题:因为要求显示温度,而温度是数字,但是LCD1602输入的数据必须是字符,直接传入数字LCD屏幕显示混乱。首次尝试将温度数字定义成字符类型,但是LCD屏显示乱码。初步估计输入类型必须是 ‘A’ 这种类型才能正常显示。再次尝试,使用折中的办法,在 void LcdWriteData(unsigned int dat) 写入数据函数中添加下列代码,将传递过来的温度数字通过switch的方法转换成 ‘A’ 这种类型字符,再将该字符传递给LCD1602,显示屏能正常显示。问题解决。(此代码更改的位置在LCD1602.c文件中)
void LcdWriteData(unsigned char dat)//写入数据
{
unsigned char datt;
if(dat != '.' && dat != '+')
{
switch(dat)
{
case 0:datt='0';
break;
case 1:datt='1';
break;
case 2:datt='2';
break;
case 3:datt='3';
break;
case 4:datt='4';
break;
case 5:datt='5';
break;
case 6:datt='6';
break;
case 7:datt='7';
break;
case 8:datt='8';
break;
case 9:datt='9';
break;
}
}
else
{
datt=dat;
}LCD1602_E = 0;
//使能允许
LCD1602_RS = 1;
//选择输入数据
LCD1602_RW = 0;
//选择写入LCD1602_DATAPINS = datt;
//写入数据
Lcd1602_Delay1ms(1);
LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;
}
- 第三个问题:LCD显示屏无法显示小数点。尝试使用if语句判断传进 void LcdWriteData(unsigned char dat) 函数的值是否是小数点,将上述的switch函数添加if--else语句。最终能显示显示小数点。问题解决。(此代码更改的位置在LCD1602.c文件中)
- 第四个问题:无法显示正号(因为本次项目测量温度为正值,所以没有考虑负号的情况,但负号也与此类似)。方法同上述小数点问题相同,添加if语句进行判断,最终能显示出正号,问题解决。
DS1302时钟模块配置在DS1302.c文件中写入对应函数:
#include "DS1302.h"//---DS1302时钟初始化2016年5月7日星期六12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
unsigned char TIME[7] = {0, 0, 0x12, 0x07, 0x05, 0x06, 0x16};
//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;
-------//
unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
void Ds1302Write(unsigned char addr, unsigned char dat)//向DS1302命令(地址+数据)
{
unsigned char n;
RST = 0;
_nop_();
SCLK = 0;
//先将SCLK置低电平。
_nop_();
RST = 1;
//然后将RST(CE)置高电平。
_nop_();
for (n=0;
n<8;
n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;
//数据从低位开始传送
addr >>= 1;
SCLK = 1;
//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0;
n<8;
n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;
//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}RST = 0;
//传送数据结束
_nop_();
}unsigned char Ds1302Read(unsigned char addr)//读取一个地址的数据
{
unsigned char n,dat,dat1;
RST = 0;
_nop_();
SCLK = 0;
//先将SCLK置低电平。
_nop_();
RST = 1;
//然后将RST(CE)置高电平。
_nop_();
for(n=0;
n<8;
n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;
//数据从低位开始传送
addr >>= 1;
SCLK = 1;
//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
//DS1302下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0;
n<8;
n++)//读取8位数据
{
dat1 = DSIO;
//从最低位开始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;
//DS1302下降沿时,放置数据
_nop_();
}RST = 0;
_nop_();
//以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}void Ds1302Init()//初始化DS1302.
{
unsigned char n;
Ds1302Write(0x8E,0X00);
//禁止写保护,就是关闭写保护功能
for (n=0;
n<7;
n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80);
//打开写保护功能
}void Ds1302ReadTime()//读取时钟信息
{
unsigned char n;
for (n=0;
n<7;
n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
}}void DS1302datapros()//时间读取处理转换函数
{
Ds1302ReadTime();
Ds1302DisplayTime[0] = TIME[2]/16;
//时
Ds1302DisplayTime[1] = TIME[2]&0x0f;
Ds1302DisplayTime[2] = '-';
//横杠
Ds1302DisplayTime[3] = TIME[1]/16;
//分
Ds1302DisplayTime[4] = TIME[1]&0x0f;
Ds1302DisplayTime[5] = '-' ;
//横杠
Ds1302DisplayTime[6] = TIME[0]/16;
//秒
Ds1302DisplayTime[7] = TIME[0]&0x0f;
}
在DS1302.h文件中声明函数:
#ifndef __DS1302_H_
#define __DS1302_H_#include
#include//---定义ds1302使用的IO口---//
sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;
//---定义全局函数---//
void Ds1302Write(unsigned char addr, unsigned char dat);
unsigned char Ds1302Read(unsigned char addr);
void Ds1302Init();
void Ds1302ReadTime();
void DS1302datapros();
//加入全局变量
extern unsigned char Ds1302DisplayTime[8];
#endif
在main.c函数中运用:
#include "reg52.h"
#include "LCD1602.h"
#include "DS18B20.h"
#include "DS1302.h"unsigned char DS18B20Display[8];
unsigned char Ds1302DisplayTime[8];
void Delay1ms(unsigned int y)
{
unsigned int x;
for( ;
y>0;
y--)
{
for(x=110;
x>0;
x--);
}
}void main()
{
unsigned int i;
Ds1302Init();
while(1)
{
LcdInit();
DS1302datapros();
//时间数据处理
DS18B20datapros(Ds18b20ReadTemp());
//温度数据处理函数
for(i=0;
i<8;
i++)
{
LcdWriteData(Ds1302DisplayTime[i]);
//显示时间
}
LcdWriteCom(0xc0);
//写入LCD地址命令,改变写入数据地址。
for(i=0;
i<6;
i++)
{
LcdWriteData(DS18B20Display[i]);
//显示温度
}
Delay1ms(100);
}
}
遇到到问题及解决方法:
- 第一个问题:代码运行后显示如下错误。经发现是 DS1302datapros() 函数后面的注释忘记加分号。修改后出现新的问题。
文章图片
- 第二个问题:修改第一个问题后出现如下问题,经翻译:出现多重定义。经过检查发现,是因为将数组 WRITE_RTC_ADDR[7] 和 READ_RTC_ADDR[7] 以及 TIME[7] 未在DS1302.c文件中定义,而是直接在DS1302.h文件中进行声明,所以出现错误。经过发现,出现的许多警告也是因为这种原因。修改后就没问题了。
文章图片
- 第三个问题:尝试在显示屏上同时显示时间和温度,且时间在第一行,温度在第二行。因为显示屏一行只显示16个字符,尝试将相关数组大小定义成16,并将多余位置定义成空格。但是尝试失败,因为显示屏内部的地址实际一行不是16个,只是本单片机只显示16个,内部的地址只运用了前面的16个,后面的没有使用,但是存在。所以最后实验结果是只显示出时间而没显示出温度。
- 接第三个问题:LCD屏内部地址是连续的,第一行末尾地址与第二行首地址也是连续的,但是一行不止16个地址,如下图所示。首地址是00,但是因为DB7位必须是1,所以设置地址要在原基础上加0x80。为解决第三个问题,在main.c函数中显示完时间后,添加 LcdWriteCom(0xc0);
改变写入LCD的数据地址。最终结果显示正确。
文章图片
文章图片
#include "reg52.h"
#include "FengMingQi.h"unsigned int i;
void FengMing(unsigned int temp)
{
unsigned int j=100;
if(temp>=30)
{
for(i=0;
i<50;
i++)
{
beep=~beep;
while(j--);
j=100;
}
}}
在FengMingQi.h函数中声明函数和串口:
#ifndef __FengMingQi_H_
#define __FengMingQi_H_#include
#includesbit beep = P1^6;
void FengMing(unsigned int temp);
#endif
在main.c中调用蜂鸣器函数:
#include "reg52.h"
#include "LCD1602.h"
#include "DS18B20.h"
#include "DS1302.h"
#include "FengMingQi.h"unsigned char DS18B20Display[8];
unsigned char Ds1302DisplayTime[8];
unsigned int temp;
void Delay1ms(unsigned int y)
{
unsigned int x;
for( ;
y>0;
y--)
{
for(x=110;
x>0;
x--);
}
}void main()
{
unsigned int i;
Ds1302Init();
while(1)
{
LcdInit();
DS1302datapros();
//时间数据处理
temp=DS18B20datapros(Ds18b20ReadTemp());
//温度数据处理函数
for(i=0;
i<8;
i++)
{
LcdWriteData(Ds1302DisplayTime[i]);
//显示时间
}
LcdWriteCom(0xc0);
//写入LCD地址命令,改变写入数据地址。
for(i=0;
i<6;
i++)
{
LcdWriteData(DS18B20Display[i]);
//显示温度
}
FengMing(temp);
//蜂鸣器的函数
Delay1ms(100);
}
}
出现的问题及解决方法:
- 问题一:出现重定义错误,在FengMingQi.c文件中定义了端口P1^6;然后又在FengMingQi.h文件中定义了一次,所以出现错误。
- 问题二:在代码运行无误时,将文件烧录到单片机上,时间和温度都能正常显示,但是在温度超过30后蜂鸣器未响应(这里因为室内温度20几度,用手捂住DS18B20温度传感器才勉强能达到30度,所以设置上限30度),但是当温度显示超过31度时,蜂鸣器响应。经分析发现,在蜂鸣器 void FengMing(unsigned int temp) 函数中定义的是unsigned int 类型,是整型,而在下面的 if 语句中使用的是temp>30,所以在31度时才会报警。修改后能正常实现功能。
#include "EEPROM.h"//延时函数10usvoid Delay10us()
{
unsigned char a,b;
for(b=1;
b>0;
b--)
for(a=2;
a>0;
a--);
}/**************************底层函数**********************/ //起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿,起始之后SDA和SCL都为0
void I2cStart()
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();
//建立时间是SDA保持时间>4.7us
SDA=0;
Delay10us();
//保持时间是>4us
SCL=0;
Delay10us();
}//终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿,结束之后保持SDA和SCL都为1,表示总线空闲
void I2cStop()
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();
//建立时间大于4.7us
SDA=1;
Delay10us();
}/**********************************高层函数*****************************************///通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定,发送成功返回1,发送失败返回0
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0;
//最大255,一个机器周期为1us,最大延时255us。
for(a=0;
a<8;
a++)//要发送8位,从最高位开始
{
SDA=dat>>7;
//起始信号之后SCL=0,所以可以直接改变SDA信号
dat=dat<<1;
Delay10us();
SCL=1;
Delay10us();
//建立时间>4.7us
SCL=0;
Delay10us();
//时间大于4us
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)//等待应答,也就是等待从设备把SDA拉低
{
b++;
if(b>200)//如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
{
SCL=0;
Delay10us();
return 0;
}
}
SCL=0;
Delay10us();
return 1;
}//使用I2c读取一个字节
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1;
//起始和发送一个字节之后SCL都是0
Delay10us();
for(a=0;
a<8;
a++)//接收8个字节
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
Delay10us();
SCL=0;
Delay10us();
}
return dat;
}//往24c02的一个地址写入一个数据
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2cStart();
I2cSendByte(0xa0);
//发送写器件地址
I2cSendByte(addr);
//发送要写入内存地址
I2cSendByte(dat);
//发送数据
I2cStop();
}//读取24c02的一个地址的一个数据
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0);
//发送写器件地址
I2cSendByte(addr);
//发送要读取的地址
I2cStart();
I2cSendByte(0xa1);
//发送读器件地址
num=I2cReadByte();
//读取数据
I2cStop();
return num;
}
在EEPROM.h文件中声明函数:
#ifndef __EEPROM_H_
#define __EEPROM_H_#include sbit SCL=P2^1;
sbit SDA=P2^0;
void I2cStart();
void I2cStop();
unsigned char I2cSendByte(unsigned char dat);
unsigned char I2cReadByte();
void At24c02Write(unsigned char addr,unsigned char dat);
unsigned char At24c02Read(unsigned char addr);
#endif
main.c函数中调用:
#include "reg52.h"
#include "LCD1602.h"
#include "DS18B20.h"
#include "DS1302.h"
#include "FengMingQi.h"
#include "EEPROM.h"unsigned char DS18B20Display[8];
unsigned char Ds1302DisplayTime[8];
unsigned int temp;
void Delay1ms(unsigned int y)
{
unsigned int x;
for( ;
y>0;
y--)
{
for(x=110;
x>0;
x--);
}
}void main()
{
unsigned int i;
TIME[0]=At24c02Read(1);
//读取EEPROM地址1内的时间数据保存在TIME中
TIME[1]=At24c02Read(2);
TIME[2]=At24c02Read(3);
Ds1302Init();
while(1)
{
LcdInit();
DS1302datapros();
//时间数据处理
At24c02Write(1,TIME[0]);
//在EEPROM地址1内写入时间数据
At24c02Write(2,TIME[1]);
//在EEPROM地址2内写入时间数据
At24c02Write(3,TIME[2]);
//在EEPROM地址3内写入时间数据temp=DS18B20datapros(Ds18b20ReadTemp());
//温度数据处理函数for(i=0;
i<8;
i++)
{
LcdWriteData(Ds1302DisplayTime[i]);
//显示时间
}LcdWriteCom(0xc0);
//写入LCD地址命令,改变写入数据地址。for(i=0;
i<6;
i++)
{
LcdWriteData(DS18B20Display[i]);
//显示温度
}FengMing(temp);
//蜂鸣器的函数Delay1ms(100);
//延时一段时间后再进行扫描温度。}
}
出现的问题及解决方法:
- 问题一:代码无误后烧录到单片机上,在一开始的几次开关电源中,时间正常显示且实现保存功能,但是多开关几次后时分秒显示错误,但是经测验,EEPROM的保存功任然能实现,即关电后再次开机任然显示上次的时间。初步检测是在main函数中一开始 读取EEPROM地址1内的时间数据保存在TIME中时 出现问题,这里应该需要一个if 语句判断是否EEPROM中是否保存有时间,但是这个判断用的变量也需要有保存功能,即在断电后该变量值不丢失,所以目前并未想到什么好的方法进行判断。这里可以应用按键或红外系统,即当按键按下时读取EEPROM中的时间,未按下时则不读取。因为某些原因这里就不再进行展示了。若后期想到什么好方法会进行更新。
推荐阅读
- 急于表达——往往欲速则不达
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 2019-02-13——今天谈梦想()
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- Ⅴ爱阅读,亲子互动——打卡第178天
- 低头思故乡——只是因为睡不着
- 取名——兰
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术