qq_40679302
机械猫
2021-06-03 20:38
采纳率: 0%
浏览 20

时间加温度显示为什么温度不显示求大佬帮忙

#include<reg52.h>
#include <math.h>
#include <intrins.h>   //使用 _nop_()将会用到此头文件
#define uchar unsigned char
#define uint unsigned int

//ds1302寄存器宏定义
#define WRITE_SECOND 0x80
#define WRITE_MINUTE 0x82
#define WRITE_HOUR   0x84
#define WRITE_DATE 0x86
#define WRITE_MONTH 0x88
#define WRITE_DAY   0x8A
#define WRITE_YEAR   0x8C
#define READ_SECOND   0x81
#define READ_MINUTE 0x83
#define READ_HOUR    0x85
#define READ_DATE   0x87
#define READ_MONTH 0x89
#define READ_DAY    0x8B
#define READ_YEAR   0x8D
#define WRITE_PROTECT 0x8E
#define pos_year   L1+0           //设置显示年的位置
#define pos_month  L1+3
#define pos_date   L1+6
#define pos_day    L1+9
#define pos_hour   L2+0
#define pos_minute L2+3
#define pos_sec L2+6

//1602连接定义
#define DATA P0
sbit RS1602=P2^6;
sbit RW1602=P2^5;
sbit E1602=P2^7;
#define L1 0x80    // 液晶显示第一行起始地址 然后再加上所有位序号(从0开始)
#define L2 0xc0    //液晶显示第二行起始地址 0x80+0x40

//1302管脚定义
sbit sclk=P3^6; // DS1302时钟信号 7脚
sbit clk_io=P3^4;    // DS1302数据信号   6脚
sbit clk_rst=P3^5;   // DS1302片选   5脚

//18b20定义
sbit DQ=P3^7;             //定义DS18B20接口
uint t,tshi,tge,txs1,txs2; //温度显示用
unsigned int Readtemp();      //读取温度int temp;       
void delay(uchar z);
void tmpDelay(int num);     //延时函数
int get_temp(void);    //获得温度
void tmpchange(void);   //发送温度转换命令
void tmpwritebyte(uchar dat); //写一个字节到DS18B20里
uchar tmpread(void);   //读一个字节
bit tmpreadbit(void);     // 读一位
int temp;
void dsreset(void);      //DS18B20初始化
void delayb(uint count); //delay
void temp_display();   //温度显示


//功能按键定义
sbit func_key=P3^0;
sbit inc_key=P3^2;
sbit dec_key=P3^3;

//地址、数据发送子程序
void delay(uchar);
void write1602_comd(uchar);
void write1602_data(uchar);
void init1602_lcd();
void keyscan();
void Init_DS1302();    
void update_time();
uchar flag=0;
uchar code table1[]="09-10-30/5";      //初始化显示,主要用显示及保持格式符,不是初始值
uchar code table2[]="12:00:00";          //初始值在Init_DS1302()


void init1602_lcd()
{
    int i;
     write1602_comd(0x01);
     write1602_comd(0x0c);
     write1602_comd(0x06);
     write1602_comd(0x3C); // 功能设置 :2行显示模式,数据为8位。还有字体的设置。
     
     write1602_comd(0x80);    //设置第一行地址指针
     
     for(i=0;i<10;i++)   //初始化显示,用于显示格式符
         { 
          write1602_data(table1[i]);
         delay(20);
        }

     write1602_comd(0xc0); // 设置第二行地址指针

     for(i=0;i<8;i++)
         { 
         write1602_data(table2[i]);
         delay(20);
         }
}

void delay(uchar z)
{
uchar i,j;
for(j=z;j>0;j--)   
for(i=125;i>0;i--); 
}

void write1602_comd(uchar com)
{
RS1602=0;
DATA=com;
RW1602=0;
delay(5);
E1602=1;
delay(5);
E1602=0;
}

void write1602_data(uchar datatowrite)
{
   RS1602=1;
   DATA=datatowrite;
   RW1602=0;
   delay(5);
   E1602=1;
   delay(5);
   E1602=0;
}


void writeds1602_byte(uchar dat)    
{
uchar i,dat_w;
dat_w=dat;        //数据送给变量dat_w
for(i=0;i<8;i++)
{
    clk_io=0;            //数据线先拉低
    if(dat_w&0x01)    //如果是1
    {clk_io=1;}
    else              //如果是0
    {clk_io=0;}
    dat_w=dat_w>>1; //右移一位
    sclk=0;          //先拉低时钟信号
    sclk=1;          //拉高时钟信号 
}    
sclk=0;            //写一字节完毕,拉低时钟信号
}

//-------------------------------
//---- 从DS1302读一字节 (下降沿有效) --------
//---- 读出数据时从低位0位到高位7 -----------
//-------------------------------

uchar readds1602_byte()
{
uchar i,k; 
k=0;
for(i=0;i<8;i++)
{
k=k>>1;
if(clk_io)
{k=k|0x80;}
sclk=1;          //先拉低时钟信号
sclk=0;
}
sclk=0;
return (k);
}

//-------------------------------
//---- 指定地址写一数据 --------
//-------------------------------

void Write1602(uchar add,uchar dat) //dat为十进制数
{
clk_rst=0;
sclk=0;
clk_rst=1;                              //拉高RST
writeds1602_byte(add);                  // 写地址
writeds1602_byte((dat/10<<4)|(dat%10)); // DS1302中的时间数据是BCD码形式
sclk=0;
clk_rst=0;
}

//-------------------------------
//---- 指定地址读出一数据 ------
//-------------------------------

uchar Read1302(uchar add)
{
uchar temp,dat1,dat2;
clk_rst=0;
sclk=0;
clk_rst=1;
writeds1602_byte(add);
temp=readds1602_byte(); //读取的数据为16进制
sclk=0;              //读取完毕,拉低SCLK
clk_rst=0;              //拉低SCLK

dat1=temp/16;        //16进制转成BCD
dat2=temp%16;
temp=dat1*10+dat2; //转换成10进制数字
return (temp);   

}


//初始化DS1302
void Init_DS1302(void)    
{     //设置初始化时间
       Write1602 (WRITE_PROTECT,0X00); delay(1); //禁止写保护
     Write1602 (WRITE_SECOND,0x00); delay(1);   //秒位初始化
       Write1602 (WRITE_MINUTE,0x00);delay(1); //分钟初始化
       Write1602 (WRITE_HOUR,0x0C); delay(1); //小时初始化
    Write1602 (WRITE_DAY,0x01); delay(1);   //星期初始化
       Write1602 (WRITE_DATE,0x12);delay(1); //日初始化
       Write1602 (WRITE_MONTH,0x05); delay(1); //月初始化
    Write1602 (WRITE_YEAR,0x09); delay(1); //年初始化
       Write1602 (WRITE_PROTECT,0x80); delay(1);//允许写保护
}

/*************** 以下为:读写年、月、日、时、分、秒的子程序*******************/
/*不包括星期在内
功能:从DS1302中读出时间和日期,并在1602液晶上显示出来
三个参数分别为:1.读时间日期存储器地址 2.写入的十位光标地址 3.个位光标地址 */
void read_write_date_time(uchar _1302_addr, _1602_addr)  //把1302的com_addr
{
uchar high,low,get_data;

   Write1602 (WRITE_PROTECT,0x00);
    delay(1); //禁止写保护
   get_data=Read1302(_1302_addr); //秒
   high=get_data/10;
   low=get_data%10;

   write1602_comd(_1602_addr);// 设置第二行地址指针
   write1602_data(high+0X30);
   write1602_data(low+0X30);
   Write1602 (WRITE_PROTECT,0x80); delay(1); //允许写保护

}

void write_lcd(uchar cusr_addr,time_data )
{
uchar hour_wei,ge_wei;
   hour_wei=time_data/10;
   ge_wei=time_data%10;
   write1602_comd(cusr_addr);// 设置第二行地址指针
   write1602_data(hour_wei+0X30);
   write1602_data(ge_wei+0X30);
}
void update_time()
{
   uchar xq;
   read_write_date_time(READ_HOUR,L2);       //小时
   read_write_date_time(READ_MINUTE,L2+3);
   read_write_date_time(READ_SECOND,L2+6);
   read_write_date_time(READ_YEAR,L1);
   read_write_date_time(READ_MONTH,L1+3);
   read_write_date_time(READ_DATE,L1+6);     //日期

   xq=Read1302(READ_DAY);                    //星期
   write1602_comd(L1+9);
   write1602_data(xq+0X30);
   Write1602 (WRITE_PROTECT,0x80);           //允许写保护 
}


//键盘处理

uchar first=1,num,second,minute,hour,day,date,month,year;

void keyscan()

if(first==1) //读取当前值,用于调整的基准
{
second=Read1302(READ_SECOND);
minute=Read1302(READ_MINUTE);
hour=Read1302(READ_HOUR);
day=Read1302(READ_DAY);
date=Read1302(READ_DATE);
month=Read1302(READ_MONTH);
year=Read1302(READ_YEAR);
   }
   first=0;
if(func_key==0) 
{
    delay(5);
    if(func_key==0)
     { 
     num++;
     flag=1;
     while(!func_key);
     if(num==1)
     {
      clk_rst=0; //停止时钟转换
      write1602_comd(pos_sec); //调整秒 将光标移动到秒位置
      write1602_comd(0x0f); //光标闪烁
     }
         }
    if(num==2)
    {
     write1602_comd(pos_minute); //将光标移动到分钟
    }
    if(num==3)
    {
     write1602_comd(pos_hour); //将光标移动到小时
    }
    if(num==4)
    {
     write1602_comd(pos_day); //将光标移动到星期
    }
    if(num==5)
    {
     write1602_comd(pos_date); //将光标移动到日
    }
    if(num==6)
    {
     write1602_comd(pos_month); //将光标移动到月
    }
    if(num==7)
    {
     write1602_comd(pos_year); //将光标移动到年
    }
    if(num==8)       //保存调整后的数据
    {
     num=0;
     write1602_comd(0x0c);   //光标停止闪烁
     flag=0;
     clk_rst=1; //开始时钟转换 
    
     Write1602 (WRITE_PROTECT,0x00);delay(1); //禁止写保护

     Write1602(WRITE_SECOND,second);delay(1);    //秒位初始化 ,写入DS1302
                Write1602(WRITE_MINUTE,minute); delay(1); //分钟初始化
           Write1602(WRITE_HOUR,hour); delay(1); //小时初始化
           Write1602(WRITE_DAY,day); delay(1); //星期初始化
           Write1602(WRITE_DATE,date); delay(1); //日初始化
           Write1602(WRITE_MONTH,month); delay(1); //月时初始化
           Write1602(WRITE_YEAR,year); delay(1); //年时初始化
     Write1602 (WRITE_PROTECT,0x80); delay(1); //允许写保护

     first=1;      //用于下次调整时重新读当前值

       }    
   }
   if(num!=0)
   {
    if(inc_key==0)
    {
     delay(1);
     if(inc_key==0)
     {
      while(!inc_key);
      if(num==1)       //秒
      {
       second++;
       if(second==60)
        second=0;
       write_lcd(pos_sec,second);//秒位初始化,写入液晶显示
       write1602_comd(pos_sec); //置光标
      
      }
      if(num==2)     //分
      {
       minute++;
       if(minute==60)
        minute=0;
       write_lcd(pos_minute,minute);
       write1602_comd(pos_minute); //置光标

      }
      if(num==3)     //时
      {
       hour++;
       if(hour==24)
        hour=0;
       write_lcd(pos_hour,hour);
         write1602_comd(pos_hour); //置光标

      }
      if(num==4)     //星期
      {
       day++;
       if(day==8)
        day=1;
         write1602_comd(pos_day); //置光标
                  write1602_data(day+0X30);

      }
      if(num==5)     //日
      {
       date++;
       if(date==32)
        date=1;
       write_lcd(pos_date,date);
         write1602_comd(pos_date); //置光标

      }
      if(num==6)     //月
      {
       month++;
       if(month==13)
        month=1;
       write_lcd(pos_month,month);
         write1602_comd(pos_month); //置光标

      }
      if(num==7)     //年
      {
       year++;
       if(year==99)
        hour=0;
       write_lcd(pos_year,year);
         write1602_comd(pos_year); //置光标

      }
     }
    }
    if(dec_key==0)
    {
     delay(1);
     if(dec_key==0)
     {
      while(!dec_key);
      if(num==1)       //秒
      {
       second--;
       if(second==-1)
        second=59;
       write_lcd(pos_sec,second);//秒位初始化,写入液晶显示
       write1602_comd(pos_sec); //置光标
      
      }
      if(num==2)     //分
      {
       minute--;
       if(minute==-1)
        minute=59;
       write_lcd(pos_minute,minute);
       write1602_comd(pos_minute); //置光标

      }
      if(num==3)     //时
      {
       hour--;
       if(hour==-1)
        hour=23;
       write_lcd(pos_hour,hour);
         write1602_comd(pos_hour); //置光标

      }
      if(num==4)     //星期
      {
       day--;
       if(day==0)
        day=7;
         write1602_comd(pos_day); //置光标
                  write1602_data(day+0X30);

      }
      if(num==5)     //日
      {
       date--;
       if(date==0)
        date=31;
       write_lcd(pos_date,date);
         write1602_comd(pos_date); //置光标

      }
      if(num==6)     //月
      {
       month--;
       if(month==0)
        month=12;
       write_lcd(pos_month,month);
         write1602_comd(pos_month); //置光标

      }
      if(num==7)     //年
      {
       year--;
       if(year==0)
        hour=15;
       write_lcd(pos_year,year);
         write1602_comd(pos_year); //置光标

      }
     }
    }   
   }
}

/******************************温度获取相关的函数——开始********************************************************************/
void temp_display()
{
    tshi=t/1000;
    tge=t/100%10;
    txs1=t/10%10;
    txs2=t%10;
write1602_comd(0xc0+10);
write1602_data(tshi+0x30);

write1602_comd(0xc0+11);
write1602_data(tge+0x30);

write1602_comd(0xc0+12);
write1602_data('.');

write1602_comd(0xc0+13);
write1602_data(txs1+0x30);

write1602_comd(0xc0+14);
write1602_data(txs2+0x30);

write1602_comd(0xc0+15);
write1602_data('C');

}

void Init_DS18B20()   //初始化ds1820
{
unsigned char x=0;
DQ = 1;          //DQ复位
tmpDelay(8);     //稍做延时
DQ = 0;          //单片机将DQ拉低
tmpDelay(80);    //精确延时 大于 480us
DQ = 1;          //拉高总线
tmpDelay(14);
x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
tmpDelay(20);
}

unsigned char ReadOneChar()//读一个字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
   DQ = 0;            // 给脉冲信号
   dat>>=1;
   DQ = 1;            // 给脉冲信号
   if(DQ)
   dat|=0x80;
   tmpDelay(4);
}
return(dat);
}

void WriteOneChar(unsigned char dat)//写一个字节
{
unsigned char i=0;
for (i=8; i>0; i--)
{
   DQ = 0;
   DQ = dat&0x01;
   tmpDelay(5);
   DQ = 1;
   dat>>=1;
}
}

unsigned int Readtemp()      //读取温度
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
double ty=0;

float tt=0; 
Init_DS18B20();
WriteOneChar(0xCC);     // 跳过读序号列号的操作
WriteOneChar(0x44);     // 启动温度转换
         
Init_DS18B20();
WriteOneChar(0xCC);     //跳过读序号列号的操作
WriteOneChar(0xBE);     //读取温度寄存器

a=ReadOneChar();       //连续读两个字节数据    读低8位 
b=ReadOneChar();                          //读高8位

t=b;
t<<=8;
t=t|a;                //两字节合成一个整型变量。
tt=t*0.0625;          //得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
ty= tt*100+0.5;       //放大100倍,这样做的目的将小数点后2位也转换为可显示数字,同时进行一个四舍五入操作。
return(ty);


}
   void tmpDelay(int num)//延时函数
{
while(num--) ;
}

void temp_delay(uchar z)
{
uchar x;
   for(;z>0;z--)
    for(x=10;x>0;x--) ;

}
/******************************温度获取相关的函数——结束********************************************************************/


update_temp()       //显示温度
{
t=Readtemp();
temp_display();
}

void main()

int j=0;
uchar temp;
    if (Read1302(READ_SECOND)>59) Init_DS1302();   //如果时间已停止则设初值,通过检测CH寄存们进行确定,这点很关键。
    init1602_lcd();
   while(1)
   {

      keyscan();
      delay(10);

   if (num==0)        //如果进入时间调校模式则不更新温度?
    {update_temp();    }

    if(flag==0)
        update_time();

   }        
                 
}
 

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • technologist_48
    CSDN专家-Fay 2021-06-03 20:41

    有个函数没有写返回值,贴出完整代码

    点赞 评论

相关推荐