基于51单片机——读取温度后串口发送数据到PC端

本文介绍了如何在STC89C52RC单片机上通过One-Wire接口与DS18B20温度传感器通信,获取温度数据,并通过串口将读取的温度以浮点数形式发送。同时详细描述了延时函数、设备初始化和串口通信的相关函数。
摘要由CSDN通过智能技术生成

链接:https://pan.baidu.com/s/1mwgnxuXqjq4zym7ewrCTHw 
提取码:yvrv

#include "reg52.h"
#include "onewire.h"
sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t *= 12;
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

float fRead_Temperature(void)
{
	
	unsigned char low,high;
	init_ds18b20();
	Write_DS18B20(0xcc); 		//跳过读取ROM
	Write_DS18B20(0x44); 		//启动温度转换
								//不加上Delay延时,等待温度转换完成,直接去读取暂存器
	init_ds18b20();
	Write_DS18B20(0xcc); 		//跳过读取ROM
	Write_DS18B20(0xbe); 		//获取暂存器数据
	low = Read_DS18B20();		//温度低8位数据
	high = Read_DS18B20();		//温度高8位数据
	
	
	return ((high<<8)|low)/16.0;
}
#include <stc15f2k60s2.h>
#include "Uart.h"
#include "onewire.h"

unsigned char Uart_Slow_Down;//串口减速函数
unsigned char Uart_Recv[10];//串口接收数据存储数组
unsigned char Uart_Recv_Index;//串口接收数组指针
unsigned char Uart_Send[10];//串口发送数组

unsigned char CNCHAR[6] = "摄氏度";


void DelayMs(unsigned int x)   //0.14ms误差 0us
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++)
 {}
 }
}

void Data_Send(float Temperature)
{
	unsigned char datas[6] = {0, 0, 0, 0, 0, 0}; //定义数组
	int i;
	unsigned int temp;
	
	if(Temperature>0)
	{
		temp= (unsigned int)(Temperature*100+0.5);
		datas[0] = temp / 10000;
		datas[1] = temp % 10000 / 1000;
		datas[2] = temp % 1000 / 100;
		datas[3] = temp % 100 / 10;
		datas[4] = temp % 10;
		
		SBUF = '+';
		while (!TI);			         //等待发送数据完成
		TI = 0;
		
		for(i=0;i<5;i++)
		{
			SBUF = '0' + datas[i];  
      while (!TI);  
      TI = 0;  
		}
		// 发送小数点  
    SBUF = '.';  
    while (!TI);  
    TI = 0;  
  
    // 发送小数部分  
    SBUF = '0' + datas[5];  
    while (!TI);  
    TI = 0;  
	
	
	for(i=0; i<sizeof(CNCHAR)&& CNCHAR[i] != '\0'; i++)
	{
	 	SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
		while (!TI);			         //等待发送数据完成
		TI = 0;
	}

		
		SBUF='+';
		while(!TI);//等待发送数据完成
		TI=0;
		
	}
	
	
}


void main()
{
	UartInit();    //初始化串口
	//Uart_SendString("");   //接收字符串
	
  while(1)
  {
		Data_Send(fRead_Temperature());
		DelayMs(1000);//1s钟刷一次
  }
}

void Uart_ISR(void) interrupt 4   //串口接收中断函数
{
	if(RI==1)//接收数据
	{
		Uart_Recv[Uart_Recv_Index] = SBUF;
		Uart_Recv_Index++;
		RI=0;
	}
	
}
#include "Uart.h"
#include <stc15f2k60s2.h>


//串口初始化
void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xC7;		//设定定时初值
	TH1 = 0xFE;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	ES = 1;
	EA = 1;
	TR1 = 1;		//启动定时器1
}




//字节发送函数
void Uart_SendByte(unsigned char byte)   //串口发送单个字节函数
{
	SBUF=byte;
	while(TI==0);//等待数据发送
	TI=0;//将发送标志位清零
}
 
void Uart_SendString(char *str)  //串口发送字符串函数
{
    while(*str!='\0')     //判断字符串截止位则退出
	{
		Uart_SendByte(*str++);  
		
	}
}

DS18B20是单总线数字传感器,共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。 这几个信号的时序如下: 1)复位脉冲和应答脉冲 单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,若为低电平,再延时480us。 2)写时序 写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。 3)读时序 单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。 DS18B20的温度读取过程一般为:复位->发SKIPROM命令(0XCC)->发开始转换命令(0X44)->延时->复位->发送SKIPROM命令(0XCC)->发读存储器命令(0XBE)->连续读出两个字节数据(即温度)->结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值