基于51单片机的知识总结,使用protues和keil共同学习。
我使用的是protues7.8 和 keil4,需要软件的联系我。
源码及protues仿真:https://download.csdn.net/download/sinat_33734313/11857025
DS18B20温度测量
protues电路仿真
仿真元器件
DS18B20
LM016L
仿真电路以及使用软件截图
硬件说明
1. LCD
参照:https://blog.csdn.net/sinat_33734313/article/details/102461590
2. DS18B20
2.1 初始化时序
2.2 读时序
2.3 写时序
程序
/*-------------------------------------------
FileName:main.c
Function: 使用DS18B20测量温度
Description:测量温度;
LCD1602实时显示温度
---------------------------------------------
Author: Ethan Chen
Date: 2019-10-12
-------------------------------------------*/#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "temp.h"
#include "lcd.h"typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;char num=0;
u8 DisplayData[8];/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{while(i--);
}/*******************************************************************************
* 函 数 名 : datapros()
* 函数功能 : 温度读取处理转换函数
* 输 入 : temp
* 输 出 : 无
*******************************************************************************/void datapros(int temp)
{static int LastTemp = 0;float tp; u8 index;index = 0;if(temp < 0) //当温度值为负数{DisplayData[index++] = '-'; // -//因为读取的温度是实际温度的补码,所以减1,再取反求出原码temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*100+0.5; //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。}else{tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量//如果温度是正的那么,那么正数的原码就是补码它本身temp=tp*0.0625*100+0.5; //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。}if( LastTemp == temp ) return;LastTemp = temp;DisplayData[index++] = temp / 10000 + '0';DisplayData[index++] = temp % 10000 / 1000 + '0';DisplayData[index++] = temp % 1000 / 100 + '0';DisplayData[index++] = '.';DisplayData[index++] = temp % 100 / 10 + '0';DisplayData[index++] = temp % 10 + '0';display(DisplayData, index);
}/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{ LcdInit();displayInit();while(1){delay(1000);datapros(Ds18b20ReadTemp()); //数据处理函数}
}
/*-----------------------------
FileName:temp.c
Function: DS18B20
Author: Ethan Chen
Date: 2019-10-12
------------------------------*/#include"temp.h"
/*******************************************************************************
* 函 数 名 : Delay1ms
* 函数功能 : 延时函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Delay1ms(uint y)
{uint x;for( ; y>0; y--){for(x=110; x>0; x--);}
}
/*******************************************************************************
* 函 数 名 : Ds18b20Init
* 函数功能 : 初始化
* 输 入 : 无
* 输 出 : 初始化成功返回1,失败返回0
*******************************************************************************/uchar Ds18b20Init()
{uchar i;DSPORT = 0; //将总线拉低480us~960usi = 100; while(i--);//延时642usDSPORT = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低i = 0;while(DSPORT) //等待DS18B20拉低总线{//Delay1ms(1);i++;if(i>100)//等待>5MS{return 0;//初始化失败}}return 1;//初始化成功
}/*******************************************************************************
* 函 数 名 : Ds18b20WriteByte
* 函数功能 : 向18B20写入一个字节
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Ds18b20WriteByte(uchar dat)
{uint i, j;for(j=0; j<8; j++){DSPORT = 0; //每写入一位数据之前先把总线拉低1usi++;DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始i=7;while(i--); //延时68us,持续时间最少60usDSPORT = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;}
}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadByte
* 函数功能 : 读取一个字节
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/uchar Ds18b20ReadByte()
{uchar byte, bi;uint i, j; for(j=8; j>0; j--){DSPORT = 0;//先将总线拉低1usi++;DSPORT = 1;//然后释放总线i++;i++;//延时6us等待数据稳定bi = DSPORT; //读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte = (byte >> 1) | (bi << 7); i = 4; //读取完之后等待48us再接着读取下一个数while(i--);} return byte;
}
/*******************************************************************************
* 函 数 名 : Ds18b20ChangTemp
* 函数功能 : 让18b20开始转换温度
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Ds18b20ChangTemp()
{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0x44); //温度转换命令//Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadTempCom
* 函数功能 : 发送读取温度命令
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Ds18b20ReadTempCom()
{ Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc); //跳过ROM操作命令Ds18b20WriteByte(0xbe); //发送读取温度命令
}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadTemp
* 函数功能 : 读取温度
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/int Ds18b20ReadTemp()
{static int LastTemp=0;static unsigned char TempTime = 0;int temp = 0;uchar tmh, tml;Ds18b20ChangTemp();Ds18b20ReadTempCom();tml = Ds18b20ReadByte();tmh = Ds18b20ReadByte();temp = tmh;temp <<= 8;temp |= tml;if( LastTemp == temp ){TempTime++;if( TempTime >= 20 ){TempTime = 0;return temp;}}else{LastTemp = temp;TempTime = 0;}return temp;
}
注:
程序运行过程中,仿真提示RAM COMMAND UNSUPPORTED,这是由于读数据太快,以至于DS18B20还没准备好。