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

📄 ds18b20.c

📁 基于ATMEL AT89S52与DALLS 18B20的应用程序
💻 C
字号:
#include <reg52.h>
#include <intrins.h>
#define jmp_rom 0xcc
#define tmp_start 0x44
#define tmp_ram_read 0xbe
#define nop _nop_()
#define BUSY 0x80 
#define WRITE_DATA 0xff 
#define delay_data 0xff 
#define COMMAND 0x00 
#define LCD_CLEAR 0x01 
#define portdata P3 

unsigned char data ds18b20_read_data[9];
unsigned char code write_ds1302_data[3]={0x12,0x00,0x00};
unsigned char data read_ds1302_data[3];

bit zheng_fu_hao;
sbit data_pin = P1^1;
sbit RS = P2^2;
sbit RW = P2^1;
sbit E = P2^0;
sbit CK=P1^5; 
sbit IO=P1^6; 
sbit DSRST=P1^7; 
sbit ACC7=ACC^7; 
sbit ACC0=ACC^0;

unsigned char lcd_busy(void) 
{ 
  unsigned char temp; 
   
  portdata = 0xff; 
  RS = 0; 
  RW = 1; 
  E = 1; 
  temp = portdata; 
  E = 0; 
  return (temp); 
} 

void lcd_command_writedata(unsigned char check,unsigned char dispdata) 
{ 
  if (check == COMMAND) 
  { 
   RS = 0; 
   } 
  else 
  { 
   RS = 1; 
  } 
  RW = 0; 
  portdata = dispdata; 
  E = 1; 
  E = 0; 
  while (lcd_busy() & BUSY); 
} 

void lcd_disp(unsigned char address,unsigned char disp_data) 
 { 
  lcd_command_writedata(COMMAND,address);
  lcd_command_writedata(WRITE_DATA,disp_data);
 } 

void lcd_init(void) 
{ 
  lcd_command_writedata(COMMAND,LCD_CLEAR); 
  lcd_command_writedata(COMMAND,0x38); 
  lcd_command_writedata(COMMAND,0x0e); 
  lcd_command_writedata(COMMAND,0x06); 
} 

void ds1302open(void)//打开DS1302 
{ 
  CK=0; 
  DSRST=0; 
  DSRST=1; 
  } 

void ds1302stop(void)//关闭DS1302 
{ 
  DSRST=0; 
  CK=1; 
  } 

void ds1302write(unsigned char putin) 
{ 
  unsigned char i; 
  ACC=putin; 
  for (i=8;i>0;i--) 
  { 
   IO=ACC0; 
   CK=1; 
   CK=0; 
   ACC=ACC>>1; 
   } 
  } 

unsigned char ds1302read (void) 
{ 
  unsigned char i; 
  ACC=0; 
  for (i=8;i>0;i--) 
  { 
   ACC=ACC>>1; 
   ACC7=IO; 
   CK=1; 
   CK=0; 
   } 
  return ACC; 
 } 

void ds1302wt(unsigned char address,unsigned char val) //DS1302写数据 
{ 
  ds1302open(); 
  ds1302write(address); 
  ds1302write(val); 
  ds1302stop(); 
  } 

unsigned char ds1302rt(unsigned char address)//DS1302读数据 
 { 
  unsigned char tempdata; 
  ds1302open(); 
  ds1302write(address); 
  tempdata=ds1302read(); 
  ds1302stop(); 
  return tempdata; 
  } 

void ds1302_write_data(void)
 {
  ds1302wt(0x84,write_ds1302_data[0]);
  ds1302wt(0x82,write_ds1302_data[1]);
  ds1302wt(0x80,write_ds1302_data[2]);
  }

void ds1302_read_data(void)
 {
  read_ds1302_data[0] = ds1302rt(0x85);
  read_ds1302_data[1] = ds1302rt(0x83);
  read_ds1302_data[2] = ds1302rt(0x81);
  }

void ds18b20_delay(unsigned char delay_time)  /*计数一次6us,再加上函数调用和返回所花费的14us时间*/
 {
   while (delay_time--);
 }

void delay_ms(unsigned int ms_delay_time) /*计数一次大约1ms*/
 {
  unsigned char i;

   while (ms_delay_time--)
      {
        for (i = 0; i < 120; i ++)
           {
            }
       }
  }

bit ds18b20_rst(void)
 { 
   bit ack = 1;
   unsigned char loop_time = 10;

   while ((loop_time --) && ack)
    {
     ds18b20_delay(10);
     data_pin = 1;
     nop;
     nop;
     data_pin = 0;
     ds18b20_delay(100);
     data_pin = 1;
     ds18b20_delay(10);
	 ack = data_pin;
	 ds18b20_delay(70);
	 }
	return (ack);
  }


bit ds18b20_read_bit(void)
 {
  bit read_bit;

   data_pin = 0;
   nop;
   nop;
   data_pin = 1;
   nop;
   nop;
   nop;
   nop;
   nop;
   nop;
   nop;
   nop;
   read_bit = data_pin;
   ds18b20_delay(7);
   return (read_bit);
  }

unsigned char ds18b20_read_byte(void)
 {
   unsigned char i;
   unsigned char read_temp = 0;

   for (i = 8; i > 0; i --)
     {
	  if(ds18b20_read_bit())
	   {
	    read_temp = read_temp >> 1;
		read_temp = read_temp | 0x80;
	    }
	  else
	    {
		read_temp = read_temp >> 1;
		 }
	   }
	 return (read_temp);
  }


void ds18b20_write_bit(bit write_data)
 {
   if (write_data)
     { 
	   data_pin = 0;
	   nop;
	   nop;
	   data_pin = 1;
	   ds18b20_delay(10);
       }
	else 
	 {
	   data_pin = 0;
	   ds18b20_delay(10);
	 }
   data_pin = 1;
   nop;
   nop;
  }

void ds18b20_write_byte(unsigned char send_data)
 {
   unsigned char i;
    
   for (i = 0; i < 8; i ++)
    {
	 ds18b20_write_bit((bit)((send_data >> i) & 0x01));
	}
  }

unsigned int ds18b20_read_temperature(void)
 {
  unsigned char i;
  unsigned int temperature;

  zheng_fu_hao = 0;
  if (!ds18b20_rst())
   {
     ds18b20_write_byte(jmp_rom);
	 ds18b20_write_byte(tmp_start);
    }
   delay_ms(1);
   if (!ds18b20_rst())
   {
     ds18b20_write_byte(jmp_rom);
	 ds18b20_write_byte(tmp_ram_read);
	  for (i = 0; i < 9; i ++)
	   {
	    ds18b20_read_data[i] = ds18b20_read_byte();
	   }
	}
   temperature = (ds18b20_read_data[1] << 8) + ds18b20_read_data[0];
   if ((ds18b20_read_data[1] & 0xf8) == 0xf8)
     {
	  temperature = ~ temperature + 1;
	  zheng_fu_hao = 1;
	  }
   return (temperature);
  }

void disp_data(void)
 {
    unsigned long temperature_temp;
    unsigned int tem_get;
    unsigned char a,b,c,d;

    tem_get = ds18b20_read_temperature();
    temperature_temp =(unsigned long)((float)(tem_get)*(float)(0.0625)); /*温度计算*/
	lcd_command_writedata(COMMAND,LCD_CLEAR);
	if (!zheng_fu_hao)     /*判断温度正负值,判是否要显示负号*/
	  {
	    lcd_disp(0x83,0xfe);
	   }
	else 
	  {
	   lcd_disp(0x83,0x2d);
	   } 
  
    a = temperature_temp / 100;  /*温度百位显示,为0时不显示*/
	if (a == 0x00)
	  {
	    lcd_disp(0x84,0xfe);
	    }
	else
	  {
       lcd_disp(0x84,a + 0x30);
	    }

    b = temperature_temp / 10 % 10; /*温度十位显示,当百位和十位同时为0时不显示*/
	if (a == 0x00 && b == 0x00)
	  {
	    lcd_disp(0x85,0xfe);
	    }
	else
	  {
       lcd_disp(0x85,b + 0x30);
	    }
	c = temperature_temp % 100 % 10;/*温度个位显示,无论其值为何值必须显示*/
    lcd_disp(0x86,c + 0x30);
	lcd_disp(0x87,0x2e);

	d = temperature_temp - a * 100 - b * 10 - c; /*温度小数位显示*/
	lcd_disp(0x88,d + 0x30); /*时钟显示*/
	lcd_disp(0x89,0xdf);
	lcd_disp(0x8a,0x43);
    ds1302_read_data();
	lcd_disp(0xc4,(read_ds1302_data[0] >> 4 & 0x0f) + 0x30);
	lcd_disp(0xc5,(read_ds1302_data[0]  & 0x0f) + 0x30);
    lcd_disp(0xc6,0x3a);
	lcd_disp(0xc7,(read_ds1302_data[1] >> 4 & 0x0f) + 0x30);
	lcd_disp(0xc8,(read_ds1302_data[1]  & 0x0f) + 0x30);
    lcd_disp(0xc9,0x3a);
	lcd_disp(0xca,(read_ds1302_data[2] >> 4 & 0x0f) + 0x30);
	lcd_disp(0xcb,(read_ds1302_data[2]  & 0x0f) + 0x30);
	lcd_disp(0xcf,0xfe);
  }
void main(void)
 {
  delay_ms(10);
  lcd_init();
  ds1302_write_data();
  while (1)
  {
   disp_data();
   }
 }

⌨️ 快捷键说明

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