我之前也遇到过这种问题,当时调了一天。这个是驱动程序的问题,你的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,请大虾指点。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)