下载
加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 单片机DS18B20温度计C语言程序

单片机DS18B20温度计C语言程序.doc

单片机DS18B20温度计C语言程序

家玉很好
2017-10-20 0人阅读 举报 0 0 暂无简介

简介:本文档为《单片机DS18B20温度计C语言程序doc》,可适用于工程科技领域

单片机DSB温度计C语言程序单片机DSB温度计C语言程序(::)标签:dsb的c语言程序#include<regh>#include<intrinsh>#include<mathH>要用到取绝对值函数abs()通过DSB测试当前环境温度,并通过数码管显示当前温度值,目前显示范围:~度sbitwela=P^数码管位选sbitdula=P^数码管段选sbitds=P^inttempValueF数码管的编码(共阳极)unsignedcharcodetable={xc,xf,xa,xb,x,x,x,xf,x,x,x,x,xc,xa,x,xe}数码管的编码(共阳极),带小数点unsignedcharcodetableWidthDot={x,x,x,x,x,x,x,x,x,x}延时函数,对于MHz时钟,例i=,则大概延时msvoiddelay(unsignedinti){unsignedintjwhile(i){for(j=j<j)}}初始化DSB让DSB一段相对长时间低电平,然后一段相对非常短时间高电平,即可启动voiddsInit(){对于MHz时钟,unsignedint型的i,作一个i操作的时间大于usunsignedintids=i=拉低约us,符合协议要求的us以上while(i>)ids=产生一个上升沿,进入等待应答状态i=while(i>)i}voiddsWait(){unsignedintiwhile(ds)while(~ds)检测到应答脉冲i=while(i>)i}向DSB读取一位数据读一位,让DSB一小周期低电平,然后两小周期高电平,之后DSB则会输出持续一段时间的一位数据bitreadBit(){unsignedintibitbds=i延时约us,符合协议要求至少保持usds=ii延时约us,符合协议要求的至少延时us以上b=dsi=while(i>)i延时约us,符合读时隙不低于us要求returnb}读取一字节数据,通过调用readBit()来实现unsignedcharreadByte(){unsignedintiunsignedcharj,datdat=for(i=i<i){j=readBit()最先读出的是最低位数据dat=(j<<)|(dat>>)}returndat}向DSB写入一字节数据voidwriteByte(unsignedchardat){unsignedintiunsignedcharjbitbfor(j=j<j){b=datxdat>>=写"",将DQ拉低us后,在us~us内将DQ拉高,即完成写if(b){ds=ii拉低约us,符号要求~us内ds=i=while(i>)i延时约us,符合写时隙不低于us要求}else写"",将DQ拉低us~usds=i=while(i>)i拉低约us,符号要求ds=ii整个写时隙过程已经超过us,这里就不用像写那样,再延时us了}}向DSB发送温度转换命令voidsendChangeCmd(){dsInit()初始化DSB,无论什么命令,首先都要发起初始化dsWait()等待DSB应答delay()延时ms,因为DSB会拉低DQ~us作为应答信号writeByte(xcc)写入跳过序列号命令字SkipRomwriteByte(x)写入温度转换命令字ConvertT}向DSB发送读取数据命令voidsendReadCmd(){dsInit()dsWait()delay()writeByte(xcc)写入跳过序列号命令字SkipRomwriteByte(xbe)写入读取数据令字ReadScratchpad}获取当前温度值intgetTmpValue(){unsignedinttmpvalueintvalue存放温度数值floattunsignedcharlow,highsendReadCmd()连续读取两个字节数据low=readByte()high=readByte()将高低两个字节合成一个整形变量计算机中对于负数是利用补码来表示的若是负值,读取出来的数值是用补码表示的,可直接赋值给int型的valuetmpvalue=hightmpvalue<<=tmpvalue|=lowvalue=tmpvalue使用DSB的默认分辨率位,精确度为度,即读回数据的最低位代表度t=value*将它放大倍,使显示时可显示小数点后两位,并对小数点后第三进行舍入如t=,进行计数后,得到value=,即度如t=,进行计数后,得到value=,即度value=t*(value>:)大于加,小于减returnvalue}unsignedcharconsttimeCount=动态扫描的时间间隔显示当前温度值,精确到小数点后一位若先位选再段选,由于IO口默认输出高电平,所以当先位选会使数码管出现乱码voiddisplay(intv){unsignedcharcountunsignedchardatas={,,,,}unsignedinttmp=abs(v)datas=tmpdatas=tmpdatas=tmpdatas=tmpdatas=tmpif(v<){关位选,去除对上一位的影响P=xffwela=打开锁存,给它一个下降沿量wela=段选P=x显示""号dula=打开锁存,给它一个下降沿量dula=位选P=xfewela=打开锁存,给它一个下降沿量wela=delay(timeCount)}for(count=count!=count){关位选,去除对上一位的影响P=xffwela=打开锁存,给它一个下降沿量wela=段选if(count!=){P=tabledatascount显示数字}else{P=tableWidthDotdatascount显示带小数点数字}dula=打开锁存,给它一个下降沿量dula=位选P=crol(xfd,count)选择第(count)个数码管wela=打开锁存,给它一个下降沿量wela=delay(timeCount)}}voidmain(){unsignedchariwhile(){启动温度转换sendChangeCmd()显示次for(i=i<i){display(tempValue)}tempValue=getTmpValue()}求知若饥虚心若愚回复引用TOPyunyunAndduoduo副镇长#发表于:|只看该作者踩窝窝送礼物问候Ta#include<regh>#defineucharunsignedchar#defineuintunsignedintsbitDQ=P^dsb与单片机连接口sbitRS=P^sbitRW=P^sbitEN=P^unsignedcharcodestr={"temperature:"}unsignedcharcodestr={""}uchardatadisdatauinttvalue温度值uchartflag温度正负标志*************************lcd程序**************************voiddelayms(unsignedintms)延时毫秒(不够精确的){unsignedinti,jfor(i=i<msi)for(j=j<j)}voidwrcom(unsignedcharcom)写指令{delayms()RS=RW=EN=P=comdelayms()EN=delayms()EN=}voidwrdat(unsignedchardat)写数据{delayms()RS=RW=EN=P=datdelayms()EN=delayms()EN=}voidlcdinit()初始化设置{delayms()wrcom(x)delayms()wrcom(x)delayms()wrcom(x)delayms()wrcom(x)delayms()wrcom(xc)delayms()}voiddisplay(unsignedchar*p)显示{while(*p!=''){wrdat(*p)pdelayms()}}initplay()初始化显示{lcdinit()wrcom(x)display(str)wrcom(xc)display(str)}******************************ds程序***************************************voiddelayB(unsignedinti)延时微秒{while(i)}voiddsrst()*ds复位*{unsignedcharx=DQ=DQ复位delayB()延时DQ=DQ拉低delayB()精确延时大于usDQ=拉高delayB()}uchardsrd()*读数据*{unsignedchari=unsignedchardat=for(i=i>i){DQ=给脉冲信号dat>>=DQ=给脉冲信号if(DQ)dat|=xdelayB()}return(dat)}voiddswr(ucharwdata)*写数据*{unsignedchari=for(i=i>i){DQ=DQ=wdataxdelayB()DQ=wdata>>=}}readtemp()*读取温度值并转换*{uchara,bdsrst()dswr(xcc)*跳过读序列号*dswr(x)*启动温度转换*dsrst()dswr(xcc)*跳过读序列号*dswr(xbe)*读取温度*a=dsrd()b=dsrd()tvalue=btvalue<<=tvalue=tvalue|aif(tvalue<xfff)tflag=else{tvalue=~tvaluetflag=}tvalue=tvalue*()温度值扩大倍精确到位小数return(tvalue)}*******************************************************************voiddsdisp()温度值显示{ucharflagdatdisdata=tvaluex百位数disdata=tvaluex十位数disdata=tvaluex个位数disdata=tvaluex小数位if(tflag==)flagdat=x正温度不显示符号elseflagdat=xd负温度显示负号:if(disdata==x){disdata=x如果百位为不显示if(disdata==x){disdata=x如果百位为十位为也不显示}}wrcom(xc)wrdat(flagdat)显示符号位wrcom(xc)wrdat(disdata)显示百位wrcom(xc)wrdat(disdata)显示十位wrcom(xc)wrdat(disdata)显示个位wrcom(xc)wrdat(xe)显示小数点wrcom(xc)wrdat(disdata)显示小数位}********************主程序***********************************voidmain(){initplay()初始化显示while(){readtemp()读取温度dsdisp()显示}}求知若饥虚心若愚回复引用TOPyunyunAndduoduo副镇长#发表于:|只看该作者踩窝窝送礼物问候Ta#include<atxh>用ATC时就用这个头文件#include<regh>用华邦WEB时必须用这个头文件#include<absacch>#include<ctypeh>#include<mathh>#include<stdioh>#include<stringh>#include<DSBh>测温头文件#include<LCDh>液晶显示头文件#include<keyscanh>键盘扫描头文件sbitalarm=P^报警信号sbitDQ=P^定义DQ引脚为Punsignedcharkeyvalue存放键盘扫描值bitupone,downone加和减标志bitalarmupflag,alarmdownflag上限报警和下限报警设置标志bitsettemperflag设置控制标志温度标志bitalarmswitch报警开关unsignedcharusertemper用户标定温度unsignedcharTH=,TL=,RS=xf上限温度,下限,分辨率位,也就是Cunsignedchart,*pt用来存放温度值,测温程序就是通过这个数组与主函数通信的unsignedcharTempBuffer={xb,x,x,x,xe,x,x,x,x,x,x,xb,x,x,x,x,''}显示实时温度,上电时显示SETCunsignedcharTempBuffer={x,x,xa,xb,x,x,x,x,x,xc,xa,xb,x,x,x,x,''}显示温度上下限,上电时显示TH:TL:Cunsignedcharcodedotcode={,,,}***因显示分辨率为,但小数运算比较麻烦,故采用查表的方法*******再将表值分离出十位和个位后送到十分位和百分位*******************************用户设定温度转换为LCD显示数据***************功能:将用户设定温度usertemper,分离出符号位,百、十、个位并将它们转化为ACSII码,送到液晶显示缓冲区******************************************************voidusertemperLCD(unsignedchartemper){if(temper>xf)判断正负,如果为负温,将其转化为其绝对值{TempBuffer=xdxd为""的ASCII码temper=~temper将负数的补码转换成绝对值temper}elseTempBuffer=xbxB为""的ASCII码TempBuffer=temperx分离出temper的百十个位if(TempBuffer==x)TempBuffer=xfe百位数消隐TempBuffer=(temper)x分离出十位TempBuffer=(temper)x分离出个位}***************温度上下限转换为LCD显示数据*************功能:将上下限报警温度,分离出符号位,百、十、个位并将它们转化为ACSII码,送到液晶显示缓冲区******************************************************voidalarmLCD(unsignedcharTH,unsignedcharTL){if(TH>xF)判断正负,如果为负温,将其转化为其绝对值{TempBuffer=xdxd为""的ASCII码TH=~TH将负数的补码转换成绝对值TH}elseTempBuffer=xbxB为""的ASCII码if(TL>xf){TempBuffer=xdxd为""的ASCII码TL=~TL}elseTempBuffer=xbxB为""的ASCII码TempBuffer=THx分离出TH的百十个位if(TempBuffer==x)TempBuffer=xfe百位数消隐TempBuffer=(TH)x分离出十位TempBuffer=(TH)x分离出个位TempBuffer=TLx分离出TL的百十个位if(TempBuffer==x)TempBuffer=xfe百位数消隐TempBuffer=(TL)x分离出十位TempBuffer=(TL)x分离出个位}**********温度转换为LCD显示数据*****************功能:将两个字节的温度值,分离出符号位,整数及小数并将它们转化为ACSII码,送到液晶显示缓冲区************************************************voidtemperLCD(void){unsignedcharx=x,y=xt=*ptptt=*ptif(t>x)判断正负温度{TempBuffer=xdxd为""的ASCII码t=~t*下面几句把负数的补码*t=~t*换算成绝对值*********x=t***********************t=x***********************if(x>)**********************t*********************}elseTempBuffer=xbxfe为变""的ASCII码t<<=将高字节左移位t=tx取出高字节的个有效数字位x=t将t暂存到X,因为取小数部分还要用到它x>>=右移位x=xxf和前面两句就是取出t的高四位t=t|x将高低字节的有效值的整数部分拼成一个字节TempBuffer=txx为变~ASCII码if(TempBuffer==x)TempBuffer=xfe百位数消隐TempBuffer=(t)x分离出十位TempBuffer=(t)x分离出个位t=txc取有效的两位小数t>>=左移两位,以便查表x=ty=dotcodex查表换算成实际的小数TempBuffer=yx分离出十分位TempBuffer=yx分离出百分位}*********键盘命令处理函数*************功能:把键盘值转化成相应的功能标志位*备注:为了提高程序的健壮性,在功能标志位无效时,**upone和downone都无效,并且各功能标志之间**采用互锁处理,虽然这样麻烦,特别是功能标志较多时**更是麻烦,但各功能标志之间是同级别的**也可采用多重ifelse方法,虽然简单,**但各功能标志之间有了明显的优先级差别**************************************voidkeycommand(unsignedcharx){switch(x){case:upone=breakcase:downone=breakcase:alarmupflag=!alarmupflagbreakcase:alarmdownflag=!alarmdownflagbreakcase:settemperflag=!settemperflagbreakcase:alarmswitch=!alarmswitchbreakdefault:break}if(!(alarmupflag||alarmdownflag||settemperflag)){upone=x在没有相应功能标志有效时downone=xupone和downone都被锁定}if(alarmupflag(!alarmdownflag)(!settemperflag))设置上限报警{if(upone)上限报警加{THupone=if(TH>=)超过度,回零到度TH=}if(downone)上限报警减{THdownone=if(TH<=)小于度,回零到度TH=}}if((!alarmupflag)(alarmdownflag)(!settemperflag))设置下限报警{if(upone){TLupone=if(TL>=)高于度,回零到度TL=}if(downone){TLdownone=if(TL<=)低于度,回零到度TL=}}if((!alarmupflag)(!alarmdownflag)(settemperflag))设置用户标定温度{if(upone){usertemperupone=if(usertemper>=)高于度,回零到度usertemper=}if(downone){usertemperdownone=if(usertemper<=)低于度,回零到度usertemper=}}if(alarmswitch)}main(){setdsb(TH,TL,RS)设置上下限报警温度和分辨率delay()while(){pt=ReadTemperature()测温函数返回这个数组的头地址读取温度,温度值存放在一个两个字节的数组中,temperLCD()实测温度转化为ACSII码,并送液晶显示缓冲区usertemperLCD(usertemper)用户设定温度转化为ACSII码,并送液晶显示缓冲区alarmLCD(TH,TL)上下限报警温度转化为ASCII码,并送液晶显示缓冲区LCDInitial()第一个参数列号,第二个为行号,为表示第一行为表示第二行,第三个参数为显示数据的首地址LCDPrint(,,TempBuffer)LCDPrint(,,TempBuffer)scanfull()看有无键按下if(keyok)如有键按下则看到底哪个键按下{keyvalue=keyscan()调用键盘扫描程序keycommand(keyvalue)键盘命令处理函数}}}

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/27

单片机DS18B20温度计C语言程序

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利