找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3163|回复: 1
打印 上一主题 下一主题
收起左侧

我用proteus做的C51显示DS18B20温度仿真一直没有显示,为什么啊?

[复制链接]
跳转到指定楼层
楼主
ID:160384 发表于 2017-1-6 11:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
2黑币

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:160384 发表于 2017-1-6 11:16 | 只看该作者
#include<reg51.h>
#include<intrins.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef char int8;
typedef int int16;
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit BUSY=P0^7;
sbit DQ=P2^4; //温度输入口
sbit EQ=P2^5;
sbit FQ=P2^6;
sbit SET=P3^2;//设置
sbit ADD=P1^1;//加减
sbit SUB=P1^2;//减键
sbit OK=P1^3;//确定键
sbit LED=P1^7;
sbit BEEP=P1^6;
uint8 flag;
int p=30,q=0,k=0;
int data set[4];
uint8 num_temp[]={"0123456789"};
#define nops();  {_nop_(); _nop_(); _nop_(); _nop_();} //定义空指令 4us

void delay(uint16 n)
{
  while (n--);
}
void delay_ms(uint16 m)
{
  uint8 n=120;
  while(m--)
    while(n--);
}
/*
* DQ:18B20复位函数
*/
void DS1802_reset()
{
  uint8 flag=1;
  while(flag)
  {
    while(flag)
    {
      DQ=1;
      delay(1);
      DQ=0;
      delay(50); //550us
      DQ=1;
                while(DQ);
      delay(6); //66us
      flag=DQ;
    }
    delay(45);//延时500us
    flag=~DQ;//500us后总线释放,DQ=1;   
  }
  DQ=1;  
}
/*
* EQ:18B20复位函数
*/
void EQDS1802_reset()
{
  uint8 flag=1;
  while(flag)
  {
    while(flag)
    {
      EQ=1;
      delay(1);
      EQ=0;
      delay(50); //550us
      EQ=1;
      while(EQ);
      delay(6); //66us
      flag=EQ;
    }
    delay(45);//延时500us
    flag=~EQ;//500us后总线释放,DQ=1;   
  }
  EQ=1;  
}
/*
* FQ:18B20复位函数
*/
void FQDS1802_reset()
{
  uint8 flag=1;
  while(flag)
  {
    while(flag)
    {
      FQ=1;
      delay(1);
      FQ=0;
      delay(50); //550us
      FQ=1;
                while(FQ);
      delay(6); //66us
      flag=FQ;
    }
    delay(45);//延时500us
    flag=~FQ;//500us后总线释放,DQ=1;   
  }
  FQ=1;  
}
/*
* 18B20写1个字节函数
* 向1-WIRE总线上写一个字节
*/
void write_byte(uint8 dat)
{
  uint8 i;
  for(i=0;i<8;i++)
  {
    DQ=1;
    _nop_();
    DQ=0;
    nops();
    DQ=dat&0x01;//最低位移出
    delay(6); //66us
    dat>>=1; //右移一位
  }
  DQ=1;
  delay(1);
}
/*EQ: 向1-WIRE总线上写一个字节
*/
void EQwrite_byte(uint8 dat)
{
  uint8 i;
  for(i=0;i<8;i++)
  {
   EQ=1;
    _nop_();
    EQ=0;
    nops();
    EQ=dat&0x01;//最低位移出
    delay(6); //66us
    dat>>=1; //右移一位
  }
EQ=1;
  delay(1);
}
/*FQ: 向1-WIRE总线上写一个字节
*/
void FQwrite_byte(uint8 dat)
{
  uint8 i;
  for(i=0;i<8;i++)
  {
  FQ=1;
    _nop_();
    FQ=0;
    nops();
    FQ=dat&0x01;//最低位移出
    delay(6); //66us
    dat>>=1; //右移一位
  }
FQ=1;
  delay(1);
}
/*
* 18B20读1个字节函数
* 从1-WIRE总线上读取一个字节
*/
uint8 read_byte()
{
  uint8 i,byte=0;
  for(i=0;i<8;i++)
  {
    byte>>=1;
    DQ=1;
    _nop_();
    DQ=0;
    nops();
    DQ=1;
    nops();
    if(DQ==1)  byte|=0x80;
    delay(6);
  }
  DQ=1;
  return byte;
}
/*EQ*/
uint8 EQread_byte()
{
  uint8 i,byte=0;
  for(i=0;i<8;i++)
  {
    byte>>=1;
    EQ=1;
    _nop_();
    EQ=0;
    nops();
    EQ=1;
    nops();
    if(EQ==1)  byte|=0x80;
    delay(6);
  }
  EQ=1;
  return byte;
}
/*FQ*/
uint8 FQread_byte()
{
  uint8 i,byte=0;
  for(i=0;i<8;i++)
  {
    byte>>=1;
   FQ=1;
    _nop_();
    FQ=0;
    nops();
    FQ=1;
    nops();
    if(FQ==1)  byte|=0x80;
    delay(6);
  }
FQ=1;
  return byte;
}
/*
* 启动温度转换
*/
void start_temp_sensor()
{
  DS1802_reset();
  write_byte(0xcc);  // 发Skip ROM命令
  write_byte(0x44); // 发转换命令
}
/**EQ启动温度转换**/
void EQstart_temp_sensor()
{
  EQDS1802_reset();
  EQwrite_byte(0xcc);  // 发Skip ROM命令
  EQwrite_byte(0x44); // 发转换命令
}
/**FQ启动温度转换**/
void FQstart_temp_sensor()
{
  FQDS1802_reset();
  FQwrite_byte(0xcc);  // 发Skip ROM命令
  FQwrite_byte(0x44); // 发转换命令
}
/*
* 读出温度
*/
int16 read_temp()
{
  uint8 temp_data[2]; // 读出温度暂放
  uint16 temp;
  DS1802_reset();   // 复位
  write_byte(0xcc);  // 发Skip ROM命令
  write_byte(0xbe); // 发读命令
  temp_data[0]=read_byte(); //温度低8位
  temp_data[1]=read_byte(); //温度高8位
  temp=temp_data[1];
  temp<<=8;
  temp|=temp_data[0];
  //temp>>=4; //右移四位,相当于除以16(1/16=0.0625)
  return temp;
}
/****EQ读出温度****/
int16 EQread_temp()
{
  uint8 EQtemp_data[2]; // 读出温度暂放
  uint16 EQtemp;
  EQDS1802_reset();   // 复位
  EQwrite_byte(0xcc);  // 发Skip ROM命令
  EQwrite_byte(0xbe); // 发读命令
  EQtemp_data[0]=EQread_byte(); //温度低8位
  EQtemp_data[1]=EQread_byte(); //温度高8位
  EQtemp=EQtemp_data[1];
  EQtemp<<=8;
  EQtemp|=EQtemp_data[0];
  //temp>>=4; //右移四位,相当于除以16(1/16=0.0625)
  return EQtemp;
}
/****FQ读出温度****/
int16 FQread_temp()
{
  uint8 FQtemp_data[2]; // 读出温度暂放
  uint16 FQtemp;
  FQDS1802_reset();   // 复位
  FQwrite_byte(0xcc);  // 发Skip ROM命令
  FQwrite_byte(0xbe); // 发读命令
  FQtemp_data[0]=FQread_byte(); //温度低8位
  FQtemp_data[1]=FQread_byte(); //温度高8位
  FQtemp=FQtemp_data[1];
  FQtemp<<=8;
  FQtemp|=FQtemp_data[0];
  //temp>>=4; //右移四位,相当于除以16(1/16=0.0625)
  return FQtemp;
}
/*
* 读忙状态
*/
void wait()
{
  P0=0xff;
  do
  {
    EN=0;
    RS=0;
    RW=1;
    EN=1;
  }while(BUSY==1);
  EN=0;
}
/*
* 写指令
*/
void write_cmd(uint8 cmd)
{
  wait();
  EN=0;
  P0=cmd;
  RS=0;
  RW=0;
  EN=1;
  EN=0;
}
/*
* 写数据
*/
void write_dat(uint8 dat)
{
  wait();
  EN=0;
  P0=dat;
  RS=1;
  RW=0;
  EN=1;
  EN=0;
}

/*
* 写地址和数据
*/
void write_lcd1602(uint8 addr,uint8 dat)
{
  write_cmd(addr);
  write_dat(dat);
}

/*
* 初始化
*/
void lcd1602_init()
{
  write_cmd(0x38);
  delay_ms(5);
  write_cmd(0x38);
  delay_ms(5);
  write_cmd(0x38);
  delay_ms(5);

  write_cmd(0x0c);
  write_cmd(0x06);
  write_cmd(0x01);

   write_lcd1602(0x80,'A');//标识符固定显示。
   write_lcd1602(0x81,':');
   write_lcd1602(0x88,'B');
   write_lcd1602(0x89,':');
   write_lcd1602(0xC0,'C');
   write_lcd1602(0xC1,':');
}

/**上、下限温度显示函数*/
void Show_ptemp(void)
{
        uint16 pt;

        if(p<0)
        {
                pt=~p+1;
                write_lcd1602(0x82,'-');
         }
        else
        {
                pt=p;
                write_lcd1602(0x82,'+');
        }
        set[0]=pt/10+0x30; //显示上限值
        set[1]=pt%10+0x30;
        write_lcd1602(0x80,'H');
        write_lcd1602(0x81,':');
        write_lcd1602(0x83,set[0]);
        write_lcd1602(0x84,set[1]);
}

void Show_qtemp(void)
{
        uint16 qt;

        if(q<0)
        {
                qt=~q+1;
                write_lcd1602(0xc2,'-');
        }
        else
        {
                qt=q;
                write_lcd1602(0xc2,'+');
        }
               
        set[2]=qt/10+0x30;
        set[3]=qt%10+0x30;
        write_lcd1602(0xc0,'L');
        write_lcd1602(0xc1,':');
        write_lcd1602(0xc3,set[2]);
        write_lcd1602(0xc4,set[3]);//显示下限值

}

  /************报警功能**********/
void alarm(float temp)
{
        int i;

        if(temp>=p)
        {
                LED=1;
                for(i=0;i<3;i++)
                {
                            BEEP=1;
                                delay_ms(1000);
                                BEEP=0;
                                delay_ms(50);
                }
                LED=0; }
        if(temp<=q)
        { BEEP=1;delay_ms(2000);BEEP=0;}
         

}

void show_temp(uint16 temp,uint8 saddr){
        temp=(temp*0.0625)*10+0.5;
      write_lcd1602(saddr,num_temp[(temp%1000)/100]);
      write_lcd1602(saddr+1,num_temp[(temp%100)/10]);
      write_lcd1602(saddr+2,'.');
      write_lcd1602(saddr+3,num_temp[temp%10]);

//        if(1==flag){
                alarm(temp/10);
//        }
//        else{
//                alarm(temp/10);
//        }
}


/*
* 主函数
*/
void main()
{
        uint16 temp;
        uint16 EQtemp;
        uint16 FQtemp;
        lcd1602_init();

        BEEP=0;
        LED=0;
        EA=1;          //全局中断开
          EX0=1;         //外部中断0开
          //EX1=1;         //外部中断1开
          IT0=0;         //边沿触发,为0则为低电平触发
          //IT1=1;         //边沿触发,为0则为低电平触发

  while(1)
  {
   /*按下SET键进入上下限温度调节,SET键同时是调节上下限温度的切换键*/
   
  //  start_temp_sensor();
        temp=read_temp();
   
          if(temp&0x8000) //判定是否为负
          {
             write_lcd1602(0x82,'-');
                 temp=~temp+1;
                // flag=1;
          }
          else{
                  write_lcd1602(0x82,' ');
        //        flag=0;
          }
          show_temp(temp,0x83);
   
   // EQstart_temp_sensor();
    EQtemp=EQread_temp();
   
          
        if(EQtemp&0x8000) //判定是否为负
    {
                EQtemp=~EQtemp+1;
                write_lcd1602(0x8a,'-');
        //        flag=1;
        }
    else
    {
      write_lcd1602(0x8a,' ');
         // flag=0;
    }
        show_temp(EQtemp,0x8b);

//         FQstart_temp_sensor();
    FQtemp=FQread_temp();
    if(FQtemp&0x8000) //判定是否为负
    {
      FQtemp=~FQtemp+1;
      write_lcd1602(0xC2,'-');
         // flag=1;
    }
    else
    {          
      write_lcd1602(0xC2,' ');
         // flag=0;
    }
        show_temp(FQtemp,0xC3);
  }
}

  /***按键***/
void ISR0_Key() interrupt 0
{
        delay_ms(20);//等待系统稳定
        if(!SET){
          write_cmd(0x38);
          delay_ms(5);
          write_cmd(0x0c);
          write_cmd(0x06);
          write_cmd(0x01);
        }
        else{
                   return;
        }

        while(1)
        {
        if(!SET)
        {
                delay_ms(20);
                 if(!SET){
                        if(k==2)
                                k=0;
                        k++;
                }
        }
        ///*调节上限温度
  if(!ADD && k==1)//如果端口电平不为高,说明可能该键已被按下
   {
   delay_ms(20);//延时去抖动
    if(!ADD)//P11仍然不为高,确定该键已被按下
     {
           p++;        //加1
           while(!ADD);//等待按键释放
     }   
   }
  if(!SUB && k==1)//如果端口电平不为高,说明可能该键已被按下
   {
    delay_ms(20);//延时去抖动
    if(!SUB)//P12仍然不为高,确定该键已被按下
     {
           p--;        //减1
           while(!SUB);//等待按键释放
       }
     }

///*调节下限温度
if(!ADD && k==2)//如果端口电平不为高,说明可能该键已被按下
   {
    delay_ms(20);//延时去抖动
    if(!ADD)//P11仍然不为高,确定该键已被按下
     {
                 q++;        //加1
                 while(!ADD);//等待按键释?
     }   
   }
  if(!SUB && k==2)//如果端口电平不为高,说明可能该键已被按下
   {
    delay_ms(20);//延时去抖动
    if(!SUB)//P12仍然不为高,确定该键已被按下
     {                                 
                q--;        //减1
                while(!SUB);//等待按键释?
     }   
   }
   Show_ptemp();
   Show_qtemp();
                if(!OK)
                {                //按下OK键退出调节
                        delay_ms(20);
                        if(!OK)
                        break;
                }
}
        lcd1602_init();
  
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表