求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序

求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序,第1张

不可以;

Get_Tmp() 函数中 a、b 为读18B20 的温度寄存器,然后将 16位结果 赋值到 无符号的 temp 变量上,然后进行温度换算,再放大1000倍,对小数点进行 四舍五入 运算。整个过程不涉及 温度符号(正负) 识别,就直接送往 显示函数 显示。

//安装目录下的EXE文件打开后可在电脑上显示当前温度值

#include <reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P2^2;           //define interface

uint temp;             // variable of temperature

uchar flag1;            // sign of the result positive or negative

sbit dula=P2^6;

sbit wela=P2^7;

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,

0x87,0xff,0xef};

void delay(uint count)      //delay

{

uint i;

while(count)

{

i=200;

while(i>0)

i--;

count--;

}

}

///////功能:串口初始化,波特率9600,方式1///////

void Init_Com(void)

{

TMOD = 0x20;

PCON = 0x00;

SCON = 0x50;

TH1 = 0xFd;

TL1 = 0xFd;

TR1 = 1;

}

void dsreset(void)       //send reset and initialization command

{

uint i;

DS=0;

i=103;

while(i>0)i--;

DS=1;

i=4;

while(i>0)i--;

}

bit tmpreadbit(void)       //read a bit

{

uint i;

bit dat;

DS=0;i++;          //i++ for delay

DS=1;i++;i++;

dat=DS;

i=8;while(i>0)i--;

return (dat);

}

uchar tmpread(void)   //read a byte date

{

uchar i,j,dat;

dat=0;

for(i=1;i<=8;i++)

{

j=tmpreadbit();

dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

return(dat);

}

void tmpwritebyte(uchar dat)   //write a byte to ds18b20

{

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(testb)     //write 1

{

DS=0;

i++;i++;

DS=1;

i=8;while(i>0)i--;

}

else

{

DS=0;       //write 0

i=8;while(i>0)i--;

DS=1;

i++;i++;

}

}

}

void tmpchange(void)  //DS18B20 begin change

{

dsreset();

delay(1);

tmpwritebyte(0xcc);  // address all drivers on bus

tmpwritebyte(0x44);  //  initiates a single temperature conversion

}

uint tmp()               //get the temperature

{

float tt;

uchar a,b;

dsreset();

delay(1);

tmpwritebyte(0xcc);

tmpwritebyte(0xbe);

a=tmpread();

b=tmpread();

temp=b;

temp<<=8;             //two byte  compose a int variable

temp=temp|a;

tt=temp00625;

temp=tt10+05;

return temp;

}

void readrom()          //read the serial

{

uchar sn1,sn2;

dsreset();

delay(1);

tmpwritebyte(0x33);

sn1=tmpread();

sn2=tmpread();

}

void delay10ms()            //delay

{

uchar a,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

void display(uint temp)   //显示程序

{

uchar A1,A2,A2t,A3,ser;

ser=temp/10;

SBUF=ser;

A1=temp/100;

A2t=temp%100;

A2=A2t/10;

A3=A2t%10;

dula=0;

P0=table[A1];  //显示百位

dula=1;

dula=0;

wela=0;

P0=0x7e;

wela=1;

wela=0;

delay(1);

dula=0;

P0=table1[A2];  //显示十位

dula=1;

dula=0;

wela=0;

P0=0x7d;

wela=1;

wela=0;

delay(1);

P0=table[A3];  //显示个位

dula=1;

dula=0;

P0=0x7b;

wela=1;

wela=0;

delay(1);

}

void main()

{

uchar a;

Init_Com();

do

{

tmpchange();

// delay(200);

for(a=10;a>0;a--)

{

display(tmp());

}

}while(1);

}

将二管脚接到P22就可以了

具体的电路图你可以留个邮箱我发给你

我应经发给你了,那个是一个开发板的原理图,外设什么的都有了,你可以参考一下

#include "reg52h"

#include<intrinsh>

#include <mathH> //要用到取绝对值函数abs()

#define uchar unsigned char

#define uint unsigned int

sbit ds=P2^1; //sbit ds=P3^2;//DS18B20

sbit duan=P2^6;

sbit wei=P2^7;

uchar i;

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x00,0x40}; //0x00是用在显示函数中0x40显示“-”(负号)

//

void delay(uchar i)

{

uint j;

while(i--)

{

for(j = 0; j < 125; j++);

}

}

//

//延时函数, 对于110592MHz时钟, 例i=10,则大概延时10ms

void dsInit()

{

//对于110592MHz时钟, unsigned int型的i, 作一个i++ *** 作的时间大于8us

unsigned int i;

ds = 0;

i = 100; //拉低约800us, 符合协议要求的480us以上

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--;

}

//向DS18B20读取一位数据

//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,

//之后DS18B20则会输出持续一段时间的一位数据

bit readBit()

{

unsigned int i;

bit b;

ds = 0;

i++; //延时约8us, 符合协议要求至少保持1us

ds = 1;

i++;

i++; //延时约16us, 符合协议要求的至少延时15us以上

b = ds;

i = 8;

while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求

return b;

}

//读取一字节数据, 通过调用readBit()来实现

unsigned char readByte()

{

unsigned int i;

unsigned char j, dat;

dat = 0;

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

{

j = readBit();

//最先读出的是最低位数据

dat = (j << 7) | (dat >> 1);

}

return dat;

}

//向DS18B20写入一字节数据

void writeByte(unsigned char dat)

{

unsigned int i;

unsigned char j;

bit b;

for(j = 0; j < 8; j++)

{

b = dat & 0x01;

dat >>= 1;

//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1

if(b)

{

ds = 0;

i++;

i++; //拉低约16us, 符号要求15~60us内

ds = 1;

i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求

}

else //写"0", 将DQ拉低60us~120us

{

ds = 0;

i = 8; while(i>0) i--; //拉低约64us, 符号要求

ds = 1;

i++;

i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了

}

}

}

//向DS18B20发送温度转换命令

void sendChangeCmd()

{

dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化

dsWait(); //等待DS18B20应答

delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号

writeByte(0xcc); //写入跳过序列号命令字 Skip Rom

writeByte(0x44); //写入温度转换命令字 Convert T

}

//向DS18B20发送读取数据命令

void sendReadCmd()

{

// EA=0;//关闭中断是因为进入显示中断会影响到DS18B20的读写时序

dsInit();

dsWait();

delay(1);

writeByte(0xcc); //写入跳过序列号命令字 Skip Rom

writeByte(0xbe); //写入读取数据令字 Read Scratchpad

// EA=1;

}

//获取当前温度值

int getTmpValue()

{

unsigned int tmpvalue;

int value; //存放温度数值

float t;

unsigned char low, high;

// EA=0;

sendReadCmd();

//连续读取两个字节数据

low = readByte();

high = readByte();

//将高低两个字节合成一个整形变量

//计算机中对于负数是利用补码来表示的

//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value

tmpvalue = high;

tmpvalue <<= 8;

tmpvalue |= low;

value = tmpvalue;

//使用DS18B20的默认分辨率12位, 精确度为00625度, 即读回数据的最低位代表00625度

t = value 00625;

//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入

//如t=110625, 进行计数后, 得到value = 1106, 即1106 度

//如t=-110625, 进行计数后, 得到value = -1106, 即-1106 度

value = t 100 + (value > 0 05 : -05); //大于0加05, 小于0减05

return value;

// EA=1;

}

/

void Init_timer0()

{

TMOD=0x01;

TH0=th0;

TL0=tl0;

EA=1;

ET0=1;

TR0=1;

} /

void display(int dd)

{

uchar SH,SZ,SL,GH,GL,i,temp;

uchar dis[8]={10,10,10,10,10,10,10,10}; //从5-8的数字为10,相应的段码是0x00,即不显示

uint dda;

dda=abs(dd);

SH = dda/ 10000;

SZ = dda % 10000 / 1000;

SL = dda % 1000 / 100;

GH = dda % 100 / 10;

GL = dda % 10;

dis[0]=GL;

dis[1]=GH;

dis[2]=SL;

if((SZ==0)&&(SH==0))

dis[3]=10;

else

dis[3]=SZ;

if (dd<0)

dis[4]=11; //是负温度,显示“-”

else

{

if(SH==0)

dis[4]=10; //温度高位是0,不显示

else

dis[4]=SH;

}

temp=0xbf;

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

{

P0=0xff;

wei=1;

temp=_cror_(temp,1);

P0=temp;

wei=0;

P0=0;

duan=1;

if(i==2)

{

P0=0x80|table[dis[2]];

}

else

P0=table[dis[i]];

duan=0;

delay(1);

}

/

P0=0xff;

wei=1;

P0=0xdf;

wei=0;

P0=0;

duan=1;

P0=table[GL];

delay(1);

duan=0;

P0=0xff;

wei=1;

P0=0xef;

wei=0;

P0=0;

duan=1;

P0=table[GH];

delay(1);

duan=0;

P0=0xff;

wei=1;

P0=0xf7;

wei=0;

P0=0;

duan=1;

P0=table[SL]|0x80;

delay(1);

duan=0;

P0=0xff;

wei=1;

P0=0xfb;

wei=0;

P0=0;

duan=1;

P0=table[SZ];

delay(1);

duan=0;

P0=0xff;

wei=1;

P0=0xfd;

wei=0;

P0=0;

duan=1;

P0=table[SH];

delay(1);

duan=0;

P0=0xff;

wei=1;

P0=0xff;

wei=0; /

}

void main()

{

int tempValue1;

// init();

// Init_timer0();

while(1)

{

//启动温度转换

sendChangeCmd();

tempValue1 = getTmpValue();

display(tempValue1);

}

}

//根据自己的硬件改改端口,我已经成功了

#include <reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P3^7; //define interface 定义DS18B20接口

uint temp; // variable of temperature

uchar flag1; // sign of the result positive or negative

sbit p0_5=P0^5;

sbit p2_7=P2^7;

sbit p2_4=P2^4;

sbit p2_5=P2^5;

sbit p2_6=P2^6;

unsigned char code TABLE[]={

0xd7,0x11,0xcd,0x5d,0x1b,

0x5e,0xde,0x15,0xdf,0x5f,

0x9f,0xdf,0xc6,0xd7,0xce,0x8e};

void delay(uint count) //delay

{

uint i;

while(count)

{

i=200;

while(i>0)

i--;

count--;

}

}

void Init_Com(void)

{

TMOD = 0x20;

PCON = 0x00;

SCON = 0x50;

TH1 = 0xFd;

TL1 = 0xFd;

TR1 = 1;

}

void dsreset(void) //send reset and initialization command

{

uint i; //DS18B20初始化

DS=0;

i=103;

while(i>0)i--;

DS=1;

i=4;

while(i>0)i--;

}

bit tmpreadbit(void) //read a bit 读一位

{

uint i;

bit dat;

DS=0;i++; //i++ for delay 小延时一下

DS=1;i++;i++;

dat=DS;

i=8;while(i>0)i--;

return (dat);

}

uchar tmpread(void) //read a byte date 读一个字节

{

uchar i,j,dat;

dat=0;

for(i=1;i<=8;i++)

{

j=tmpreadbit();

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好

//一个字节在DAT里

}

return(dat); //将一个字节数据返回

}

void tmpwritebyte(uchar dat) //write a byte to ds18b20

{ //写一个字节到DS18B20里

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(testb) //write 1 写1部分

{

DS=0;

i++;i++;

DS=1;

i=8;while(i>0)i--;

}

else

{

DS=0; //write 0 写0部分

i=8;while(i>0)i--;

DS=1;

i++;i++;

}

}

}

void tmpchange(void) //DS18B20 begin change 发送温度转换命令

{

dsreset(); //初始化DS18B20

delay(1); //延时

tmpwritebyte(0xcc); // 跳过序列号命令

tmpwritebyte(0x44); //发送温度转换命令

}

uint tmp() //get the temperature 获得温度

{

float tt;

uchar a,b;

dsreset();

delay(1);

tmpwritebyte(0xcc);

tmpwritebyte(0xbe); //发送读取数据命令

a=tmpread(); //连续读两个字节数据

b=tmpread();

temp=b;

temp<<=8; //two byte compose a int variable

temp=temp|a; //两字节合成一个整型变量。

tt=temp00625; //得到真实十进制温度值,因为DS18B20

//可以精确到00625度,所以读回数据的最低位代表的是

//00625度。

temp=tt10+05; //放大十倍,这样做的目的将小数点后第一位

//也转换为可显示数字,同时进行一个四舍五入 *** 作。

return temp; //返回温度值

}

void delay10ms() //delay

{

uchar a,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

void display(uint temp)

{

uchar a,b,c,d;

a=temp/100;

b=temp/10-a10;

d=temp%10;

c=(temp%100-d)/10;

P0=TABLE[d];

p0_5=0;

p2_7=0;

delay(1);

p2_7=1;

P0=TABLE[c];

p2_4=0;

delay(1);

p2_4=1;

P0=TABLE[b];

p0_5=1;

p2_5=0;

delay(1);

p2_5=1;

P0=TABLE[a];

p2_6=0;

delay(1);

p2_6=1;

}

void main() //主函数

{

uchar a;

Init_Com(); //初始化串口

do

{

tmpchange(); //温度转换

for(a=10;a>0;a--)

{

display(tmp()); //显示十次

}

}

while(1);

}

把返回值放到你数码管显示子程序中分解显示即可

sbit DQ=P1^6; //采集温度数据线

sbit SPK=P3^7;

unsigned char tflag;

unsigned int tive;

float temper;

/

函数功能:短暂延时

入口参数:num

出口参数:

/

void delay(unsigned int num)

{

while(num--);

}

/

函数功能:DS18B20初始化

入口参数:

出口参数:

/

void init_DS18B20(void)

{

//主机发送复位脉冲

DQ=1;

DQ=0;

delay(600); //x

DQ=1;

//等待DS18B20发送应答信号

delay(60); //防止DS18B20本身问题而读不出数据采用确认法

while(!DQ);

// delay(480); //DS18B20本身没有问题,可以延时将应答过程忽略

}

/

函数功能:读一个字节

入口参数:

出口参数:

/

readchar(void) //从低位开始读

{

unsigned char i=0;

unsigned char dat=0;

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

{

DQ=1;

DQ=0;

delay(10); //CPU缓冲时间 采样时间

dat>>=1; //从高到低先存放一位数据

DQ=1;

if(DQ) //如果是1,将数据存放

dat|=0x80;

DQ=1;

delay(9); //数据读取时间,下一次数据读取前需要延时

}

return(dat);

}

/

函数功能:写一个字节

入口参数:

出口参数:

/

writechar(unsigned char dat)

{

unsigned char i=0;

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

{

DQ=1;

DQ=0; //等待接收缓冲区的来临,整个过程的时间为60~120us

delay(15); //

DQ=dat&0x01; //第一次写最低位,将字节变为位

delay(15); //

dat>>=1; //准备写入下一位数据。

}

}

/

函数功能:读取温度

入口参数:

出口参数:

/

read_temperature(void)

{

unsigned int a,b;

init_DS18B20(); //初始化子程序

writechar(0xcc); //写入指令

writechar(0x44);

init_DS18B20();

writechar(0xcc);

writechar(0xbe);

a=readchar(); //低八位

b=readchar(); //高八位

tive=b;

tive<<=8;

tive=tive|a;

if(tive>0x0800) //温度为负温度第13位到15为为1,温度为正温度 //第13位到15为为0,所以值小于0x800说明为正温度

tive=~tive+1;

else

tive=tive;

temper=tive00625; //采用12位分辨率所以每次的增量是00625

temper=temper10; //保留小数点后面一位

return(temper);

}

以上就是关于求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序全部的内容,包括:求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序、ds18b20显示温度程序,写完温度跳变很大,而且感觉显示的与实际温度无关,求大神、请问这个DS18B20程序能显示零度以下的温度吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9284824.html

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

发表评论

登录后才能评论

评论列表(0条)

保存