打印

正在写ds18b20的程序。。。

[复制链接]
4380|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ai大海ai|  楼主 | 2012-8-4 16:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟头一次尝试着用51单片机操作芯片,看了一天的18b20的资料,稍微看懂了点,可写程序时,却无从下手,在网上看人家的源程序,表示差距好大。不大理解,这个芯片,就一个数据线,要把那么多的二进制数写进去,那得怎样的写啊?对于初学者独立看芯片然后写程序,大师们有何建议啊。。。

相关帖子

沙发
李冬发| | 2012-8-4 18:22 | 只看该作者
http://blog.gkong.com/more.asp?name=lidongfa&id=74990

这是本人做的一个机箱温控的一段程序。是PLM51的代码,主频12MHz。

$db pw(94) rom(large) co ot(3) sb
MCS51OS: DO;
$nolist
$include(\PLM51\REG51.DCL)
$include(\PLM51\LIT.DCL)
$include(DS18B20.dcl)
$list


DCL System$Err  LITERALLY '0';
DCL Hard$Err    LITERALLY '1';
DCL Command$Err LITERALLY '2';
DCL Time$Err    LITERALLY '3';
DCL Date$Err    LITERALLY '4';

DCL TemperatureLimit LITERALLY '40';

/*=========================================================================*/

DCL Copyright(*) BYTE CON
(
'Copyright(c) 2003 by LiDongfa.All right reserved'
);
DCL Version BYTE CON(00H);

/*=========================================================================*/
/*                                                                         */
/* System clock interrupt serve program.                                  */
/* Use the 1# timer and 1# register.                                      */
/*                                                                         */
/*=========================================================================*/

DCL Timer0Cnt WORD CON(1000);
DCL Char$Img(31) BYTE CON
(
/*       edga fbcp */
/* 0 */  0010$0001B, /* 0 */
/* 1 */  1111$1001B, /* 1 */
/* 2 */  0000$1011B, /* 2 */
/* 3 */  1000$1001B, /* 3 */
/* 4 */  1101$0001B, /* 4 */
/* 5 */  1000$0101B, /* 5 */
/* 6 */  0000$0101B, /* 6 */
/* 7 */  1110$1001B, /* 7 */
/* 8 */  0000$0001B, /* 8 */
/* 9 */  1000$0001B, /* 9 */
/*   */  1111$1111B  /* 10 */
);
DCL Disp$Buf(2) BYTE;
DCL (Disp$Buf$Ptr) BYTE;

DCL LED1   LITERALLY 'P32';
DCL LED2   LITERALLY 'P33';
DCL TMDAT   LITERALLY 'P35';
DCL FANOUT  LITERALLY 'P37';
DCL FanOutTmp BIT;
DCL FirstRead BIT;
DCL FanOutDelay BYTE;
DCL Temperature WORD;  /* 读取后温度值存于Temperature中 */
DCL Temp  WORD;

DCL Second WORD;
DCL MSecond$Cnt WORD;

Display$Temp:PROCEDURE PUB;
Temp = Temperature / 16;
Disp$Buf(0) = Char$Img(Temp MOD 10);
Disp$Buf(1) = Char$Img((Temp / 10) MOD 10);
END Display$Temp;

System$Clock:PROCEDURE USING 1;
MSecond$Cnt = MSecond$Cnt + 1;

IF MSecond$Cnt MOD 4 = 0 THEN
DO;
  LED1 = 1;
  LED2 = 1;
  P1 = Disp$Buf(Disp$Buf$Ptr);
  IF Disp$Buf$Ptr = 0 THEN
   LED1 = 0;
  ELSE IF Disp$Buf$Ptr = 1 THEN
   LED2 = 0;

  Disp$Buf$Ptr = Disp$Buf$Ptr + 1;
  IF Disp$Buf$Ptr >= 2 THEN
   Disp$Buf$Ptr = 0;
END;

IF MSecond$Cnt < 1000 THEN
  RETURN;
  
MSecond$Cnt = 0;
Second = Second + 1;

IF FanOutDelay > 0 THEN
  FanOutDelay = FanOutDelay - 1;

END System$Clock;


/*=========================================================================*/
clk$Inter: PROCEDURE INTERRUPT 1 USING 1;
TR0 = 0;
TH0 = HIGH(-Timer0Cnt + 34);
TL0 = LOW(-Timer0Cnt + 34);
TR0 = 1;

CALL System$Clock;
END clk$Inter;



/* End of System clock interrupt serve program. */
/*=======================================================================*/

Sys$Reset:PROCEDURE;
DCL i BYTE;

DISABLE;

MSecond$Cnt = 0;
Second = 0;

TH0  = HIGH(-Timer0Cnt);
TL0  = LOW(-Timer0Cnt);
IP   = 0000$0010B;
IE   = 0000$0010B;
TMOD = 0001$0001B;
TCON = 0001$0000B;
PCON = 0;
P1 = 0FFH;
P3 = 0FFH;

Disp$Buf$Ptr = 0;
Disp$Buf(0) = Char$Img(10);
Disp$Buf(1) = Char$Img(10);

Temperature = 0;
FirstRead = 1;
FanOutDelay = 20;

ENABLE;
END Sys$Reset;


/* 延时部分 */
dmsec:PROCEDURE(tm)  PUB;
DCL tm WORD;
DCL i BYTE;

DO WHILE (tm > 0);
  i = 150;
  DO WHILE (i > 0);
   i = i - 1;
  END;

  tm = tm - 1;
END;
END dmsec;


/* 发送复位 */
tmreset:PROCEDURE PUB;
DCL i BYTE;

TMDAT = 0;
i = 150;
DO WHILE(i > 0);
  i = i - 1;          /* 延时 900 uS(11.0592Mhz时) */
END;

TMDAT = 1;

i = 5;
DO WHILE (i > 0);
  i = i - 1;
END;
END tmreset;


/* 判断DS1820是否存在的子程序。最好不要用,因为当器件不存在时将会进入死循环 */
/* 等待存在脉冲 */
/* 判断器件是否存在 */
tmpre:PROCEDURE PUB;
DCL i BYTE;

DO WHILE (TMDAT);
END;

DO WHILE (NOT TMDAT);
END;

i = 7;
DO WHILE (i > 0);
  i = i - 1;
END;

END tmpre;

/* 读一位 */
tmrbit:PROCEDURE BIT PUB;
DCL i BYTE;
DCL dat BIT;

TMDAT = 0;
i = i + 1;
i = i + 1;
TMDAT = 1;
i = 2;
DO WHILE (i > 0);
  i = i - 1;  /* 延时 */
END;
dat = TMDAT;

i = 10;
DO WHILE (i > 0);
  i = i - 1;  /* 延时 */
END;

RETURN (dat);
END tmrbit;



/* 读一个字节 */
tmrbyte:PROCEDURE BYTE PUB;
DCL (j,dat) BYTE;
DCL (i) BYTE;

dat = 0;
DO i = 1 TO 8;
  j = EXPAND(tmrbit);
  dat = SHL(j,7) OR SHR(dat,1);
END;

RETURN (dat);
END tmrbyte;



/* 写一个字节 */
tmwbyte:PROCEDURE(dat) PUB;
DCL dat BYTE;

DCL testb  BIT;
DCL (i,j) BYTE;

DO j = 1 TO 8;
  testb = BOOLEAN(dat AND 1);
  
  dat = SHR(dat,1);
  IF testb = 1 THEN
  DO;
   TMDAT = 0;  /* 写1 */
   i = i + 1;
   i = i + 1;
   TMDAT = 1;
   i = 10;
   DO WHILE (i > 0);
    i = i - 1;
   END;
  END;
  ELSE
  DO;
   TMDAT = 0;  /* 写0 */
   i = 10;
   DO WHILE (i > 0);
    i = i - 1;
   END;
   TMDAT = 1;
   i = i + 1;
   i = i + 1;
  END;
END;
END tmwbyte;


/* 发送ds1820 开始转换 */
tmstart :PROCEDURE PUB;

CALL tmreset;   /* 复位 */
/* CALL tmpre; */  /* 等待存在脉冲 */
CALL dmsec (1);   /* 延时 */
CALL tmwbyte (0CCH); /* 跳过序列号命令 */
CALL tmwbyte (044H);  /* 发转换命令 44H */
END tmstart;


/* 读取温度 */
tmrtemp :PROCEDURE PUB;
DCL (a,b) BYTE;

CALL tmreset;   /* 复位 */
/* CALL tmpre; */  /* 等待存在脉冲 */
CALL dmsec (1);   /* 延时 */
CALL tmwbyte (0CCH);  /* 跳过序列号命令 */
CALL tmwbyte (0BEH);  /* 发送读取命令 */
a = tmrbyte;   /* 读取低位温度 */
b = tmrbyte;     /* 读取高位温度 */
Temp = b * 256;
Temp = Temp + a;

IF FirstRead = 1 THEN
DO;
  FirstRead = 0;
  Temperature = Temp;
END;
ELSE
DO;
  Temperature = (Temperature * 9 + Temp) / 10;
END;

END tmrtemp;


/* the program entry point */
DCL Cnt BYTE;

CALL Sys$Reset;
Cnt = 0;

MainLoop:

/* 这段是调试代码 */
/*
CALL dmsec (1000);
Disp$Buf(0) = Char$Img(Cnt);
Disp$Buf(1) = Char$Img(Cnt);

Cnt = Cnt + 1;
IF Cnt >= 10 THEN
DO;
  Cnt = 0;
END;

IF FanOutTmp = 1 THEN
DO;
  FanOutTmp = 0;
  FANOUT = FanOutTmp;
END;
ELSE
DO;
  FanOutTmp = 1;
  FANOUT = FanOutTmp;
END;
*/


/* 启动ds18b20 */
DISABLE;
CALL tmstart;
ENABLE;
CALL dmsec (1200);

/* 读取温度,执行完毕温度将存于Temperature中 */
DISABLE;
CALL tmrtemp;
ENABLE;

Temp = Temperature / 16;
IF FanOutDelay = 0 THEN
DO;
  IF Temp >= TemperatureLimit THEN
  DO;
   FanOutTmp = 0;
   FANOUT = FanOutTmp;
   FanOutDelay = 20;
  END;
  ELSE IF Temp < TemperatureLimit - 1 THEN
  DO;
   FanOutTmp = 1;
   FANOUT = FanOutTmp;
   FanOutDelay = 20;
  END;
END;

CALL Display$Temp;

GOTO MainLoop;

END MCS51OS;

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
dong_abc + 1
板凳
ai大海ai|  楼主 | 2012-8-4 22:35 | 只看该作者
好长啊,谢谢。。。 2# 李冬发

使用特权

评论回复
地板
NE5532| | 2012-8-5 09:12 | 只看该作者
没有理解串行通讯,就是因为只有1根线,所以才有那么复杂的通讯协议。搞这个器件,核心就是看懂1-W协议那部分,然后用程序来实现,至于寄存器设置,照着数据手册做就可以了。

使用特权

评论回复
5
zhoukouguren| | 2012-8-5 14:21 | 只看该作者
6
ai大海ai|  楼主 | 2012-8-5 14:54 | 只看该作者
恩,我看人家写的程序,对位操作太熟练了,特巧妙。。。不知道可不可以不用位操作那种的。 4# NE5532

使用特权

评论回复
7
NE5532| | 2012-8-5 15:00 | 只看该作者
恩,我看人家写的程序,对位操作太熟练了,特巧妙。。。不知道可不可以不用位操作那种的。 4# NE5532
ai大海ai 发表于 2012-8-5 14:54


位操作,是基本操作,大部分单片机操作位比操作字节慢,所以不是用位操作就是高手,做好规划,尽量减少位操作的,才是高手。

使用特权

评论回复
8
g7214| | 2012-8-5 16:01 | 只看该作者
这是什么语言。。。。

使用特权

评论回复
9
ayb_ice| | 2012-8-6 08:40 | 只看该作者
说话实话

写这个单总线确实还真需要的水平,特别是MCU还要考虑其它任务的时候

使用特权

评论回复
10
ai大海ai|  楼主 | 2012-8-6 09:13 | 只看该作者
那我是不是起步太高,有点好高骛远了? 9# ayb_ice

使用特权

评论回复
11
ai大海ai|  楼主 | 2012-8-6 09:14 | 只看该作者
但芯片是单总线的,只能进行位操作啊。。。 7# NE5532

使用特权

评论回复
12
ai大海ai|  楼主 | 2012-8-6 09:15 | 只看该作者
你这是c++写的? 2# 李冬发

使用特权

评论回复
13
ayb_ice| | 2012-8-6 09:27 | 只看该作者
那我是不是起步太高,有点好高骛远了? 9# ayb_ice
ai大海ai 发表于 2012-8-6 09:13



这个协议确实比SPI,UART,IIC要复杂点,有些地方不能快,也不能慢,慢慢来吧,先努力看协议,理解了协议再写程序

使用特权

评论回复
14
fjzzclc| | 2012-8-6 11:06 | 只看该作者
取经呀~~~~~~~~~

使用特权

评论回复
15
geek小虾| | 2012-8-6 12:28 | 只看该作者
这个时序里面的延时要求很严格 可以定义全局变量精确延时

使用特权

评论回复
16
NE5532| | 2012-8-6 16:56 | 只看该作者
楼主确实要求有点快了,应该先研究SPI和I2C之类。

使用特权

评论回复
17
李冬发| | 2012-8-7 03:11 | 只看该作者
这个是古董PLM语言。51的MCU只用PLM写,不用C。

使用特权

评论回复
18
ai大海ai|  楼主 | 2012-8-7 07:00 | 只看该作者
我写52的都用c。。。 17# 李冬发

使用特权

评论回复
19
ai大海ai|  楼主 | 2012-8-7 07:02 | 只看该作者
写一个delay()函数就可以了吧,源程序用的是i++这种的,一次为4毫秒。 15# geek小虾

使用特权

评论回复
20
ai大海ai|  楼主 | 2012-8-7 07:05 | 只看该作者
我看原作者的程序,差不多理解了,就是一位一位的送数据,把位整合为字节,一次以一字节的顺序传。个人感觉实践中比较好理解这些协议,像我看I2协议,看完都忘了,不理解。 13# ayb_ice

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

43

帖子

0

粉丝