温度检测有几处不明白

2019-07-15 13:35发布

用18B20检测温度,并用显示器显示,但是仿真图出不来,求大神指教
#include <reg51.h>
# define uchar unsigned  char
# define uint unsigned  int
uchar data disdata[7];
uchar temp1,temp2;
  uchar d;
  bit flag;  //正负标志位
  uint temper;  //温度值
sbit DS=P2^4;    //74HC595 单
sbit SH_CP=P2^3;
sbit ST_CP=P2^0;
sbit DS1=P2^7;    //74HC595级联
sbit SH_CP1=P2^6;
sbit ST_CP1=P2^5;
sbit RS=P1^1;    //1602
sbit RW=P1^2;
sbit E=P1^3;
sbit DQ=P1^0;   //18B20
sbit SCL=P1^4;  //AT24C02
sbit SDA=P1^5;  
sbit SID=P1^6;       //12864
sbit SCLK=P1^7;                          //端口定义
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ;  //段选
uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};     //位选
uchar code text[]={'2','0','1','6','.','0','7','.','0','8'}; //日期  2016.07.08
uchar code text1[]={0x5b,0x3f,0x06,0xfd,0x3f,0x87,0x3f,0x7f,}; //数码管日期  2016.07.08
void delay(uint m)         //延时
{
   while(m--);
}
void delay1(uchar c)         //延时
{
    unsigned  char a,b;
for(;c>0;c--)
     for(b=142;b>0;b--)
      for(a=2;a>0;a--);
}
/*********************DS18B20**********************/
init1 (void) /*初始化子程序*/
{
  uchar i=0;
  DQ=1;      //DQ复位
  delay(8);
  DQ=0;      //DQ拉低
  delay(80);    //精确延时大于480us
  DQ=1;      //拉高
  delay(14);
  i=DQ;
  delay(20);
}
uchar read_date1()   /*读数据子程序*/
{
   uchar  i;
   uchar date=0;
   for(i=0;i<8;i++)
   {
      DQ=0;    //给脉冲信号
   date>>=1;
   DQ=1;    //给脉冲信号
   if(DQ)
   date|=0x80;
   delay(4);
   }
      return (date);
}
write_date1(uchar date)    /*写数据子程序*/
{
    uchar  i;
    for(i=0;i<8;i++)
   {
      DQ=0;
   date>>=1;
   DQ=CY;
   delay(5);
   DQ=1;
   }
}
read_temp()        /*读温度并转换温度子程序*/
{
   init1();
   write_date1(0xcc);
   write_date1(0x44);
   delay(10);
   init1();
   write_date1(0xcc);
   write_date1(0xbe);
   temp1=read_temp(); //低位
   temp2=read_temp(); //高位
   temper=temp2;  /*转换温度*/
   temper<<=8;
   temper=temper|temp1;
     if(temper<0x0fff)
     flag=0;
     else
    {
  temper=~temper+1;
  flag=1;
    }
temper=temper*(0.625);//温度值扩大10倍,精确到1位小数
return(temper);
}
                           
/****************AT24C02程序***********************/
void  init2 ()          /*初始化子程序*/
{
   SDA=1;
   delay(20);
   SCL=1;
   delay(20);
}
void start ()   /*开始信号子程序*/
{
   SDA=1;    //SCL在高电平期间,SDA一个下降沿启动总线
   delay(20);
   SCL=1;
   delay(20);
   SDA=0;
   delay(20);
}
void respons ()    /*应答信号子程序*/
{
    uchar j;
SCL=1;
    delay(20);
while ((SDA=1)&&(j<255))    //一段时间无应答,则不再等待
j++;
SCL=0;
   delay(20);
}
void stop ()    /*停止信号子程序*/
{
   SDA=0;    //SCL在高电平期间,SDA一个上升沿停止  总线
   delay(20);
   SCL=1;
   delay(20);
   SDA=1;
   delay(20);
}
void write_date2(uchar date)    /*写数据子程序*/
{          //串行发送一个字节,先传最高位
  uchar n,temp;
  temp=date;
  for(n=0;n<8;n++)
  {
   temp=temp<<1;    //左移一位,最高位移入PSW寄存器的CY位
   SCL=0;
   delay(20);
   SDA=CY;
   delay(20);
   SCL=1;
   delay(20);  
  }
   SCL=0;
   delay(20);
   SDA=1;
   delay(20);
}
uchar read_date2()    /*读数据子程序*/
{       //串行接收一个字节,先接收最高位
   uchar n,k;
   SCL=0;
   delay(20);
   SDA=1;
   delay(20);
   for(n=0;n<8;n++)
   {
      SCL=1;
   delay(20);
   k=(k<<1)|SDA;
   SCL=0;
      delay(20);
   }
    return k;   //变量k中保存着接收的8位串行数据
}
void write_add(char address,char date)    /*写地址子程序*/
{
   start();
   write_date2(0xa0);
   respons ();
   write_date2(address);
   respons ();
   write_date2(date);
   respons ();
   stop();
}
uchar read_add(char address) /*读地址子程序*/
{
   char byte;  
   start();
   write_date2(0xa0);
   respons ();
   write_date2(address);
   respons ();
   start();
   write_date2(0xa1);
   respons ();
   byte=read_date2();
   stop();
   return byte;
}
void  temp_save ()   //温度存入24c02
{
   init2();
   write_add(2,temper);
}
/****************1602程序***********************/
void write_595(unsigned char Data)
{
SH_CP=0;
ST_CP=1;
for (d=0;d<8;d++)
{
  Data=Data<<1;
  DS=CY;
  SH_CP=1;
  delay1(5);
  SH_CP=0;
}
ST_CP=0;
delay1(5);
ST_CP=1;
delay1(5);
ST_CP=0 ;
}
void write_com3(unsigned char com)/*写命令子程序*/
{
RS=0;
RW=0;
write_595(com);
delay1(5);
E=1;
delay1(5);
E=0;
}
void write_date3(unsigned char date)/*写数据子程序*/
{
RS=1;
RW=0;
write_595(date);
delay1(5);
     E=1;
     delay1(5);
     E=0;
}
void init3 ()            /*初始化子程序*/
{
E=0;
delay1(15);                //延时较长,可跳过检查忙碌
write_com3(0x38);delay1(5);   //显示模式设置
write_com3(0x0c);delay1(5);   //开显示 光标不闪烁
write_com3(0x01);delay1(5);   //清屏显示
write_com3(0x06);delay1(5);   //光标加1
write_com3(0x80);delay1(5);   //字符显示首地址
}
void lcd_display(unsigned char *p)//显示
{
while(*p!='')
{
  write_date3(*p);
  p++;
  delay1(1);
}
}
void disp()//温度值显示
{  
  uchar flagdat;
     disdata[0]=temper/1000+0x30;//百位数
     disdata[1]=temper%1000/100+0x30;//十位数
     disdata[2]=temper%100/10+0x30;//个位数
     disdata[3]=temper%10+0x30;//小数位
     if(flag==0)
     flagdat=0x20;//正温度不显示符号
     else
        flagdat=0x2d;//负温度显示负号:-
     if(disdata[0]==0x30)
     {
  disdata[0]=0x20;//如果百位为0,不显示
      if(disdata[1]==0x30)
      {
   disdata[1]=0x20;//如果百位为0,十位为0也不显示
      }
     }
     write_com3(0xc0);
     write_date3(flagdat);//显示符号
     write_com3(0xc1);
     write_date3(disdata[0]);//显示百位
     write_com3(0xc2);
     write_date3(disdata[1]);//显示十位
     write_com3(0xc3);
     write_date3(disdata[2]);//显示个位
     write_com3(0xc4);
     write_date3(0x2e);//显示小数点
     write_com3(0xc5);
     write_date3(disdata[3]);//显示小数位
}
void disp1()   //1602管显示日期
{
uchar g;
for(g=0;g<10;g++)   
  {
     write_date3(text[g]);
  delay(20);
  }
  }         
/****************12864程序***********************/
void w_date4(unsigned char date)   /*发送一个字节*/
{
   unsigned char e;
   for(e=0;e<8;e++)
   {
       SID=date&0x80; //取出最高位      
    SCLK=1;      
    SCLK=0;      
    date<<=1; //左移   
   }
}
void write_cd(bit start,uchar onedata) /*写指令或数据子程序*/
{
  uchar start_data,Hdata,Ldata;
  if(start==0)
    start_data=0xf8;  //0:写指令
  else      
    start_data=0xfa;  //1:写数据
  
  Hdata=onedata&0xf0;    //取高四位
  Ldata=(onedata<<4)&0xf0;  //取低四位
  w_date4(start_data);   //发送起始信号
  delay1(1); //延时是必须的
  w_date4(Hdata);       //发送高四位
  delay1(1);  //延时是必须的
w_date4(Ldata);    //发送低四位
  delay1(1);  //延时是必须的
}
void init4()  /*LCD字库初始化程序*/
{
    delay1(10);  //启动等待,等LCD讲入工作状态
write_cd(0,0x30);  //8 位介面,基本指令集
    write_cd(0,0x0c);  //显示打开,光标关,反白关
    write_cd(0,0x01);  //清屏,将DDRAM的地址计数器归零
    delay1(10);
}
void Lcd_pos(uchar x,y)  /* 设定显示位置 */
{
uchar pos;
if(x==1)
  {x=0x80;}
else if(x==2)
  {x=0x90;}
else if(x==3)
  {x=0x88;}
else if(x==4)
  {x=0x98;}
else
  {x=0x80;}
pos=x+y-1;
write_cd(0,pos);  // 设置RAM地址
}
/* 在液晶上显示字符串,输入横纵坐标,和字符串名即可 */
void   lcd_mesg(uchar x,uchar y,uchar *str)  /*显示函数*/
{
  Lcd_pos(x,y);
while(*str!='')
{
   write_cd(1,*str++);
}
}
void display_temp()     /*温度显示函数*/
{
temper=read_temp();
disdata[0]=temper/1000+0x30;  //将温度值存放在数组中 ,
disdata[1]=(temper%1000)/100+0x30;
disdata[2]=(temper%100)/10+0x30;

write_cd(0,0x88+4);  //第三行第5位开始显示
write_cd(1,disdata[0]);  //显示温度值
write_cd(1,disdata[1]);
write_cd(1,'.');   //显示小数点
write_cd(1,disdata[2]);   
}
void disp2()    //12864显示日期
{
  uchar h;
  for(h=0;h<10;h++)   
  {
     write_cd(text[h]);
  delay(20);
  }
}
/****************数码管显示程序***********************/
void write2_595(unsigned char Data)    //595级联
{
SH_CP1=0;
ST_CP1=1;
for (d=0;d<8;d++)
{
  Data=Data<<1;
  DS1=CY;
  SH_CP1=1;
  delay1(5);
  SH_CP1=0;
}
ST_CP1=0;
delay1(5);
ST_CP1=1;
delay1(5);
ST_CP1=0 ;
}
void display(unsigned int temp)    //温度显示子函数
{
     uchar  i;
  temper=read_temp();
  disdata[0]=temper/10000;
     disdata[1]=temper%10000/1000;
     disdata[2]=temper%1000/100;
     disdata[3]=temper%100/10;
  disdata[4]=temper%10;
     disdata[5]=12;
  for(i=0;i<6;i++)
  {
  if(i==2)
  {
     write2_595(table1[d]);   //先传位码
     write2_595(table[disdata[i]]|0x80);   //后传段码
  }
else
   {
       write2_595(table1[d]);   //先传位码
     write2_595(table[disdata[i]]);   //后传段码
   }
  delay (100) ;
  }
}
void disp3()  //数码管显示日期
{
  uchar l;
  for(l=0;l<10;l++)   
  {
     write2_595(table1[d]);   //先传位码
     write2_595(text1[l]);  //后传段码
  }
}
/****************外部中断程序***********************/
void int0() interrupt 0   //外部中断0子程序
{
  EX0=0;
  delay1(20);
  EX0=1;
  delay1(20);
  disp(); //1602温度显示
  display_temp(); //12864温度显示
  display();      //数码管温度显示                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
}
void int1() interrupt 2   //外部中断1子程序
{
  EX1=0;
  delay1(20);
  EX1=1;
  delay1(20);
  disp1();      //1602显示日期
  disp2();  //12864显示日期
  disp3();  //数码管显示日期
}
/****************主程序***********************/
void mian ()
{
   EA=1;  //打开总中断
   EX0=1; //打开外部中断0
   IT0=1; //设置为下降沿触发
   EX1=1; //打开外部中断1
   IT1=1; //设置为下降沿触发
   while(1);
}


这个是仿真图 这个是仿真图
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。