我的项目性能介绍

  • 编程语言: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。

LCD1602屏配置

在h文件中申明端口和函数:

#ifndef __LCD1602_H_#define __LCD1602_H_#include<reg52.h>//重定义关键字#ifndef uchar#define uchar unsigned char#endif#ifndef uint #define uint unsigned int#endif//定义端口#define LCD1602_DATAPINS P0sbit 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);  //设置数据指针终点}

在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;}/***************************高层函数**************************/void  Ds18b20ChangTemp()            //DS18B20转换温度{    Ds18b20Init();    Delay1ms(1);    Ds18b20WriteByte(0xcc);            //跳过ROM操作命令    Ds18b20WriteByte(0x44);        //温度转换命令    //Delay1ms(100);                        //期待转换胜利,而如果你是始终刷着的话,就不必这个延时了}void  Ds18b20ReadTempCom()        //发送读取温度命令{    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<reg52.h>//定义应用的IO口sbit DSPORT=P3^7;//申明全局函数void Delay1ms(unsigned int);unsigned char Ds18b20Init();void Ds18b20WriteByte(unsigned char com);unsigned char Ds18b20ReadByte();void  Ds18b20ChangTemp();void  Ds18b20ReadTempCom();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 { 9     unsigned int i;10 11 12     while(1)13     {14         LcdInit();15 16         dataprosTemp(Ds18b20ReadTemp());     //数据处理函数17         for(i=0;i<6;i++)18         {19             LcdWriteData(DisplayTemp[i]);    20         }21         Delay1ms(100);22     }23 }

遇到的问题及解决办法:

  1. 第一个问题:本来打算将函数 void datapros(unsigned int temp) 写在DS18B20.c文件中而后再在DS18B20.h文件中申明,然而该函数应用到数组 unsigned int DisplayData[8]; 且此数组在main.c文件中有所应用,然而在DS18B20.h文件中申明时,呈现未知谬误,无正告无谬误但就是不能运行,所以将该函数间接写在main.c文件中。问题失去解决。
  2. 接上一个问题:数组unsigned int DisplayData[8]; 在DS18B20.h文件中无奈定义状况。并不是无奈定义,是因为短少关键词extern。
  3. 第二个问题:因为要求显示温度,而温度是数字,然而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;}
  1. 第三个问题:LCD显示屏无奈显示小数点。尝试应用if语句判断传进 void LcdWriteData(unsigned char dat) 函数的值是否是小数点,将上述的switch函数增加if--else语句。最终能显示显示小数点。问题解决。(此代码更改的地位在LCD1602.c文件中)
  2. 第四个问题:无奈显示正号(因为本次我的项目测量温度为正值,所以没有思考负号的状况,但负号也与此相似)。办法同上述小数点问题雷同,增加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<reg52.h>#include<intrins.h>//---定义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的数据地址。最终结果显示正确。

蜂鸣器配置:

在FengMingQi.c函数中增加蜂鸣器相干代码:

#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<reg52.h>#include<intrins.h>sbit 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度时才会报警。批改后能失常实现性能。

EEPROM配置:

在EEPROM.c文件中增加相干代码:

#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都为0void 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,发送失败返回0unsigned 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 <reg52.h>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中的工夫,未按下时则不读取。因为某些起因这里就不再进行展现了。若前期想到什么好办法会进行更新。