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

📄 ds18b20._c

📁 基于AVR单片机的DS18B20测温程序.
💻 _C
字号:
// Target : M8
// Crystal: 8.0000Mhz

/*******************************************************************************
*  不可在RESET时做LCD显示,因为DS18B20的复位回应时间只有80us,显示一个字符的时间
   远大于这个值
*
*******************************************************************************/
#include <iom8v.h>
#include <macros.h>

#define LCM_Data  PORTB
#define Busy    0x80

#define  Set_DQ1        DDRC |= 0x08;  PORTC |= 0x08;         //总线拉高
#define  Set_DQ0        DDRC |= 0x08;  PORTC &= 0xf7;         //总线置低
#define  Read_DQ        PINC&0x08                             //读总线
#define  MatchROM       0xcc                                  //匹配ROM
#define  WriteMode      0x4e                                  //写模式
#define  TH             0x64                                  //设置温度上限100
#define  TL             0x8a                                  //设置温度下限-10
#define  MatchTemp      0x7f                                  //写温度匹配寄存器,12bit
#define  ConverTem      0x44                                  //DS18B20温度转换命令
#define  Get_Value      0xbe                                  //读取温度寄存器值
uchar data[5];

void process(long int i,uchar*p)
{
p[0]=i/1000;
i=i%1000;
p[1]=i/100;
i=i%100;
p[2]=i/10;
i=i%10;
p[3]=i;
for(i=0;i<4;i++)
p[i]+=0x30;
p[4]='$'; 
}


void delayms(uint i)
{
 uint j;
 for(;i!=0;i--)
 for(j=0;j<8000;j++)
 ;
}

void delayus(uint i)
{
 for(;i!=0;i--)
 ;
}
 
 
 

void port_init(void)
{
   DDRD  = 0xfe;
   PORTD = 0xff;
   DDRB  = 0xff;
   PORTB = 0xff;
   DDRC  = 0xff;
   PORTC = 0xff;
}


/**********************************************************/ 
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
 //ReadStatusLCM(); //检测忙
 LCM_Data = WDLCM;
 //PORTC=0B00000100;
 //PORTC=0B00000100;
 delayms(1);
 PORTC=0B00000101;
 PORTC=0B00000100;
}

//写指令
void  WriteCommandLCM(unsigned char WCLCM,unsigned char BuysC) //BuysC为0时忽略忙检测

{
 if (BuysC) 
 ;//ReadStatusLCM(); //根据需要检测忙
 LCM_Data = WCLCM;
 delayms(1);
 PORTC=0B00000001;
 delayms(1);
 PORTC=0B00000000;
}

//读数据
unsigned char ReadDataLCM(void)
{
 PORTC=0X00000111;
 return(LCM_Data);
}

//读状态


void LCMInit(void) //LCM初始化
{
/* LCM_Data = 0;
 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
 delayms(5);
 WriteCommandLCM(0x38,0);
 delayms(5);
 WriteCommandLCM(0x38,0);
 delayms(5);
*/
 WriteCommandLCM(0x38,0); //显示模式设置,开始要求每次检测忙信号
 //WriteCommandLCM(0x08,0); //关闭显示
 WriteCommandLCM(0x01,0); //显示清屏
 WriteCommandLCM(0x06,0); // 显示光标移动设置
 WriteCommandLCM(0x0c,0); // 显示开及光标设置
}

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


//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
 if (Y) X += 0x40; //当要显示第二行时地址码+0x40;
 X += 0x80; // 算出指令码
 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
 WriteDataLCM(DData);
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
 unsigned char ListLength;

  ListLength = 0;
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
 while (DData[ListLength]!= '$') //若到达字串尾则退出
  {
   if (X <= 0xF) //X坐标应小于0xF
    {
     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
     ListLength++;
     X++;
    }
  }
}

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


/***************************************************************
*  功能:主机向总线写0                                         *
***************************************************************/
void Writr0(void)
{
   Set_DQ1;
   Set_DQ0;
   delayus(700);
 
   Set_DQ1; 
   asm("nop");
   delayus(15);
}

/***************************************************************
*  功能:主机向总线写1                                         *
***************************************************************/
void Writr1(void)
{
   Set_DQ1;
   Set_DQ0;
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
 asm("nop");
 asm("nop");
 asm("nop");
    asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");

   Set_DQ1;
 delayus(30);

}
 
/***************************************************************
*  功能:向总线写一个字节                                      *
*  输入:需要写的字                                            *
***************************************************************/
void WriteBits(char Byte)
{
   char i = 0;
   for (i=0;i<8;i++)
   {
      if (Byte & 0x01)
	  {
	     Writr1();
	  }
	  else
	  {
	     Writr0();
	  }
	  Byte>>=1;
   }
}

/***************************************************************
*  功能:DS18B20复位程序                                       *
*  返回:总线复位成功,返回1                                   *
***************************************************************/
char Reset1820(void)
{
   static char CheckTimes = 0;
   static char CheckValue = 1;
   delayus(664);
   Set_DQ1;
   Set_DQ0;                                  //拉低总线480us
   delayus(332);
   Set_DQ1;
   DDRC  &= 0xf7;                            //设置端口为输入状态,读取数据
   PORTC |= 0x08;  
   while(PINC&0x08);                         //等待,直至确认复位成功
   CheckValue = Read_DQ; 
   delayus(150);
   return CheckValue;
}

void Init1820(void)
{
 /*  if (Reset1820() == 0x08)
   {
	  DisplayListChar(0,0,"1820 Not Detect $");
	  DisplayListChar(0,1,"                $");
   }
   else
   {
	  DisplayListChar(0,0,"Init DS18B20 OK!$");
	  DisplayListChar(0,1,"                $");
   }	  
 */
	  WriteBits(MatchROM);
	  WriteBits(WriteMode);
	  WriteBits(TH);
	  WriteBits(TL);
	  WriteBits(MatchTemp);
}
  
/***************************************************************
*  功能:从总线中读取数据位                                    *
*  返回:读取值                                                *
***************************************************************/
char ReadBit(void)
{
   char i = 0;
   char Read_Value = 0;
   Set_DQ1;
   Set_DQ0;
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");
   asm("nop");

   Set_DQ1;
   
   DDRC  &= 0xf7;              //设置端口为输入状态,读取数据
   PORTC |= 0x08;

   Read_Value = Read_DQ;
   asm("nop");
   asm("nop");
   delayus(30);
   return Read_Value;
}


/***************************************************************
*  功能:从总线读取一个字节                                    *
*  返回:读取到的字符                                          *
***************************************************************/
char ReadBits(void)
{
   char i = 0;
   char b = 0;
   char ReadBits_Value = 0;
   for (i=8;i>0;i--)
   {
      ReadBits_Value = ReadBits_Value>>1;
	  b = ReadBit();
	  if(b)
	  {
	     ReadBits_Value = ReadBits_Value|0x80;
	  }
	  
   }
   //DEC_Num_Disp(0,1,ReadBits_Value,5);
   return ReadBits_Value;   
}

/***************************************************************
*  功能:获得温度值                                            *
*  返回:温度值--摄氏温度                                      *
***************************************************************/
void Get_Temperature(void)
{  
   uint i;
   static int TempLow = 0;
   static int TempHi = 0;
   static char Temp2 = 0;
   static long final = 0;
   Reset1820();
   WriteBits(MatchROM);
   WriteBits(ConverTem);
   //for(i=0;i<20;i++)
   //delayus(66);
   
   Reset1820();
   WriteBits(MatchROM);
   WriteBits(Get_Value);
   //for(i=0;i<20;i++)
   delayus(70);
   TempLow = ReadBits();                //温度低位
   delayus(70);
   TempHi = ReadBits();
                                       //温度高位
   

   final = (((TempHi)<<8)|TempLow)*0.0625;


  
   process(final,data);
   DisplayListChar(3,1,data);
}

//call this routine to initialize all peripherals
void init_devices(void)
{
    //stop errant interrupts until set up
    CLI(); //disable all interrupts
    port_init();
    LCMInit(); 				  		      //清屏
    MCUCR = 0x00;
    GICR  = 0x00;
    TIMSK = 0x04; //timer interrupt sources
    SEI(); //re-enable interrupts
    //all peripherals are now initialized
}

void main(void)
{
   uchar i;
   init_devices();
   /*
   delayms(5);
   DisplayListChar(0,0,"Reset after sure$");
   DisplayListChar(0,1,"        C       $");
   Init1820();  
   delayms(10);
   */
   DisplayListChar(0,0,"DS18B20+LCD$");  
   DisplayListChar(0,1,"Made by zhang_he$"); 
   delayms(80);
   DisplayListChar(0,0,"Press the button$");
   while(PIND!=0xfe);		   
   DisplayListChar(0,0," Now Temp:      $");
   DisplayListChar(0,1,"        C       $");

  for(i=0;;i++)
   {
	  Get_Temperature();
   }
	  
}

⌨️ 快捷键说明

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