单片机ts18b20测温程序 请大神注释程序 最好每一句都注释明白(小白一只 只有15财富 全送好人)

单片机ts18b20测温程序 请大神注释程序 最好每一句都注释明白(小白一只 只有15财富 全送好人),第1张

/****lcd1602显示温度(使用温度传感器18b20)*****/

#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

/*********液晶屏相关参数**************/

#define data_port P1 //液晶屏指令、数据通信接口

sbit rs=P2^0 //液晶屏寄存器选择接口(rs=0时选择指令寄存器,rs=1时选择数据寄存器)

sbit rw=P2^1 //液晶屏读写选择接口(rw=0时选择写入,rw=1时选择读出)

sbit en=P2^2 //液晶屏使能接口(en=0时通信接口中断,en=1时通信接口接通)

uchar code line1_str[]={" Temperature "}//液晶屏第一行要显示的字符串

uchar code num_tab[]={"0123456789"}

/*********温度传感器18b20相关参数**********/

sbit DQ=P3^5 //温度传感器18b20的数据接口

/**********子函数声明部分************/

void T1_int() //定时器T1初始化子函数声明

void in_command(uchar com) //向液晶屏输入命令子函数声明

void in_data(uchar dat) //向液晶屏输入数据子函数声明

void lcd_disp_string(uchar str[]) //液晶屏显示一串字符子函数声明

void lcd_int() //液晶屏初始化子函数声明

void disp_temperature(uint temp)//lcd1602显示温度子函数声明

bit ds18b20_ret() //温度传感器18b20复位子函数声明

void ds18b20_wr_com(uchar com) //向温度传感器18b20写入命令子函数声明

void rd_ram_command() //发送命令子函数(读取18b20的RAM)

uint ds18b20_rd_data() //读出温度传感器18b20寄存器的相关数据(主要是温度值)子函数声明

void temperature_convert()//18b20温度转换子函数声明

void delayms(uint ms) //毫秒延时子函数声明

void delay_n10_us(uchar n) //微秒延时子函数声明

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

void main()

{

T1_int() //定时器T1初始化

DQ=1 //释放温度传感器18b20的数据接口

temperature_convert() //第一次调用18b20温度转换子函数消除85°C问题

lcd_int() //液晶屏初始化(放在18b20温度转换子函数后边用来延时,跳过85°C)

while(1)

{

temperature_convert() //调用18b20温度转换子函数

rd_ram_command() //发送命令子函数(读取18b20的RAM)

disp_temperature(ds18b20_rd_data())//调用lcd1602显示温度子函数

}

}

/**********定时器T1初始化*************/

void T1_int()

{

TMOD=0x10 //0001 0000 T1工作在定时方式1

TH1=0 //T1设定初值

TL1=0

TR1=0 //暂时关闭T1

}

/**********18b20温度转换子函数*************/

void temperature_convert()

{

while(ds18b20_ret()==0)//温度传感器18b20复位

ds18b20_wr_com(0xcc) //向温度传感器18b20写入"跳跃ROM命令"

ds18b20_wr_com(0x44) //向温度传感器18b20写入"温度转换命令"

delay_n10_us(50) //500us延时,等待转换完成

}

/**********发送命令子函数(读取18b20的RAM)***********/

void rd_ram_command()

{

while(ds18b20_ret()==0)

ds18b20_wr_com(0xcc) //向温度传感器18b20写入"跳跃ROM命令"

ds18b20_wr_com(0xbe) //向温度传感器18b20写入"读RAM命令"

}

/******读出18b20寄存器的相关数据(主要是温度值)子函数******/

uint ds18b20_rd_data()

{

uchar i

uint temp_val

for(i=0i<16i++)

{

temp_val>>=1

DQ=0

_nop_()

DQ=1

_nop_()

_nop_()

if(DQ==1)

{

temp_val|=0x8000

}

delay_n10_us(7) //70us延时,确保读出

}

return(temp_val)

}

/******向温度传感器18b20写入命令子函数声明****/

void ds18b20_wr_com(uchar com)

{

uchar i

for(i=0i<8i++)

{

if((com&0x01)==0)

{

DQ=0

delay_n10_us(7) //70us延时,确保写入0

DQ=1

_nop_()

}

else

{

DQ=0

_nop_()

DQ=1

delay_n10_us(7) //70us延时,确保写入1

}

com>>=1

}

}

/**********温度传感器18b20复位子函数**********/

bit ds18b20_ret()

{

uint temp //暂存脉冲时间

DQ=0 //启动复位脉冲

delay_n10_us(50) //500us延时(大于480us)

DQ=1 //停止复位脉冲

TR1=1 //启动T1

while(DQ==1 &&TH1*256+TL1<=60)//等待18b20回应,等待时间不超过60us

if(DQ==0) //18b20回应

{

temp=TH1*256+TL1

while(TH1*256+TL1-temp<40)//等待60us再次检测回应脉冲是否存在

if(DQ==0) //18b20正常回应

{

while(TH1*256+TL1<=480)//等待正常复位完成

TR1=0 //关闭T1

TH1=0 //计时归零

TL1=0

return(1) //18b20有正常回应返回1

}

else

{

TR1=0 //关闭T1

TH1=0 //计时归零

TL1=0

return(0) //18b20有正常回应返回0

}

}

else

{

TR1=0 //关闭T1

TH1=0 //计时归零

TL1=0

return(0) //18b20没有回应返回0

}

}

/*********lcd1602显示温度子函数声明********/

void disp_temperature(uint temp)

{

uchar temp_h,temp_l,flag=0//温度整数部分,小数部分(二进制)和最高位是否为'0'标志

uint temp_decimal=0 //存储温度值的小数部分(十进制)

in_command(0xc2) //设定第二行字符串起始显示位置

if(temp>=0x8000)

{

in_data('-') //显示'-'号

temp=~temp

temp+=1

}

else

{

in_data(' ') //'+'号不显示

}

temp_h=temp/16

temp_l=temp%16

if(temp_h/100!=0)

{

flag=1

in_data(num_tab[temp_h/100]) //显示温度值的百位

}

else

{

in_data(' ') //百位为'0'则百位不显示

}

temp_h%=100

if(temp_h/10!=0 || flag==1)

{

flag=1

in_data(num_tab[temp_h/10]) //显示温度值的十位

}

else

{

in_data(' ') //百位,十位都为'0'则十位不显示

}

temp_h%=10

in_data(num_tab[temp_h]) //显示温度值的个位

in_data('.') //显示小数点

if(temp_l/8==1)

{temp_decimal+=5000}

temp_l=temp_l%8

if(temp_l/4==1)

{temp_decimal+=2500}

temp_l=temp_l%4

if(temp_l/2==1)

{temp_decimal+=1250}

temp_l=temp_l%2

if(temp_l==1)

{temp_decimal+=625}

in_data(num_tab[temp_decimal/1000])//显示温度值的十分位

in_data(' ')

in_data(223) //显示温度单位标志'摄氏度'

in_data('C')

}

/**********液晶屏初始化子函数**********/

void lcd_int()

{

/***************LCD初始设置*****************/

delayms(15) //延时15MS,等待LCD初始化

in_command(0x01) //清显示屏

in_command(0x38) //8位通信,2行显示,5*7点阵

in_command(0x0c) //开显示,关光标,关闪烁

in_command(0x06) //字符不动,光标右移动,地址加一

/************1602显示上电后电机默认的状态信息**************/

in_command(0x80) //设定第一行字符串起始显示位置

lcd_disp_string(line1_str) //显示数据(字符)

}

/**********液晶屏显示一串字符**********/

void lcd_disp_string(uchar str[])

{

uchar i=0

while(str[i]!='\0')

{

in_data(str[i]) //显示数据(字符)

i++

delayms(50) //延时

}

}

/********向液晶屏输入命令子函数************/

void in_command(uchar com)

{

delayms(2)

en=0//关闭通信,为设置参数做准备

rs=0//选择指令寄存器

rw=0//写入液晶

_nop_()

data_port=com

en=1//开始通信

_nop_()

en=0//关闭通信,为设置参数做准备

}

/********向液晶屏输入数据子函数************/

void in_data(uchar dat)

{

delayms(2)

en=0//关闭通信,为设置参数做准备

rs=1//选择数据寄存器

rw=0//写入液晶

_nop_()

data_port=dat

_nop_()

en=1//开始通信

_nop_()

en=0//关闭通信,为设置参数做准备

}

/********微秒延时子函数************/

void delay_n10_us(uchar n)

{

while(n--)

{

_nop_()

_nop_()

}

}

/********毫秒延时子函数************/

void delayms(uint ms)

{

uchar i

while(ms--)

{

for(i=0i<124i++)

}

}

//按照我的电路图我这是四位有负温度显示你可以看一下。有什么问题可以问我?

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

created: 2010/07/27

created: 27:7:2010   10:27

filename:  D:\Keil Debug\ds18b20.c

file path: D:\Keil Debug

file base: ds18b20

file ext: c

author:  Honguo ZHU

purpose:

//DS18B20的读写程序,数据脚P2.7

//温度传感器18B20汇编程序,采用器件默认的12位转化

//最大转化时间750微秒,显示温度-55到+125度,显示精度

//为0.1度,显示采用4位LED共阳显示测温值

//P0口为段码输入,P34~P37为位选

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

#include "reg51.h"

#include "intrins.h"                            //_nop_()延时函数用

#define  Disdata P0                             //段码输出口

#define  discan  P3                             //扫描口

#define  uchar unsigned char

#define  uint  unsigned int

#define READROM_18b20_CM     0x33

#define MATCHROM_18b20_CM    0x55

#define SKIPROM_18b20_CM     0xCC

#define SEARCHROM_18b20_CM   0xF0

#define ALARMSEARCH_18b20_CM 0xEC

#define CONVERTT_CM          0x44

#define RSCRATCHPAD_CM       0xBE

#define WSCRATCHPAD_CM       0x4E

#define CSCRATCHPAD_CM       0x48

#define RECALLE2_CM          0xB8

#define RPOWERSUNNLY_CM      0xB4

sbit     DQ=P2^7                               //温度输入口

sbit     DIN=P0^7                              //LED小数点控制

//

//

//**************温度小数部分用查表法***********//

uchar code ditab[16]=

{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}

//

uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}

//共阳LED段码表        "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "不亮" "-"

uchar code scan_con[4]={0x8f,0x4f,0x2f,0x1f}    //列扫描控制字

uchar data temp_data[2]={0x00,0x00}             //读出温度暂放

uchar data display[5]={0x00,0x00,0x00,0x00,0x00}     //显示单元数据,共4个数据和一个运算暂用

//

//

//

/*****************11us延时函数*************************/

//

void delay(uint t)

{

for (t>0t--)

}

//

/****************显示函数******************************/

scan()

{

char k

for(k=0k<4k++)                             //4位LED扫描控制

{

Disdata = 0xff                         //

discan=scan_con[k]                     //位选

Disdata=dis_7[display[k]]              //数据显示

if (k==1)

{

DIN=0

}                            //小数点显示

delay(300)

}

}

//

//

/****************DS18B20复位函数************************/

ow_reset(void)

{

char presence=1

while(presence)

{

while(presence)

{

DQ=1_nop_()_nop_()   //从高拉倒低

DQ=0

delay(50)              //550 us

DQ=1

delay(6)               //66 us

presence=DQ            //presence=0 复位成功,继续下一步

}

delay(45)                   //延时500 us

presence=~DQ

}

DQ=1                           //拉高电平

}

//

//

/****************DS18B20写命令函数************************/

//向1-WIRE 总线上写1个字节

void write_byte(uchar val)

{

uchar i

for(i=8i>0i--)

{

DQ=1_nop_()_nop_()                  //从高拉倒低

DQ=0_nop_()_nop_()_nop_()_nop_()  //5 us

DQ=val&0x01                           //最低位移出

delay(6)                              //66 us

val=val/2                             //右移1位

}

DQ=1

delay(1)

}

//

/****************DS18B20读1字节函数************************/

//从总线上取1个字节

uchar read_byte(void)

{

uchar i

uchar value=0

for(i=8i>0i--)

{

DQ=1_nop_()_nop_()

value>>=1

DQ=0_nop_()_nop_()_nop_()_nop_()         //4 us

DQ=1_nop_()_nop_()_nop_()_nop_()         //4 us

if(DQ)

{value|=0x80}

delay(6)                                     //66 us

}

DQ=1

return(value)

}

//

/****************读出温度函数************************/

//

uint read_temp()

{

uint  temp

// ow_reset()                  //总线复位

// delay(200)

//  write_byte(SKIPROM_18b20_CM)       //发命令

// write_byte(CONVERTT_CM)            //发转换命令

ow_reset()

delay(1)

write_byte(SKIPROM_18b20_CM)       //发命令

write_byte(RSCRATCHPAD_CM)

temp_data[0]=read_byte()           //读温度值的第字节

temp_data[1]=read_byte()           //读温度值的高字节

temp=temp_data[1]

temp<<=8

temp=temp|temp_data[0]             // 两字节合成一个整型变量。

return temp                 //返回温度值

}

//

/****************温度数据处理函数************************/

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个

//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩

//下的低字节的低半字节转化成十进制后,就是温度值的小数部分

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

work_temp(uint tem)

{

uchar n=0

if(tem>6348)                        // 温度值正负判断

{

tem=65536-tem

n=1

}            // 负温度求补码,标志位置1

display[4]=tem&0x0f           // 取小数部分的值

display[0]=ditab[display[4]]  // 存入小数部分显示值

display[4]=tem>>4             // 取中间八位,即整数部分的值

display[3]=display[4]/100     // 取百位数据暂存

display[1]=display[4]%100     // 取后两位数据暂存

display[2]=display[1]/10      // 取十位数据暂存

display[1]=display[1]%10

/******************符号位显示判断**************************/

if(!display[3])

{

display[3]=0x0a           //最高位为0时不显示

if(!display[2])

{

display[2]=0x0a        //次高位为0时不显示

}

}

if(n)

{

display[3]=0x0b

}      //负温度时最高位显示"-"

}

//

//

/****************主函数************************/

main()

{

uint   h

Disdata=0xff                             //初始化端口

discan=0xff

for(h=0h<4h++)                       //开机显示"0000"

{display[h]=0}

ow_reset()                               //开机先转换一次

write_byte(SKIPROM_18b20_CM)             //Skip ROM

write_byte(CONVERTT_CM)                  //发转换命令

for(h=0h<100h++)                     //开机显示"0000"

{scan()}

while(1)

{

work_temp(read_temp())     //处理温度数据

scan()                     //显示温度值

}

}

//

//***********************结束**************************//

以下把你的程序中没有翻译的给你补全一下

#define DQ P3_4 //定义DS18B20总线I/O

/*****延时子程序*****/

void Delay_DS18B20(int num)

{

while(num--) //num不等于零继续减1作时延

}

/*****初始化DS18B20*****/

void Init_DS18B20(void)

{

unsigned char x=0 //定义复位成功标志

DQ = 1//DQ复位

Delay_DS18B20(8) //稍做延时

DQ = 0//单片机将DQ拉低

Delay_DS18B20(80) //精确延时,大于480us

DQ = 1//拉高总线

Delay_DS18B20(14) //延时30~60us

x = DQ //稍做延时后,如果x=0则初始化成功,x=1则初始化失败

Delay_DS18B20(20) //延时120us左右

}

/*****读一个字节*****/

unsigned char ReadOneChar(void)

{

unsigned char i=0 //定义for的读数变量

unsigned char dat = 0 //定义数据变量

for (i=8i>0i--)// i 大于0,i减1,i=0时重新把输值i=8

{

DQ = 0// 给脉冲信号

dat>>=1 //数据右移

DQ = 1// 给脉冲信号

if(DQ) //如果DQ=1,

dat|=0x80 //数据或入0x80

Delay_DS18B20(4) //稍作延时

}

return(dat) //返回读到的数据

}

/*****写一个字节*****/

void WriteOneChar(unsigned char dat)

{

unsigned char i=0 //定义for变量

for (i=8i>0i--) //i 大于0,i减1,i=0时重新把输值i=8

{

DQ = 0//DQ输出0

DQ = dat&0x01 输出数据最低位

Delay_DS18B20(5)//稍作延时

DQ = 1 //拉高DQ

dat>>=1//数据右移

}

}

/*****读取温度*****/

unsigned int ReadTemperature(void)

{

unsigned char a=0 //定义温度低位寄存器

unsigned char b=0 //定义温度高位寄存器

unsigned int t=0 //定义整形温度寄存器

float tt=0//定义实形(浮点形)温度寄存器

Init_DS18B20() //调用DS18B20复位程序

WriteOneChar(0xCC)//跳过读序号列号的 *** 作

WriteOneChar(0x44)//启动温度转换

Init_DS18B20()//调用DS18B20复位程序

WriteOneChar(0xCC)//跳过读序号列号的 *** 作

WriteOneChar(0xBE)//读取温度寄存器

a=ReadOneChar()//读低8位

b=ReadOneChar() //读高8位

t=b //高8位温度数据送温度寄存器

t<<=8 //数据左移8位

t=t|a //或入低8位温度数据

tt=t*0.0625//十进制与十六进制数据转换

t= tt*10+0.5//放大10倍输出并四舍五入

return(t) //返回带一位小数的温度值

}

/*****END*****/


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7946981.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存