⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zlg7289demo2.c

📁 使用89c51单片机实现单总线多个DS18B20测温
💻 C
字号:
 
#include "ZLG7289.h" 
 

sbit DQ = P1^3;  //定义DS18B20端口DQ  
sbit BEEP=P1^7 ;

unsigned char presence,j ;     //判断是否是器件正确
unsigned char code rom[4][8]={0x28,0x62,0x77,0x39,0x01,0x00,0x00,0xff,
                              0x28,0xbe,0x7e,0x39,0x01,0x00,0x00,0xb5,
                              0x28,0xbb,0xd7,0x5d,0x01,0x00,0x00,0x00,
                              0x28,0x73,0xeb,0x5d,0x01,0x00,0x00,0x9b};          //器件的序列号 (4个)根据具体的器件不同
unsigned char   temp_data[8] = {0x00,0x00};                          //读到的温度值
unsigned int   H_T=250,L_T=190,crru_temp=0,temp=0;                   //设定的最高、最低温度阈值 
unsigned char   key_flag=0,HL_flag=0,mem_flag=1;                     //分别为按键标志、设置中断报警标志、测量温度的模式
unsigned char   display[6] ={0x00,0x00,0x00,0x00,0x00,0x00};         //数码管显示的值 
unsigned char code  ditab[16] =    {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
                                    0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //小数点转换
volatile unsigned char key = 0xFF;                                             //键值
void beep();                                                                   //蜂鸣器响
unsigned char   alarm=0;                                                     //报警标记


void INT0_SVC() interrupt 0                 //中断服务程序
{ 
  key = ZLG7289_Key(); 
  key_flag=1;                               //按键标志
 } 
  
 
 
/* 
函数:Delay() 
功能:延时0.01 655.36s 
参数: 
 t>0时,延时(t*0.01)s 
 t=0时,延时655.36s 
说明: 
  晶振采用11.0592MHz 
*/ 
void Delay(unsigned int t)              
{ 
  do 
 { 
  TH0 = 0xDC; 
  TL0 = 0x00; 
  TR0 = 1; 
   while ( !TF0 ); 
  TF0 = 0; 
  TR0 = 0; 
 } while (--t); 
} 
 
 /**********************************************************/
void Delayb20(unsigned int num)//延时函数
{
  while( --num );
}

/**********************************************************/
 Init_DS18B20(void)//初始化ds1820
{
     EA=0; 
     DQ = 1;      //DQ复位
     Delayb20(8);    //稍做延时

     DQ = 0;      //单片机将DQ拉低
     Delayb20(90);   //精确延时 大于 480us

     DQ = 1;       //拉高总线
     Delayb20(8);

     presence = DQ;    //如果=0则初始化成功 =1则初始化失败
     Delayb20(100);
     DQ = 1; 
     EA=1;
     return(presence); //返回信号,0=presence,1= no presence
}

/**********************************************************/
ReadOneChar(void)//读一个字节
{
unsigned char i = 0;
unsigned char dat = 0;
EA=0;
for (i = 8; i > 0; i--)
  {
    DQ = 0; // 给脉冲信号
    dat >>= 1;
    DQ = 1; // 给脉冲信号

    if(DQ)
     dat |= 0x80;
    Delayb20(4);
  }
EA=1;
    return (dat);
}

/**********************************************************/
WriteOneChar(unsigned char dat)//写一个字节
{
  unsigned char i = 0;
  EA=0;
  for (i = 8; i > 0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
    Delayb20(5);

    DQ = 1;
    dat>>=1;
  }
  EA=1;
}
/*********************************************************/
Read_Romnum(void)      //读器件的系列号
{
   unsigned char i = 0;
   Init_DS18B20();
   if(presence==1)        
    { beep();alarm=1;}      //DS18B20不正常,蜂鸣器报警
    else
    {
      WriteOneChar(0x33);  // 跳过读序号列号的操作
    //  for(i=0;i<8;i++)
	//   rom[j][i]=ReadOneChar();        
    }
}

/*********************************************************/

Read_Temperature()//读取温度
{
    unsigned char i = 0,j=0,num=0;
    
    Init_DS18B20();
    if(presence==1)        
      { beep();alarm=1;}      //DS18B20不正常,蜂鸣器报警
    else 
     {
       WriteOneChar(0xCC);    // 跳过读序号列号的操作
       WriteOneChar(0x44);    // 启动温度转换
     }  
     
     
    for(num=0;num<3;num++)     //读3个器件的温度 
     {
       Init_DS18B20();
       WriteOneChar(0x55);       //匹配序列号的操作
       for(i=0;i<8;i++)          //写入64位序列号  
       {
          WriteOneChar(rom[num][i]); 
        }
       WriteOneChar(0xBE);  //读取温度寄存器

       temp_data[num<<1] = ReadOneChar();   //温度低8位
       temp_data[(num<<1)+1] = ReadOneChar();   //温度高8位 
     }   
     if((mem_flag==1)||(mem_flag==2)||(mem_flag==3))    //判断是单独模式 
       {
         temp_data[6]=temp_data[(mem_flag-1)<<1];
         temp_data[7]=temp_data[((mem_flag-1)<<1)+1];
       }
     else if(mem_flag==4)                               //求平均值模式
       {  
         for(j=0;j<3;j++)     //?这个for应该是不需要的  直接就可以?                    
         {
           display[3]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
           display[2]=((temp_data[2]&0xf0)>>4)|((temp_data[3]&0x0f)<<4);
           display[1]=((temp_data[4]&0xf0)>>4)|((temp_data[5]&0x0f)<<4);
           display[5]=(display[1]+display[2]+display[3])%3;
           temp=(display[1]+display[2]+display[3])/3;
           display[4]=(temp_data[0]&0x0f)+(temp_data[2]&0x0f)+(temp_data[4]&0x0f);
           display[2]=(display[4]+(display[5]<<4))/3;
           display[0]=ditab[display[2]&0x0f]; 
           display[4]=temp+((display[2]&0xf0)>>4);  //这段程序中的display[]只是用来做计算的中间辅助单位 display[0],display[4]后面有用
         } 
       }	   
}

/*********************************************************/
void beep()                       
  {
    unsigned char i;
    for (i=0;i<10;i++)
    {
      Delayb20(60);
      BEEP=!BEEP;                //BEEP取反
    } 
    BEEP=1;                      //关闭蜂鸣器
  }

/*********************************************************/  
Disp_Temperature()     //显示温度
{
  if(alarm)            //报警显示 
  {
    if(alarm==1)        //器件报警  显示EE--
    {
        display[3]=0x0b;
        display[2]=0x0b;
        display[1]=0x0a;
        display[0]=0x0a;
    }
    else if(alarm==2)   //高温报警  显示HE--
    {
        display[3]=0x0c;
        display[2]=0x0b;
        display[1]=0x0a;
        display[0]=0x0a;
    }
    else if(alarm==3)   //低温报警  显示LE--
    {
        display[3]=0x0d;
        display[2]=0x0b;
        display[1]=0x0a;
        display[0]=0x0a;
    }
  }
  else if(key==0xff)     //温度显示 
  {
    if(mem_flag!=4)       //单独模式 
    { 
     display[4]=temp_data[6]&0x0f;
     display[0]=ditab[display[4]];     //查表得小数位的值
     display[4]=((temp_data[6]&0xf0)>>4)|((temp_data[7]&0x0f)<<4);
    }
    display[3]=mem_flag;
    if(mem_flag==4)display[3]=0x0e;    //如果是平均模式 显示P.XXX 
    display[1]=display[4]%100;
    display[2]=display[1]/10;
    display[1]=display[1]%10;
    crru_temp=display[4];
    crru_temp=crru_temp*10+display[0];
    H_T=H_T%1000;
    L_T=L_T%1000;
    if(crru_temp>H_T)alarm=2;        //判断是否产生温度高低阈值报警
    if(crru_temp<L_T)alarm=3;
  }
  else if(HL_flag==1)                //最高温度报警设定值
  {
     display[3]=0x0c;
     display[2]=H_T/100;
     display[1]=H_T/10%10;
     display[0]=H_T%10;  
  }
  else if(HL_flag==2)                //最低温度报警设定值
  {
     display[3]=0x0d;
     display[2]=L_T/100;
     display[1]=L_T/10%10;
     display[0]=L_T%10;  
  }
  else if(key==59)                   //模式选择显示    
  { 
     display[3]=mem_flag;
     if(mem_flag==4)display[3]=0x0e;
     display[2]=0x0a;
     display[1]=0x0a;
     display[0]=0x0a; 
  }
  
  ZLG7289_Download(0,4,0,display[0]); 
  ZLG7289_Download(0,5,1,display[1]); 
  ZLG7289_Download(0,6,0,display[2]); 
  ZLG7289_Download(0,7,1,display[3]); 
}

void initTarg(void)      //初始化目标板
{
	TMOD=0x21;
	TH0=0xDC;
	TL0=0x00;
	IT0=1;
	EA=1;
	EX0=1;
}

void main() 
{ 

   initTarg();
   Delay(30);    //延时300ms,等待ZLG7289复位完毕 
   ZLG7289_Init(20);  //调用ZLG7289的初始化函数 
   Delay(100); 
   //测试 
   ZLG7289_Test(); 
   Delay(200); 
   //复位 
   ZLG7289_Reset(); 
   Delay(100); 
 while(1)
 {
   if(key==0xff)   //读温度
   {
     Read_Temperature();    
   }
   
   Disp_Temperature();  //数码管显示

   if(key_flag)         //按键处理程序
   {
    switch(key)
    {
     case 63:              //设定功能键
            key_flag=1;
            HL_flag ++;
            if(HL_flag==3)HL_flag=1;
            break;
    case 62:              //十位数加1
            if(HL_flag==1) H_T=H_T+100;
            if(HL_flag==2) L_T=L_T+100;
            break;
    case 61:              //个位数加1
            if(HL_flag==1) H_T=H_T+10;
            if(HL_flag==2) L_T=L_T+10;
            break;
    case 60:              //小数位加1
            if(HL_flag==1) H_T=H_T+1;
            if(HL_flag==2) L_T=L_T+1;
            break;           
    case 59:              //说明测得是单个DS18b20温度  还是多个DS18b20的平均值
            key_flag=1;
            mem_flag++;
            if(mem_flag==5)mem_flag=1;
            break;
    case 58:              // 确认键
            key_flag=0;
            HL_flag=0;
            key=0xff;
            break;
    case 57:
            break;
    default:break;
    }
    key_flag=0;
  } 
  
  if(alarm)      //有报警,蜂鸣起响
  {   
    beep();   
  }
  
  Delay(20);     
 } 
  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -