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

📄 ds18b20-shuma-c51.c

📁 利用单片机采集DS18B20的温度
💻 C
字号:
/**********************************************************

                   DS18B20温度采集系统

    通过DD18B20读取温度,数码管显示温度值,并由串口
传送到上位机,上位机显示当前温度,画出温度曲线

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

#include <regx51.h>

#define XTAL 11059200    // CUP	晶振频率
#define baudrate 9600    // 通信波特率

#define uchar unsigned char
#define uint unsigned int

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

unsigned char presence ;

unsigned char code  LEDData[ ]   = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
                                    0x80,0x90,0xff};
unsigned char data  temp_data[2] = {0x00,0x00};
unsigned char data  display[5] =   {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};
void beep(); 
sbit DIN = P0^7; // 小数点
bit  flash=0;    // 显示开关标记

/**********************************************************/
void Delay(unsigned int num)// 延时函数
{
  	while( --num );
}

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

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

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

     presence = DQ;    // 如果=0则初始化成功 =1则初始化失败
     Delay(100);
     DQ = 1; 
     
     return(presence); // 返回信号,0=presence,1= no presence
}
/**********************************************************/
uchar ReadOneChar(void) // 读一个字节
{
	unsigned char i = 0;
	unsigned char dat = 0;

	for (i = 8; i > 0; i--)
  	{
    	DQ = 0; // 给脉冲信号
    	dat >>= 1;
    	DQ = 1; // 给脉冲信号

    	if(DQ)
     	dat |= 0x80;
    	Delay(4);
  	}

    return (dat);
}

/**********************************************************/
void WriteOneChar(unsigned char dat)// 写一个字节
{
  	unsigned char i = 0;

  	for (i = 8; i > 0; i--)
  	{
    	DQ = 0;
    	DQ = dat&0x01;
    	Delay(5);

    	DQ = 1;
    	dat>>=1;
  	}
}

/*********************************************************/
void Read_Temperature(void)// 读取温度
{
  	Init_DS18B20();

  	if(presence==1)        
   	{ 
		beep();
		flash=1;
	}                        // DS18B20不正常,蜂鸣器报警
   	else 
   	{
     	flash=0;
     	WriteOneChar(0xCC);  // 跳过读序号列号的操作
     	WriteOneChar(0x44);  // 启动温度转换

     	Init_DS18B20();
     	WriteOneChar(0xCC);  // 跳过读序号列号的操作
	    WriteOneChar(0xBE);  // 读取温度寄存器

     	temp_data[0] = ReadOneChar();   // 温度低8位
     	temp_data[1] = ReadOneChar();   // 温度高8位 
   	}
}

/*********************************************************/
void Disp_Temperature()// 显示温度
{
  	unsigned char  n=0;

	display[4]=temp_data[0]&0x0f;
	display[0]=ditab[display[4]];     // 查表得小数位的值
	
	display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
	display[3]=display[4]/100;
	display[1]=display[4]%100;
	display[2]=display[1]/10;
	display[1]=display[1]%10;

  	if(!display[3])          // 高位为0,不显示
  	{ 
    	display[3]=0x0a;              
    	if(!display[2])      // 次高位为0,不显示
     	display[2]=0x0a;
  	}

	P0 = 0xc6;    // 显示 C
	P2 = 0x7f;
	Delay(300);
	
	P0 = 0x9c;    // 显示 °  
	P2 = 0xbf;
	Delay(300);
	
	P0 =LEDData[display[0]] ;  // 显示小数位
	P2 = 0xdf;
	Delay(300);
	
	P0 =LEDData[display[1]];  // 显示个位
	DIN = 0;
	P2 = 0xef;
	Delay(300);
	
	P0 =LEDData[display[2]];  // 显示十位
	P2 = 0xf7;
	Delay(300);
	
	P0 =LEDData[display[3]];  // 显示十位
	P2 = 0xfb;
	Delay(300);
	
	P2 = 0xff;                // 关闭显示
}

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

/*********************************************************/
void init(void)
{
	EA  = 1;                           // "中断总允许"

    TMOD = 0x20;			// 定时器1工作于8位自动重载模式, 用于产生波特率

	TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
	TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));   // 定时器0赋初值

	SCON = 0x50;			// 设定串行口工作方式
	PCON &= 0x00;			// 波特率不倍增

	TR1 = 1;				// 启动定时器1
	IE = 0x00;				// 禁止任何中断
}

/*********************************************************/
void send_char(void)
// 传送十六位的温度数据,低位在前
{
	unsigned i=0;

	while (i < 2)
	{
		SBUF = temp_data[i];
		while (!TI);			    	// 等特数据传送
		TI = 0;					        // 清除数据传送标志
		i++;
	}
}

/*********************************************************/
void main(void)
{
	uchar receive;

  	init();

  	while(1)
  	{
    	Read_Temperature();                  // 读取温度

		if (flash==0)             
		{
			Disp_Temperature();              // 显示温度
		}
		else 
		{
			P2 = 0xff ;                      // DS18B20不正常,关闭显示
		}

		if (RI)						         // 是否有数据到来
		{
			RI = 0;
			receive = SBUF;

			if (receive == 's')             // 是否开始采集温度
			{
				send_char();			    // 传送采集的温度
			}
		}
  }
}

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

⌨️ 快捷键说明

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