温度传感器18B20时序正确,但总是不成功的原因
难怪会失败!
前几天也出现向小编一样的情况
这就是时序不正确
不知道 咋的 我的还没调出来,同时也不上面的原因,不知为啥 哎 http://bbs.elecfans.com/jishu_448097_1_1.html
温度传感器读不出来一般都是时序的问题, for(time=0;time<200;time++);
你这延时是有多久啊?
书上写的是 600us左右吧 这也是我一直疑惑的问题,晶振12MHZ,不知这个语句时间怎么算。 哥,你指的时序问题是 像上面一样的语句时间长度问题
你用的是什么单片机啊!我来调试一下,看哈问题所在
不管能不能找到问题所在,先谢谢了 你先试试 吧
用的是
at89c51
bit datayn(void) //初始化设置
{
bit flag=1;
di=1;
for(time=0;time<2;time++);
di=0;
for(time=0;time<200;time++);
di=1;
for(time=0;time<10;time++);
flag=di;
for(time=0;time<100;time++);
di=1;
for(time=0;time<10;time++);
return(flag) ;
}
uchar read_onechar(void)
{
unsigned char dat;
unsigned char i;
for(i=0;i<8;i++)
{
di=1;
_nop_();
di=0;
dat>>=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
di=1;
for(time=0;time<2;time++);
if(di)
{
dat |= 0x80;
}
for(time=0;time<15;time++); //这里原先的4应该改大,否则读取错误
}
return dat;
}
void write_onechar(uchar dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
di=1;
_nop_();
di=0;
for(time=0;time<5;time++);
di=dat&0x01;
for(time=0;time<15;time++);
di=1; //这个释放总线必不可少,但你这里没错
_nop_();
_nop_();
dat>>=1;
}
for(time=0;time<3;time++);
}
你应该就是第一个注释那里有错,时间的精度没有问题,我调试的时候忘啦第二个注释的语句,结果搞啦好半天,这是按照你的仿真图来调试的
没有加液晶,是用LED灯来测试的,这样基本是没问题的啦!
哥,很感谢了 谢谢了
哥,有空能在帮我看个程序吗,还是18b20,温度倒是出来 ,也挺好。后来我在原来基础上加了四个模块(由不同温度调电机转速),刚开始还好,一段时间后就不稳了,有空帮忙看看吧,先谢谢了 http://bbs.elecfans.com/jishu_448650_1_1.html
最近因为开学等事情很忙,所以可能挤不出多少时间,不过我会帮你看一下的,这也算我们共同学习吧!
如果已经调试好啦!告诉我一下
先谢谢了 哈哈 暂时还没有调好,还有就是18b20温度变化后,显示屏变化显示很慢,一般有10s左右才变化;没加后面模块时候,温度显示时候,偶尔还会闪一下其他数字值温度,个人认为很可能是时序问题
后来我又把程序改过了 ,还是一样的毛病,现在才感觉写程序好写,不好调试啊 http://bbs.elecfans.com/jishu_448704_1_1.html
挺不错的资料,收藏了先
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2;
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit dula=P2^6;
sbit wela=P2^7;
uchar flag,num;
uint temp;
uchar code table[]={"Temp= C"};
uchar code table1[]={"0123456789"}; //不带小数点数字编码
void delay_us(uint x) //延时x微秒
{
while(x--);
}
void delay(uint i) //延时i 毫秒
{
uint x,y;
for(x=i;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) //液晶写命令函数
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //液晶写数据
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_yejing() //液晶初始化
{
dula=0;
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<12;num++)
{
write_data(table[num]);
delay(5);
}
write_com(0x80+10);
write_data(0xdf);
}
/*void ds_reset() //DS18B20初始化
{
ds=1;
delay_us(1);
ds=0;
// delay_us(600);
// delay_us(40);
delay_us(81);
ds=1;
delay_us(44);
if(ds==0)
flag=1; //检测28b20成功
else
flag=0; //检测28b20失败
delay_us(140);
ds=1;
} */
void ds_reset() //DS18B20初始化
{
uint i;
ds=0;
i=103;
while(i>0) i--;
ds=1;
i=4;
while(i>0) i--;
}
/*bit ds_read_bit() //温度传感器读一位
{
bit dat;
// ds=1;
// delay_us(2);
ds=0;
// delay_us(6);
// delay_us(2);
ds=1;
delay_us(4);
dat=ds;
delay_us(15);
return(dat);
} */
bit ds_read_bit()
{
uint i;
bit dat;
ds=0;
i++;
ds=1;
i++;i++;
dat=ds;
i=8;
while(i>0) i--;
return dat;
}
uchar ds_read_byte() //温度传感器读一字节
{
uchar value,i,j;
value=0;
for(i=0;i<8;i++)
{
j=ds_read_bit();
value=(j<<7)|(value>>1);
}
return value;
}
void ds_write_byte(uchar dat) //温度传感器写一个字节
{
uchar j;
uint i;
bit onebit;
for(j=0;j<8;j++)
{
onebit=dat&0x01;
dat=dat>>1;
if(onebit) //写1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else //写0
{
ds=0;
i=8;
while(i>0)
i--;
ds=1;
i++;i++;
}
}
}
void tem_change() //发送温度转换命令
{
ds_reset();
delay(2);
ds_write_byte(0xcc);
ds_write_byte(0x44);
}
uint get_temp()
{
float wendu;
uchar H,L;
ds_reset();
delay(2);
ds_write_byte(0xcc);
ds_write_byte(0xbe);
L=ds_read_byte();
H=ds_read_byte();
temp=H;
temp=temp<<8;
temp=temp|L;
wendu=temp*0.0625;
temp=wendu*100+0.05;
return temp;
}
void display(uint wendu) //液晶屏显示温度
{
uchar qian,bai,shi,ge,wenduH,wenduL;
wenduH=wendu/100;
wenduL=wendu%100;
qian=wenduH/10; //测得的温度的首位
bai=wenduH%10; //测得的温度的第二位
shi=wenduL/10; //测得的温度的第三位
ge=wenduL%10; //测得的温度的第四位
write_com(0x80+5);
delay(5);
write_data(table1[qian]);
delay(5);
write_data(table1[bai]);
delay(5);
write_data('.');
delay(5);
write_data(table1[shi]);
delay(5);
write_data(table1[ge]);
delay(5);
}
void main()
{
uint e;
init_yejing();
while(1)
{
tem_change();
for(e=10;e>0;e--)
{
display(get_temp());
}
}
}
我想问下大神们写一个字节这个地方为什么一定要分别把j定义为uchar 把i定义为uint,不能定义反也不能都定义成uint或uchar 否则就无法出数据呢?还有读一个字节这个地方为什么程序中那个函数可以, 但是我自己写的上面的那个程序就不行啊?眼都看瞎了都不知道怎么回事 谢谢大神了
