51单片机DS18B20温度传感器使用和数码管温度计、LCD1602温度显示代码
温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读中文手册,并且对照代码注释充分分析代码。请不要觉得中文手册内容繁多!如能静心分析,定能深有体会,获益匪浅!
一、DS18B20中文手册(节选)
主函数操作顺序(执行序列)
功能指令
数码管温度计详解代码如下:
-
-
-
-
/*====================================
-
自定义类型名
-
====================================*/
-
typedef unsigned char INT8U;
-
typedef unsigned char uchar;
-
-
typedef unsigned int INT16U;
-
typedef unsigned int uint;
-
-
/*====================================
-
硬件接口位声明
-
====================================*/
-
sbit DS = P2^2; //DS18B20单总线
-
sbit DU = P2^6; //数码管段选
-
sbit WE = P2^7; //数码管位选
-
/*====================================
-
共阴极数码管段选码
-
====================================*/
-
uchar code table[]={
-
//0 1 2 3 4 5 6 7 8
-
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
-
//9 A B C D E F - . 关显示
-
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
-
};
-
-
/*====================================
-
数码管位选码
-
====================================*/
-
//第1位 2位 3位 4位 5位 6位 7位 8位
-
uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
-
-
/*====================================
-
函数:void Delay_Ms(INT16U ms)
-
参数:ms,毫秒延时形参
-
描述:12T 51单片机自适应主时钟毫秒级延时函数
-
====================================*/
-
void Delay_Ms(INT16U ms)
-
{
-
INT16U i;
-
do{
-
i = MAIN_Fosc / 96000;
-
while(--i); //96T per loop
-
}while(--ms);
-
}
-
/*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/
-
void Delay_us(uchar us)
-
{
-
while(us--);
-
}
-
/*====================================
-
函数:void Display(INT16U Value)
-
参数:Value,显示值 取值0-65535
-
描述:共阴极数码管显示函数可显示一个字节的数
-
====================================*/
-
void Display(INT16U Value) //注意由于需要显示的数大于一个字节所有形参需为int型
-
{
-
//------------------------------
-
DU = 0; //关闭段选
-
P0 = table[Value/100]; //数码管显示百位
-
DU = 1; //打开段选
-
DU = 0; //关闭段选
-
-
WE = 0; //关闭位选
-
P0 = T_COM[0]; //第一位数码管
-
WE = 1; //打开位选
-
WE = 0; //关闭位选
-
Delay_Ms(3);
-
//-------------------------------
-
DU = 0;
-
P0 = table[Value%100/10]|0x80; //显示十位
-
DU = 1;
-
DU = 0;
-
-
WE = 0;
-
P0 = T_COM[1]; //第二位数码管
-
WE = 1;
-
WE = 0;
-
Delay_Ms(3);
-
//-------------------------------
-
DU = 0;
-
P0 = table[Value%10]; //显示个位
-
DU = 1;
-
DU = 0;
-
-
WE = 0;
-
P0 = T_COM[2]; //第三位数码管
-
WE = 1;
-
WE = 0;
-
Delay_Ms(3);
-
}
-
/*单总线初始化时序*/
-
/*出始化时序里包含了复位DS18B20和接收DS18B20返回的存在信号*/
-
bit ds_init()
-
{
-
bit i;
-
DS = 1;
-
_nop_();
-
DS = 0;
-
Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
-
DS = 1; //释放总线(检测到上升沿)
-
Delay_us(4); //延时37.95us 等待18B20发回存在信号(存在脉冲)
-
i = DS;
-
Delay_us(20); //141.95us
-
DS = 1;
-
_nop_();
-
return (i); //返回一个存在信号
-
}
-
/*写一个字节*/
-
void write_byte(uchar dat)
-
{
-
uchar i;
-
for(i=0;i<8;i )
-
{
-
DS = 0;
-
_nop_();//产生些时序
-
DS = dat & 0x01; //0000 0001
-
Delay_us(10);//76.95us
-
DS = 1; //释放总线准备下一次数据写入
-
_nop_();
-
dat >>= 1;
-
}
-
}
-
-
uchar read_byte()
-
{
-
uchar i, j, dat;
-
for(i=0;i<8;i )
-
{
-
DS = 0;
-
_nop_();//产生读时序 1us,延时一个指令周期,空指令
-
DS = 1; //释放总线
-
_nop_(); //延时时间可以通过单步调试来计算
-
j = DS;
-
Delay_us(10);//76.95us
-
DS = 1;
-
_nop_();
-
dat = (j<<7)|(dat>>1);
-
}
-
return (dat);
-
}
-
void main()
-
{
-
uint i;
-
uchar L, M;
-
while(1)
-
{
-
ds_init();//初始化DS18B20
-
write_byte(0xcc);//发送跳跃ROM指令
-
write_byte(0x44);//发送温度转换指令
-
ds_init();//初始化DS18B20
-
write_byte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,
-
//忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)
-
write_byte(0xbe);//读取DS18B20暂存器值,读取将从字节0开始,一直进行下去,直到第9字节(字节8,CRC)读完
-
L = read_byte();//总线控制器在发出温度转换指令之后进行读时序
-
M = read_byte();//总线控制器在发出温度转换指令之后进行读时序
-
i = M; //高速暂存器(共8位),详见中文手册
-
i <<= 8; //将最低位移至高位
-
i |= L;
-
i = i * 0.0625 * 10 0.5;
-
Display(i);
-
}
-
}
LCD1602温度显示
-
-
-
-
-
-
-
sbit dula = P2^6;//数码管段选
-
sbit wela = P2^7;//数码管位选
-
sbit rw = P3^6; //LCD1602读/写选择端
-
sbit RS = P3^5;//LCD1602数据/命令选择端
-
-
sbit LCDEN = P3^4; //LCD1602使能端
-
-
void delayUs()
-
{
-
_nop_(); //空指令,延时一个指令周期
-
}
-
-
void delayMs(uint a)
-
{
-
uint i, j;
-
for(i = a; i > 0; i--)
-
for(j = 100; j > 0; j--);
-
}
-
-
-
void writeComm(uchar comm) //写指令
-
{
-
RS = 0;
-
P0 = comm;
-
LCDEN = 1;
-
delayUs();
-
LCDEN = 0;
-
delayMs(1);
-
}
-
-
//写数据:RS=1, RW=0;
-
void writeData(uchar dat)
-
{
-
RS = 1;
-
P0 = dat;
-
LCDEN = 1;
-
delayUs();
-
LCDEN = 0;
-
delayMs(1);
-
}
-
-
-
void init() //LCD1602初始化函数
-
{
-
rw = 0; //LCD1602读/写选择端
-
dula = wela = 0;
-
writeComm(0x38);//LCD1602显示设置
-
writeComm(0x0c);//开显示
-
writeComm(0x06);//当读或写一个字符后地址指针加一,且光标加一
-
writeComm(0x01);//清屏指令
-
}
-
-
void writeString(uchar * str, uchar length)//LCD1602写字符串
-
{
-
uchar i;
-
for(i = 0; i < length; i )
-
{
-
writeData(str[i]);
-
}
-
}
-
-
/**//*****************************DS18B20*******************************/
-
-
/*温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读
-
中文手册,并且对照代码注释充分分析代码。如能静心分析,定能深有体会,获
-
益匪浅!*/
-
sbit ds = P2^2;
-
void dsInit()//初始化,详见中文手册
-
{
-
-
unsigned int i;
-
ds = 0;
-
i = 100;
-
while(i>0) i--; //用于延时(严格按照时序来写)
-
ds = 1;
-
i = 4;
-
while(i>0) i--;
-
}
-
-
void dsWait()//等待信号
-
{
-
unsigned int i;
-
while(ds);
-
while(~ds);
-
i = 4;
-
while(i > 0) i--;
-
}
-
-
-
bit readBit()//读一个bit位,一节数据共8个bit位,故后面会连续读到8次来实现读一个字节的数据
-
{
-
unsigned int i;
-
bit b;
-
ds = 0;
-
i ;
-
ds = 1;
-
i ; i ;
-
b = ds;
-
i = 8;
-
while(i>0) i--;
-
return b;//返回数据
-
}
-
-
unsigned char readByte() //读一个字节的数据
-
{
-
unsigned int i;
-
unsigned char j, dat;
-
dat = 0;
-
for(i=0; i<8; i )//每一次读一位,一节数据共8位,读8次
-
{
-
j = readBit();
-
-
dat = (j << 7) | (dat >> 1);
-
}
-
return dat;
-
}
-
-
-
void writeByte(unsigned char dat)//写一节数据
-
{
-
unsigned int i;
-
unsigned char j;
-
bit b;
-
for(j = 0; j < 8; j )//每次写一位,写8次
-
{
-
b = dat & 0x01;//取最低位,从最低位泄气
-
dat >>= 1; //右移一位
-
if(b)
-
{
-
ds = 0;
-
i ; i ;//延时以产生时序
-
ds = 1;
-
i = 8;
-
while(i>0) i--; //延时以产生时序
-
}
-
else
-
{
-
ds = 0;
-
i = 8;
-
while(i>0) i--;//延时以产生时序
-
ds = 1;
-
i ; i ;//延时以产生时序
-
}
-
}
-
}
-
-
-
void sendChangeCmd()//发送指令
-
{
-
dsInit();
-
dsWait();
-
delayMs(1);
-
writeByte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,
-
//忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)
-
writeByte(0x44);//发送温度转换指令
-
}
-
-
void sendReadCmd()//读操作
-
{
-
dsInit();
-
dsWait();
-
delayMs(1);
-
writeByte(0xcc);//发送跳跃ROM指令
-
writeByte(0xbe);//发送温度转换指令
-
}
-
-
-
int getTmpValue() //获取温度值
-
{
-
unsigned int tmpvalue;
-
int value;
-
float t;
-
unsigned char low, high;
-
sendReadCmd();
-
-
low = readByte();
-
high = readByte();
-
-
tmpvalue = high;
-
tmpvalue <<= 8;
-
tmpvalue |= low;
-
value = tmpvalue;
-
-
t = value * 0.0625;
-
-
value = t * 100 (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
-
return value;
-
}
-
-
void display(int v) //LCD1602显示内容设置
-
{
-
unsigned char count;
-
unsigned char datas[] = {0, 0, 0, 0, 0};
-
unsigned int tmp = abs(v);
-
datas[0] = tmp / 10000;
-
datas[1] = tmp % 10000 / 1000;
-
datas[2] = tmp % 1000 / 100;
-
datas[3] = tmp % 100 / 10;
-
datas[4] = tmp % 10;
-
writeComm(0xc0 3);
-
if(v < 0)
-
{
-
writeString("- ", 2);
-
}
-
else
-
{
-
writeString(" ", 2);
-
}
-
if(datas[0] != 0)
-
{
-
writeData('0' datas[0]);
-
}
-
for(count = 1; count != 5; count )
-
{
-
writeData('0' datas[count]);
-
if(count == 2)
-
{
-
writeData('.');
-
}
-
}
-
}
-
/**//*****************************DS18B20*******************************/
-
-
void main()
-
{
-
uchar table[] = " xianzaiwendu: ";
-
sendChangeCmd();
-
init();
-
writeComm(0x80);
-
writeString(table, 16);//发送" xianzaiwendu: "
-
while(1)
-
{
-
delayMs(1000); //温度转换时间需要750ms以上
-
writeComm(0xc0);
-
display(getTmpValue());//通过LCD1602显示温度转换值
-
sendChangeCmd();//发送转换指令
-
}
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggghhi
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01