您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子元器件>傳感器>

C 程序如下: - ds18b20應(yīng)用程序?qū)嵗治?/h1>
2017年11月23日 16:08 網(wǎng)絡(luò)整理 作者: 用戶評(píng)論(0

  C 程序如下:

  由于本例僅保存一位小數(shù),溫度小數(shù)位對(duì)照表 df_Table[]將 0000~1111 對(duì)應(yīng)的 16 個(gè)不同的小數(shù)進(jìn)行四舍五入,例如,當(dāng)讀取的溫度低字節(jié)低 4 位為 0101 時(shí),對(duì)應(yīng)的溫度應(yīng)為 2 -2 +2-4 =0.3125≈0.3,因此數(shù)組第 5 個(gè)元素(對(duì)應(yīng) 0101)的值為 3;又如,如果低 4 位為 0110,對(duì)應(yīng)的溫度為 2 -2 +2-3 =0.375≈0.4,因此,數(shù)組第 6 個(gè)元素(對(duì)應(yīng) 0110)取值為 4。

  #include #include

  #define uint unsigned int

  #define uchar unsigned char

  #define delay4us() {_nop_();_nop_();_nop_();_nop_();} //12MHZ 系統(tǒng)頻率下,延時(shí) 4us

  sbit DQ = P3^3;

  sbit LCD_RS = P2^0;

  sbit LCD_RW = P2^1;

  sbit LCD_EN = P2^2;

  uchar code Temp_Disp_Title[]={“Current Temp : ”}; //1602 液晶第一行顯示內(nèi)容

  uchar Current_Temp_Display_Buffer[]={“ TEMP: ”}; //1602 液晶第二行顯示內(nèi)容

  uchar code df_Table[]={ 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 }; //溫度小數(shù)位對(duì)照表

  uchar CurrentT = 0; //當(dāng)前讀取的溫度整數(shù)部分

  uchar Temp_Value[]={0x00,0x00}; //從 DS18B20 讀取的溫度值

  uchar Display_Digit[]={0,0,0,0}; //待顯示的各溫度數(shù)位

  bit DS18B20_IS_OK = 1; //DS18B20 正常標(biāo)志

  void DelayXus(uint x) //延時(shí) 1

  {

  uchar i;

  while(x--)

  {

  for(i=0;i《200;i++);

  }

  }

  bit LCD_Busy_Check() //LCD 忙標(biāo)志,返回值為 1602LCD 的忙標(biāo)志位,為 1 表示忙

  {

  bit result;

  LCD_RS = 0;

  LCD_RW = 1;

  LCD_EN = 1;

  delay4us();

  result = (bit)(P0&0x80);

  LCD_EN=0;

  return result;

  }

  void Write_LCD_Command(uchar cmd) //1602LCD 寫(xiě)指令函數(shù)

  {

  while(LCD_Busy_Check());

  LCD_RS = 0;

  LCD_RW = 0;

  LCD_EN = 0; _

  nop_();

  _nop_();

  P0 = cmd;

  delay4us();

  LCD_EN = 1;

  delay4us();

  LCD_EN = 0;

  }

  void Write_LCD_Data(uchar dat) //1602LCD 寫(xiě)數(shù)據(jù)函數(shù)

  {

  while(LCD_Busy_Check());

  LCD_RS = 1;

  LCD_RW = 0;

  .LCD_EN = 0;

  P0 = dat; delay4us();

  LCD_EN = 1;

  delay4us();

  LCD_EN = 0;

  }

  void LCD_Initialise() //1602LCD 初始化

  {

  Write_LCD_Command(0x01);

  DelayXus(5);

  Write_LCD_Command(0x38);

  DelayXus(5);

  Write_LCD_Command(0x0c);

  DelayXus(5);

  Write_LCD_Command(0x06);

  DelayXus(5);

  {

  void Set_LCD_POS(uchar pos) //1602LCD 設(shè)置顯示位置

  }

  Write_LCD_Command(pos|0x80);

  }

  void Delay(uint x) //延時(shí) 2

  {

  while(x--);

  }

  uchar Init_DS18B20() //初始化(或者說(shuō)復(fù)位)DS18B20

  {

  uchar status;

  DQ = 1;

  Delay(8);

  DQ = 0;

  Delay(90);

  DQ = 1;

  Delay(8);

  status=DQ;

  Delay(100);

  DQ = 1;

  return status;

  }

  uchar ReadOneByte() //從 DS18B20 讀一字節(jié)數(shù)據(jù)

  {

  uchar i,dat=0;

  DQ = 1;

  _nop_();

  for(i=0;i《8;i++)

  {

  DQ = 0;

  dat 》》= 1;

  DQ = 1;

  _nop_();

  _nop_();

  if(DQ)

  dat |= 0X80;

  Delay(30);

  DQ = 1;

  }

  return dat;

  void WriteOneByte(uchar dat) //從 DS18B20 寫(xiě)一字節(jié)數(shù)據(jù)

  {

  uchar i;

  for(i=0;i《8;i++)

  {

  DQ = 0;

  DQ = dat& 0x01;

  Delay(5);

  DQ = 1; dat 》》= 1;

  }

  }

  void Read_Temperature() //從 DS18B20 讀取溫度值

  {

  if(Init_DS18B20()==1) //DS18B20 故障

  DS18B20_IS_OK=0;

  else

  {

  WriteOneByte(0xcc); //跳過(guò)序列號(hào)命令

  WriteOneByte(0x44); //啟動(dòng)溫度轉(zhuǎn)換命令

  Init_DS18B20(); //復(fù)位 DS18B20(每一次讀寫(xiě)之前都要對(duì) DS18B20 進(jìn)行復(fù)位操作)

  WriteOneByte(0xcc); //跳過(guò)序列號(hào)命令

  WriteOneByte(0xbe); //讀取溫度寄存器

  Temp_Value[0] = ReadOneByte(); //讀取溫度低 8 位(先讀低字節(jié),再讀高字節(jié),)

  Temp_Value[1] = ReadOneByte();//讀取溫度高 8 位 (每次只能讀一個(gè)字節(jié)) DS18B20_IS_OK=1; //DS18B20 正常

  }

  }

  void Display_Temperature() //在 1602LCD 上顯示當(dāng)前溫度

  {

  uchar i;

  uchar t = 150, ng = 0; //延時(shí)值與負(fù)數(shù)標(biāo)志

  if((Temp_Value[1]&0xf8)==0xf8) //高字節(jié)高 5 位如果全為 1,則為負(fù)數(shù),為負(fù)數(shù)時(shí)取反

  { //加 1,并設(shè)置負(fù)數(shù)標(biāo)志為 1

  Temp_Value[1] = ~Temp_Value[1];

  Temp_Value[0] = ~Temp_Value[0]+1;

  if(Temp_Value[0]==0x00) //若低字節(jié)進(jìn)位,則高字節(jié)加 1

  Temp_Value[1]++;

  ng = 1; //設(shè)置負(fù)數(shù)標(biāo)志為 1

  }

  Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得到溫度小數(shù)部分

  }

  }

  //獲取溫度整數(shù)部分(低字節(jié)低 4 位清零,高 4 位右移 4 位)+(高字節(jié)高 5 位清零, //低三位左移 4 位)

  CurrentT = ((Temp_Value[0]&0xf0)》》4) | ((Temp_Value[1]&0x07)《《4);

  / //將溫度整數(shù)部分分解為 3 位待顯示數(shù)字

  Display_Digit[3] = CurrentT/100;

  Display_Digit[2] = CurrentT%100/10;

  Display_Digit[1] = CurrentT%10;

  //刷新 LCD 緩沖 //加字符 0 是為了將待數(shù)字轉(zhuǎn)化為字符顯示

  Current_Temp_Display_Buffer[11] = Display_Digit[0] + ‘0’;

  Current_Temp_Display_Buffer[10] = ‘?!?

  Current_Temp_Display_Buffer[9] = Display_Digit[1] + ‘0’;

  Current_Temp_Display_Buffer[8] = Display_Digit[2] + ‘0’;

  Current_Temp_Display_Buffer[7] = Display_Digit[3] + ‘0’;

  if(Display_Digit[3] == 0) //高位為 0 時(shí)不顯示

  Current_Temp_Display_Buffer[7] = ‘ ’;

  if(Display_Digit[2] == 0&&Display_Digit[3]==0) //高位為 0,且次高位為 0,則次高位不顯示

  Current_Temp_Display_Buffer[8] = ‘ ’;

  //負(fù)號(hào)顯示在恰當(dāng)位置

  if(ng)

  {

  if(Current_Temp_Display_Buffer[8] == ‘ ’)

  Current_Temp_Display_Buffer[8] = ‘-’;

  else

  if(Current_Temp_Display_Buffer[7] == ‘ ’)

  Current_Temp_Display_Buffer[7] = ‘-’;

  else

  Current_Temp_Display_Buffer[6] = ‘-’;

  }

  Set_LCD_POS(0x00); //第一行顯示標(biāo)題

  for(i=0;i《16;i++)

  {

  Write_LCD_Data(Temp_Disp_Title[i]);

  }

  Set_LCD_POS(0x40); //第二行顯示當(dāng)前溫度

  for(i=0;i《16;i++)

  {

  Write_LCD_Data(Current_Temp_Display_Buffer[i]);

  }

  //顯示溫度符號(hào)

  Set_LCD_POS(0x4d);

  Write_LCD_Data(0x00);

  Set_LCD_POS(0x4e);

  Write_LCD_Data(‘C’);

  }

  void main() //主函數(shù)

  {

  LCD_Initialise();

  Read_Temperature();

  Delay(50000);

  Delay(50000);

  while(1)

  {

  Read_Temperature();

  if(DS18B20_IS_OK)

  Display_Temperature();

  DelayXus(100);

  }

  }

非常好我支持^.^

(10) 20.4%

不好我反對(duì)

(39) 79.6%

( 發(fā)表人:李倩 )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?