标题:
请问一下protues模拟ds18b20显示总是是15.93是什么原因呢
[打印本页]
作者:
jinzhijie
时间:
2021-10-1 19:11
标题:
请问一下protues模拟ds18b20显示总是是15.93是什么原因呢
1.png
(117.39 KB, 下载次数: 39)
下载附件
2021-10-1 19:15 上传
#include"reg52.h"
#include"myled.h"
#include"ds18b20.h"
#include"delay.h"
#include"lcd1602.h"
#include"stdio.h"
//#include "temp.h"
void Timer0_Init(void);
unsigned char menuflag,ds18b20_timer;
unsigned char timer_us;
unsigned int timer_ms;
unsigned int timer_xs;
void main()
{
unsigned int ack;
int ds18b20_temp;//用来接收数据
int inttemp,dectemp;//保存分离温度inttemp整数部分和dectemp小数部分
unsigned char str[12];//用来保存数据转换成的字符串ascll码
unsigned char len;
Timer0_Init();
lcd1602_init();
delay1ms(10);
EA = 1;
while (1)
{
if(menuflag)
{
// inttemp = 6;
// ack = ds18b20_giveOrder(inttemp);
// lcd1602set_position(0,1);
// lcd1602_write_dat(ack + '0');
ack = ds18b20_giveOrder(0);
if(ack)
{
inttemp = ack>>4;//保留整数部分,即去高4位
dectemp = ack&0x0f;//取小数部分,就是低4位
len = lcd1602_integertostr(inttemp,str);//len就是inttemp的长度,这个函数就是计算长度的
str[len++] = '.';
dectemp = (dectemp*100)/16; //*0.0625
str[len++] = dectemp/10+'0'; //
str[len++] = dectemp%10+'0'; //
str[len] = '\0'; //结束符
while(len < 6)
{
str[len++] = ' ';//空格填满
}
lcd1602_shwo_str(0,0,str);
}
// led_display(timer_ms);
}
}
}
void Timer0_Init(void) //10微秒@12.000MHz
{
// AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x88; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;
TR0 = 1; //定时器0开始计时
}
void timer0_isr() interrupt 1
{
TR0 = 0;
ds18b20_timer = 1;
if(ds18b20_timer == 1)
{
timer_us++;
if(timer_us >= 10)
{
timer_us = 0;
timer_ms++;
if(timer_ms >= 500)
{
timer_ms = 0;
menuflag = ~menuflag;
timer_xs++;
if(timer_xs >= 1000)
{
}
}
}
}
TL0 = 0x88; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TR0 = 1;
}
#include"ds18b20.h"
#include"intrins.h"
void delay_us(uchar us)//约2us延时函数
{
while(--us);
}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadByte
* 函数功能 : 读取一个字节
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
unsigned char ds18b20_readbyte()
{
uchar i,dat;
for(i=0;i<8;i++)
{
ds18b20=0;
dat>>=1;
ds18b20=1;
if(ds18b20)
dat|=0x80;
delay_us(25);
}
return (dat);
}
/*******************************************************************************
* 函 数 名 : ds18b20_wretebyte
* 函数功能 : 向18B20写入一个字节
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_writebyte(unsigned char dat)
{
uchar i;
for(i=0;i<8;i++)
{
ds18b20=0;
ds18b20=dat&0x01;
delay_us(25);//延时
ds18b20=1;//释放总线准备下一次数据的写入
dat>>=1;
}
}
bit ds18b20_init()
{
bit i;
ds18b20=1;
delay_us(5);
ds18b20=0;
delay_us(200);//拉低总线499.45us,总线上的温度传感器将会被全部复位
delay_us(200);
ds18b20=1;//释放总线
delay_us(50);//延时37.95us,等待温度传感器发回存在信号
i=ds18b20;
delay_us(25);//延时141.95us,读取温度传感器存在的时间
return (i);
}
unsigned int ds18b20_giveOrder(u16 dat)//下达指令
{
unsigned int mynum;
unsigned char msb,lsb;
//初始化ds18b20
if(dat==0)
{
ds18b20_init();
ds18b20_writebyte(0xcc); //跳过ROM操作命令
ds18b20_writebyte(0x44); //发送温度转换
delay1ms(5);
ds18b20_init();
ds18b20_writebyte(0xcc); //跳过ROM操作命令
ds18b20_writebyte(0xbe); //发送读取温度命令
lsb = ds18b20_readbyte();
msb = ds18b20_readbyte();
msb<<=8;
mynum = ((int)msb<<8)+lsb;
}
return mynum;
}
#ifndef _DS18B20_H_
#define _DS18B20_H_
#include"reg52.h"
#include"delay.h"
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef u16
#define u16 unsigned char
#endif
sbit ds18b20 = P3^7;
unsigned int ds18b20_giveOrder(u16 dat1);//下达指令
#endif
#ifndef _LCD1602_H_
#define _LCD1602_H_
#include"reg52.h"
#include"delay.h"
#define lcd1602_dat P0
//#define LCD1602_4PINS
sbit lcd1602_rs = P2^0;
sbit lcd1602_rw = P2^1;
sbit lcd1602_en = P2^2;
void lcd1602_readbf();
void lcd1602_init();
void lcd1602_write_cmd(unsigned char cmd);
void lcd1602_write_dat(unsigned char dat);
void lcd1602_shwo_str(unsigned char x,unsigned char y,unsigned char *str);
unsigned char lcd1602_integertostr(long dat,unsigned char *str);
void lcd1602set_position(unsigned char x,unsigned char y);
#endif
#include"lcd1602.h"
#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
void lcd1602_readbf()//读lcd忙函数
{
unsigned char state;
unsigned char i;
lcd1602_dat= 0xff;//IO 口置1 做输入
lcd1602_dat |= 0xf0;//接四路高四位 口置1 做输入
lcd1602_rs = 0;
lcd1602_rw = 1;
do
{
lcd1602_en = 1;
state = lcd1602_dat;//一个脉冲只接四位 第一次为高四位
lcd1602_en = 0;
i++; //lcd1602_dat就是p0总io口
if(i>50)
break;
}
while(state & 0x80);
}
#else
void lcd1602_readbf()//读lcd忙函数
{
unsigned char state;
unsigned char i;
// lcd1602_dat= 0xff;//IO 口置1 做输入
//1602必须要接高四位
lcd1602_dat |= 0xf0;//接四路高四位 口置1 做输入
lcd1602_rs = 0;
lcd1602_rw = 1;
do
{
lcd1602_en = 1;
state = lcd1602_dat;//一个脉冲只接四位 第一次为高四位
lcd1602_en = 0;
delay1ms(1); //lcd1602_dat就是p0总io口
lcd1602_en = 1;
state |= lcd1602_dat; //再次发送 得到低四位
lcd1602_en = 0;
i++;
if(i>50)
break;
}
while(state & 0x80);
}
#endif
#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
void lcd1602_write_cmd(unsigned char cmd)
{
lcd1602_readbf();//忙检测
lcd1602_rs = 0;//函数
lcd1602_rw = 0;//写
lcd1602_dat= cmd;//lcd1602_dat就是p0总io口
delay1ms(1);
lcd1602_en = 1;
lcd1602_en = 0;
}
#else
void lcd1602_write_cmd(unsigned char cmd)
{
lcd1602_readbf();//忙检测
lcd1602_rs = 0;//函数
lcd1602_rw = 0;//写
lcd1602_dat= cmd;//高四位不需要处理,因为接的是高四位
delay1ms(5);
lcd1602_en = 1;
delay1ms(1);
lcd1602_en = 0;
lcd1602_dat = cmd << 4;
delay1ms(5);
lcd1602_en = 1;
delay1ms(1);
lcd1602_en = 0;
}
#endif
#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
void lcd1602_write_dat(unsigned char dat)
{
lcd1602_readbf();//忙检测
lcd1602_rs = 1;//数据
lcd1602_rw = 0;//写
lcd1602_dat= dat;//高四位不需要处理,因为接的是高四位
delay1ms(1);
lcd1602_en = 1;
lcd1602_en = 0;
}
#else
void lcd1602_write_dat(unsigned char dat)
{
lcd1602_readbf();//忙检测
lcd1602_rs = 1;//数据
lcd1602_rw = 0;//写
lcd1602_dat= dat;//高四位不需要处理,因为接的是高四位
delay1ms(5);
lcd1602_en = 1; //lcd1602_dat就是p0总io口
delay1ms(1);
lcd1602_en = 0;
lcd1602_dat = dat << 4;//低四位需要左移 因为接的是高四位所以数据需要左移
delay1ms(5);
lcd1602_en = 1;
delay1ms(1);
lcd1602_en = 0;
}
#endif
#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
void lcd1602_init()
{
lcd1602_write_cmd(0x02);//归位就是复位
lcd1602_write_cmd(0x06);//进入设置模式
lcd1602_write_cmd(0x0c);//显示开
lcd1602_write_cmd(0x38);//8位8位数据口,两行,5*8点阵
lcd1602_write_cmd(0x01);//清屏
}
#else
void lcd1602_init()
{
lcd1602_write_cmd(0x02);//归位就是复位
lcd1602_write_cmd(0x06);//进入设置模式
lcd1602_write_cmd(0x0c);//显示开
// lcd1602_write_cmd(0x38);//8位8位数据口,两行,5*8点阵
lcd1602_write_cmd(0x33);
delay1ms(5);
lcd1602_write_cmd(0x32);
lcd1602_write_cmd(0x28);//4位8位数据口,两行,5*8点阵
lcd1602_write_cmd(0x01);//清屏
}
#endif
void lcd1602_shwo_str(unsigned char x,unsigned char y,unsigned char *str)//定位加*str指针方式发送字符串
{
lcd1602_write_cmd(0x38);
if(y == 0)
{
lcd1602_write_cmd(0x80 + x);
}else{
lcd1602_write_cmd(0xc0 + x);
}
while(*str != '\0')// '\0'这个是结束符的意思
{
lcd1602_write_dat(*str++);
}
}
unsigned char lcd1602_integertostr(long dat,unsigned char *str)
{
unsigned int i = 0;
unsigned char len = 0;
unsigned char buf[11];
if(dat < 0)
{
dat = -dat;//如果是负数,取绝对值
*str++ = '-';
len++;
// dat = Numerical_conversion(dat);
for(i=0;dat>9; i++)
{
buf[i] = dat%10; //先遇10取余
dat /=10;
len++;
}
*str++ = dat%10 + '0'; //转换ascll码 + '0'或者*0x30
len++;
for(i=len;i>2;i--)
{
*str++ = buf[i-3] + '0';
}
*str = '\0';
}
if(dat > 0)
{
for(i=0;dat>9; i++)
{
buf[i] = dat%10; //先遇10取余
dat /=10;
len++;
}
*str++ = dat%10 + '0'; //转换ascll码 + '0'或者*0x30
len++;
for(i=len;i>1;i--)
{
*str++ = buf[i-2] + '0';
}
*str = '\0';
}
return len;
}
复制代码
作者:
wulin
时间:
2021-10-1 20:42
给你一个示例对照查找问题。
ds18b20 0~120度PWM恒温控制LCD显示 仿真.zip
(161.62 KB, 下载次数: 17)
2021-10-1 20:42 上传
点击文件名下载附件
作者:
gqzjl
时间:
2021-10-4 09:11
延时要长点
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1