ds18b20采集数据只显示85是怎么回事

ds18b20采集数据只显示85是怎么回事,第1张

我之前也遇到过这种问题,当时调了一天。这个是驱动程序的问题,你的DS18B20驱动程序中,数据位的读取时候用到的时钟CLK之间时间沿太少,你在从CLK=0变到1之间(或者反过来)稍加延时,5个us左右就行了。

因为仿真软件是理想化的,只要有时钟就行。

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P3^3; //定义DS18B20接口

int temp;

uchar flag1;

void display(unsigned char lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void delay();//延时子函数,5个空指令

code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x08,0x00};

//共阴数码管 0-9 - _ 空 表

unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0};//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数

int tmp(void);

void tmpchange(void);

void tmpwritebyte(uchar dat);

uchar tmpread(void);

bit tmpreadbit(void);

void dsreset(void);

void delayb(uint count);

void main() //主函数

{

uchar i;

int l_tmp;

while(1)

{

tmpchange(); //温度转换

l_tmp=tmp();

if(l_tmp<0)

l_tmpdate[0]=10; //判断温度为负温度,前面加"-"

else

{

l_tmpdate[0]=temp/1000; //显示百位,这里用1000,是因为我们之前乖以10位了

if(l_tmpdate[0]==0)

l_tmpdate[0]=12;//判断温度为正温度且没有上百,前面不显示

}

l_tmp=temp%1000;

l_tmpdate[1]=l_tmp/100;//获取十位

l_tmp=l_tmp%100;

l_tmpdate[2]=l_tmp/10;//获取个位

l_tmpdate[3]=11;

l_tmpdate[4]=l_tmp%10;//获取小数第一位

for(i=0;i<10;i++){ //循环输出10次,提高亮度

display(l_tmpdate,5);

}

}

}

void display(unsigned char lp,unsigned char lc)//显示

{

unsigned char i; //定义变量

P2=0; //端口2为输出

P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管

for(i=0;i<lc;i++){ //循环显示

P2=table[lp[i]]; //查表法得到要显示数字的数码段

delay(); //延时5个空指令

if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据

break;

P2=0; //清0端口,准备显示下位

P1++; //下一位数码管

}

}

void delay(void) //空5个指令

{

_nop_();_nop_();_nop_();_nop_();_nop_();

}

void delayb(uint count) //delay

{

uint i;

while(count)

{

i=200;

while(i>0)

i--;

count--;

}

}

void dsreset(void) //DS18B20初始化

{

uint i;

DS=0;

i=103;

while(i>0)i--;

DS=1;

i=4;

while(i>0)i--;

}

bit tmpreadbit(void) // 读一位

{

uint i;

bit dat;

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

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

dat=DS;

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

return (dat);

}

uchar tmpread(void) //读一个字节

{

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)

{ //写一个字节到DS18B20里

uint i;

uchar j;

bit testb;

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

{

testb=dat&0x01;

dat=dat>>1;

if(testb) // 写1部分

{

DS=0;

i++;i++;

DS=1;

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

}

else

{

DS=0; //写0部分

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

DS=1;

i++;i++;

}

}

}

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

{

dsreset(); //初始化DS18B20

delayb(1); //延时

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

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

}

int tmp() //获得温度

{

float tt;

uchar a,b;

dsreset();

delayb(1);

tmpwritebyte(0xcc);

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

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

b=tmpread();

temp=b;

temp<<=8;

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

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

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

//00625度。

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

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

return temp; //返回温度值

}

void readrom() //read the serial 读取温度传感器的序列号

{ //本程序中没有用到此函数

uchar sn1,sn2;

dsreset();

delayb(1);

tmpwritebyte(0x33);

sn1=tmpread();

sn2=tmpread();

}

void delay10ms()

{

uchar a,b;

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

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

}

ds18b20加lcd1602加串口输出最近刚刚做的,调试成功了,lcddata口是P0

#include<intrinsh>

#include<stdioh>

#include"STC12C5AH"

#define XTAL 11059200 // CUP 晶振频率

#define baudrate 9600 // 通信波特率

#define uchar unsigned char

#define uint unsigned int

sbit DQ=P2^3; //DS18B20数据脚

sbit E=P2^7; //1602使能

sbit RW=P2^6; //1602读写

sbit RS=P2^5; //1602数据/命令选择

uchar data temp_data[2] = {0x00,0x00}; //高低8位数据缓存

uchar code num[]={'0','1','2','3','4','5','6','7','8','9'}; //lcd1602数字转ASCII表用于显示数字

uint DS[4]; //温度显示4位有效数字

uint dh;

uint dl;

uint DStemp; //16进制转10进制数据缓存

void Delay(unsigned int num) { // DS18B20及主程序延时函数 1=3us

unsigned int i;

for(i=num;i>0;i--) ;

}

void InitUART(void) //串口初始化

{

TMOD = 0x20;

SCON = 0x50;

TH1 = 0xFD;

TL1 = TH1;

PCON = 0x00;

EA = 1;

ES = 1;

TR1 = 1;

}

void SendOneByte(unsigned char c) //串口发送1字节

{

SBUF = c;

while(!TI);

TI = 0;

}

void delay() //lcd1602延迟

{

int i,j;

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

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

;

}

void wcmd(uchar del) //命令写入程序

{

P0 = del;

RS = 0;

RW = 0;

E = 0;

delay();

E = 1;

delay();

}

void write(uchar del) //写入一位数据

{

P0 = del;

RS = 1;

RW = 0;

E = 0;

delay();

E = 1;

delay();

}

void L1602_init(void) //lcd1602初始化

{

wcmd(0x01);

wcmd(0x38);

wcmd(0x0c);

wcmd(0x06);

wcmd(0xd0);

}

void L1602_char(uchar hang,uchar lie,char sign) //写入1个字符

{

uchar a;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

wcmd(a);

write(sign);

}

void L1602_string(uchar hang,uchar lie,uchar p) //写入字符串

{

uchar a,b=0;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

while(1)

{

wcmd(a++);

b++;

if((p == '\0')||(b==16)) break;

write(p);

p++;

}

}

uchar Init_DS18B20(void) { // 初始化ds1820

DQ=1; // DQ复位

Delay(22); // 稍做延时

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

Delay(160); // 精确延时 大于 480us

DQ=1; // 拉高总线

Delay(22);

while(DQ);

L1602_string(1,15,"ok"); //初始化成功在LCD1602上显示OK

Delay(166);

DQ=1;

return(1); // 返回信号,0=presence,1= no presence

}

uchar ReadOneChar(void) { // 读一个字节

uchar i;

uchar value=0;

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

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(22); //66 us

}

DQ=1;

return(value);

}

void WriteOneChar(unsigned char dat) { // 写一个字节

unsigned char i=0;

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

DQ=0;

DQ=dat&0x01;

Delay(18);

DQ=1;

dat>>=1;

}

}

void Read_Temperature(void) { // 读取温度

Init_DS18B20();

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

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

Init_DS18B20();

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

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

temp_data[0]=ReadOneChar(); // 温度低8位

temp_data[1]=ReadOneChar(); // 温度高8位

}

void Main()

{

L1602_init(); //初始化LCD1602

Init_DS18B20(); //初始化DS18B20

InitUART(); //初始化串口通信

L1602_string(1,1,"DS18B20"); //lcd1602测试

L1602_string(2,15,"`c");

while(1)

{

Read_Temperature(); //读取高低8位数据

Delay(800000);

dl=temp_data[0];

dh=temp_data[1];

SendOneByte(dh); //串口发送高低8位数据

SendOneByte(dl);

DStemp=(dh256+dl)/10625/10; //16进制转换10进制 先除10否则会溢出

DS[0]=DStemp%10; //提取温度各个位数字

DS[1]=DStemp/10%10;

DS[2]=DStemp/100%10;

DS[3]=DStemp/1000;

L1602_char(1,3,''); //显示各个位数字

L1602_char(1,5,num[DS[0]]);

L1602_char(1,4,num[DS[1]]);

L1602_char(1,2,num[DS[2]]);

L1602_char(1,1,num[DS[3]]);

}

}

其实转ascii码只要加38就好了,当时没想到

以上就是关于ds18b20采集数据只显示85是怎么回事全部的内容,包括:ds18b20采集数据只显示85是怎么回事、ds18b20的c语言程序、用温度芯片ds18b20编写简单的检测温度程序,可总是不能正常运行。数码管总是静止显示271,请大虾指点。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/9283770.html

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

发表评论

登录后才能评论

评论列表(0条)

保存