请教大虾们如何编写C程序获取18B20的序列号?并且在液晶上显示
[ 本帖最后由 ruiquan765 于 2009-3-13 22:36 编辑 ]
Re: [求助] 如何获取18B20的序列号
我写了这个程序,可是却无法显示出来,谁帮我分析分析
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit rs=P2^7;
sbit rw=P2^6;
sbit e=P2^5;
sbit psb=P2^4;
sbit dq=P3^5;
uint temp;
char sn[8]={0}; //定义数组来存放序列号
void delay(uint count) //延时
{
uint i,j;
for(i=0;i
for(j=0;j<10;j++);
}
void b20_Init() //18B20初始化
{
uint i;
dq=0;
for(i=103;i>0;i--);
dq=1;
for(i=4;i>0;i--);
}
bit b20_Readbit() //18B20读一位
{
uint i;
bit dat;
dq=0;
i++;
dq=1;
i++;
i++;
dat=dq;
for(i=8;i>0;i--);
return(dat);
}
uchar b20_Readbyte() //18B20读一个字节
{
uchar i,j,dat;
dat=0;
for(i=0;i<8;i++)
{
j=b20_Readbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
void b20_Writebyte(uchar dat) //18B20写一个字节
{
uchar i,j;
bit testb;
for(j=0;j<8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
dq=0;
i++;
i++;
dq=1;
for(i=0;i<8;i++);
}
else
{
dq=0;
for(i=0;i<8;i++);
dq=1;
i++;
i++;
}
}
}
void b20_Readrom() //read the serial 读取温度传感器的序列号子函数
{
unsigned char i;
b20_Init();
delay(1);
b20_Writebyte(0x33);
for(i=7;i>-1;i--)
{
sn=b20_Readbyte();
}
}
bit Lcd_CheckBusy(void) //12864检查忙
{
bit busy;
rs=0;
rw=1;
e=1;
_nop_();
busy=(bit)(P0&0x80);
e=0;
return(busy);
}
void Lcd_Wait()
{
while(Lcd_CheckBusy());
}
void Lcd_Writedata(uchar i) //12864写数据
{
Lcd_Wait();
rs=1;
rw=0;
e=0;
_nop_();
_nop_();
P0=i;
e=1;
_nop_();
_nop_();
e=0;
}
void Lcd_Writecmd(uchar i) //12864写指令
{
Lcd_Wait();
rs=0;
rw=0;
e=0;
_nop_();
_nop_();
e=1;
P0=i;
_nop_();
_nop_();
e=0;
} //12864初始化
void Lcd_Init()
{
psb=1;
Lcd_Writecmd(0x30);
delay(5);
Lcd_Writecmd(0x0c);
delay(5);
Lcd_Writecmd(0x01);
delay(5);
Lcd_Writecmd(0x06);
}
void Lcd_Display() //12864显示
{
uchar i;
Lcd_Writecmd(0x80);
for(i=0;i<8;i++)
{
unsigned char l=sn&0x0f; //取低4位
unsigned char h=sn&0xf0; //取高4位
h>>=4;
if((h>=0x00)&&(h<=0x09))
Lcd_Writedata(h+0x30); //取ASCII码
else
Lcd_Writedata(h+0x37); //取ASCII码
if((l>=0x00)&&(l<=0x09))
Lcd_Writedata(l+0x30); //取ASCII码
else
Lcd_Writedata(l+0x37); //取ASCII码
}
}
void main()
{
Lcd_Init();
b20_Readrom();
while(1)
{
Lcd_Display();
delay(6000);
}
}
我也在研究多点测温的呵呵,不过比你晚了一年,现在在找怎么才能读到18b20的序列号,关于匹配ROM的问题,希望能多多帮忙……还有资料的话帮忙发
767738626@qq.com,谢啦!
18B20手册上对这些都有详细解释,我这里要说的仅仅是时序很重要。有条件还是用示波器调比较好。
恩,首先你可以先试着把温度测出来,先不读序列号,这样确保你的时序正确,然后使用读取ROM指令来读序列号。
关于这个序列号的读取,在我的AVR学习笔记里有,可以在论坛找到我的学习笔记,看看怎么实现的
赞同楼上说法,先试着把温度测出来确保你的时序正确,然后使用读取ROM指令来读序列号
*我的EMAIL: sunke9@qq.com
*我的博客http://blog.ednchina.com/sunke9/
*我网店:https://sunke9.taobao.com/
承接:电子、自动控制产品设计开发;单片机、ARM编程。
不要太相信你的程序,我就吃过大亏,一段代码,用了两年多,结果上新产品就是不行,时好时不好的,后来上示波器才发现波形误差了几个微秒。又改了才能用。所以总结经验。每次都要用示波器仔细调时序的说。
回复 5楼 tiankai001 的帖子
tiankai001说得很好,先读温度,如果温度读不起来建议用逻辑分析仪看时序。可以用并口虚拟逻辑分析器。网上都有得下
主要是吃18B20的亏太多了,每批货不一样,时钟都有些许差别,这在设计中是最头疼的。上次出问题是应为芯片前后变了,虽然型号都一样,可是竟然同样的代码时序不一样。(透漏下,国产的,具体谁大家都知道。不好明说免得人家说我诽谤。)现在紧张到换个IO都要重测时序,还别说,不同的IO也不一样。哎。。。
无奈,换别的芯片短时间也不可能,只能先这样弄了。。。
汇编好难,18b20 一个测温还好,多个读序列号就很麻烦了