[转帖]DS18B20测温传感器C51源程序!
转贴自精诚电子:/************************************************************
*18B20驱动程序,DQ为数据口,接于P2.1
*11.0592M晶振,上拉4.7k电阻
*Author:fyb
*2005-3-25 11:23,OK!
*************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uintunsigned int
sbit dq = P1^7;
bitflag;
uint Temperature;
uchar temp_buff; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
uchar id_buff;
uchar *p;
uchar crc_data;
uchar code CrcTable ={
0,94, 188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133, 103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59, 217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166, 68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210, 48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241, 19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148, 118,40,171,245,23,73,8,86,180,234,105,55,213, 139,
87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53};
//
/************************************************************
*Function:延时处理
*parameter:
*Return:
*Modify:
*************************************************************/
void TempDelay (uchar us)
{
while(us--);
}
/************************************************************
*Function:18B20初始化
*parameter:
*Return:
*Modify:
*************************************************************/
void Init18b20 (void)
{
dq=1;
_nop_();
dq=0;
TempDelay(86); //delay 530 uS//80
_nop_();
dq=1;
TempDelay(14); //delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(dq==0)
flag = 1; //detect 1820 success!
else
flag = 0; //detect 1820 fail!
TempDelay(20); //20
_nop_();
_nop_();
dq = 1;
}
/************************************************************
*Function:向18B20写入一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
void WriteByte (uchar wr)//单字节写入
{
uchar i;
for (i=0;i<8;i++)
{
dq = 0;
_nop_();
dq=wr&0x01;
TempDelay(5); //delay 45 uS //5
_nop_();
_nop_();
dq=1;
wr >>= 1;
}
}
/************************************************************
*Function:读18B20的一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
uchar ReadByte (void) //读取单字节
{
uchar i,u=0;
for(i=0;i<8;i++)
{
dq = 0;
u >>= 1;
dq = 1;
if(dq==1)
u |= 0x80;
TempDelay (4);
_nop_();
}
return(u);
}
/************************************************************
*Function:读18B20
*parameter:
*Return:
*Modify:
*************************************************************/
void read_bytes (uchar j)
{
uchar i;
for(i=0;i<j;i++)
[此贴子已经被作者于2005-11-7 10:16:24编辑过]
<P>再贴一个汇编的:转自C51BBS:</P>
<P>;12位分辨率DS18B20程序<BR>;======================================================================<BR>;由于公司代理服务器的限制,不能ftp到laogu.com,如果您<BR>;需更多的DS18B20(C51/PIC/DSP)资料,QQ:432656<BR>;12G最新版本的各种软件,操作系统/编程/代码/资料<BR>;哪位好心人帮我上传一些软件,谢谢!<BR>;======================================================================<BR>;下面代码是本人在前人的基础上,吸收优化,适合本人实际应用。<BR>;;特点:<BR>;1.防止定时器打断时序;<BR>;2.考虑了DS18B20损坏或者断线,单片机不会死循环;<BR>;3.具备补码=〉原码;<BR>;4.复位不正常时给出温度-55度,提醒用户检查;<BR>;5.稳定性:冰水 0度->用电吹风 120度->冰水 0度 正常//测试时请不要把引脚弄湿短路<BR>;6.破坏性:加热到150度以上,再降温到120度,软件正常显示实际温度; <BR>;注意:<BR>;在调试中,发现时序与DS18B20的批次有关,不同批次需要微调时序;<BR>;如果发现结果错误,请先调整debug 1,不行再依次调整debug 2,debug 3……<BR>;或许全部都要调整,看你运气 ^_^;<BR>;CPU AT89C52 11.0592MHz<BR>;DQ BIT P1.7<BR>;**********************************************************************<BR>;//12位分辨率<BR>;检测DS18B20的温度,最多检测3次;如果失败,给出-55度<BR>;出口:DS1820_L,DS1820_H<BR>;使用资源:A,C,R0,R6,R7,TH0<BR>;Edited by hello 2002/08/19/22<BR>;Changed by hello 2002/08/20/16/06||禁止修改||<BR>;----------------------------------------------------------------------<BR>DS1820:<BR> MOV DS1820_L,#70H<BR> MOV DS1820_H,#83H<BR> MOV TH0,#00 ;防止中断打乱时序<BR> MOV R1,#03<BR>DS1820_1:<BR> LCALL RE1820 ;RESET DS1820<BR> JNZ DS1820_9 ;RESET FAIL<BR> MOV TH0,#00 ;防止中断打乱时序<BR> MOV A,#0CCH ;SKIP ROM<BR> LCALL WR1820 <BR> MOV A,#44H ;CONVER T<BR> LCALL WR1820<BR> MOV A,#8 ;/debug 4 <BR> LCALL DL100M ;100ms<BR> MOV TH0,#00<BR> LCALL RE1820 ;RESET DS1820<BR> JNZ DS1820_9 ;RESET FAIL<BR> MOV A,#0CCH ;SKIP ROM<BR> LCALL WR1820<BR> MOV TH0,#00 ;防止中断打乱时序<BR> MOV A,#0BEH ;Read scratchpad<BR> LCALL WR1820<BR> MOV TH0,#00 ;防止中断打乱时序<BR> LCALL RD1820<BR> MOV DS1820_L,A<BR> LCALL RD1820<BR> MOV DS1820_H,A ;采样完成<BR> ;SJMP DS1820_EXIT<BR> CJNE A,#80H,$+3 ;以下给同事提供方便,将补码还原成原码<BR> JC DS1820_EXIT<BR> CPL A<BR> SETB ACC.7<BR> MOV DS1820_H,A<BR> MOV A,DS1820_L<BR> CPL A<BR> INC A<BR> MOV DS1820_L,A<BR> SJMP DS1820_EXIT<BR>DS1820_9:<BR> DJNZ R1,DS1820_1<BR>DS1820_EXIT: <BR> RET<BR>;-------------------------------------------------------------------------<BR>;<BR>;出口:A<BR>;复位成功:A=#0,复位失败:A=#0FFH<BR>;使用资源:A,R7<BR>;Edited by hello 2002/08/20<BR>;-------------------------------------------------------------------------<BR>RE1820:<BR> MOV A,#00H ;RESET DS1820 OK<BR> CLR DQ<BR> MOV R7,#100<BR> DJNZ R7,$<BR> DJNZ R7,$ <BR> ;DQ=#0,DELAY=255*2+100*2=710us/debug 3<BR> SETB DQ<BR> MOV R7,#35<BR> DJNZ R7,$ ;DQ=#1,DELAY=35*2=70us <BR> /debug 3<BR> JNB DQ,RE1820_1 ;RESET OK,GOTO RE1820_1<BR> MOV A,#0FFH ;FAIL,A=#0FFH <BR>RE1820_1:<BR> MOV R7,#240<BR> DJNZ R7,$ ;DELAY=160*2=320us <BR> /debug 3<BR> RET<BR>;------------------------------------------------------------------------<BR>;<BR>;入口:A<BR>;使用资源:A,C,R6,R7<BR>;Edited by hello 2002/08/20<BR>;------------------------------------------------------------------------<BR>WR1820:<BR> MOV R6,#08 ;1B=8bit<BR>WR1820_1:<BR> CLR DQ<BR> MOV R7,#6<BR> DJNZ R7,$ ;DQ=#0,DELAY=7*2=15us //debug 2<BR> RRC A ;1us<BR> MOV DQ,C ;1us<BR> MOV R7,#25<BR> DJNZ R7,$ ;DQ=#1,20*2=60us //debug 2<BR> <BR> SETB DQ<BR> NOP<BR> NOP<BR> DJNZ R6,WR1820_1<BR> SETB DQ<BR> RET<BR>;----------------------------------------------------------------------<BR>;<BR>;出口 :A<BR>;使用资源:A,C,R6,R7<BR>;Edited by hello 2002/08/20 <BR>;----------------------------------------------------------------------<BR>RD1820:<BR> MOV R6,#08<BR>RD1820_1:<BR> SETB DQ<BR> NOP<BR> NOP<BR> NOP<BR> CLR DQ<BR> NOP<BR> NOP<BR> NOP <BR> SETB DQ<BR> MOV R7,#7<BR> DJNZ R7,$ ;DQ=1,9*2=18us <BR> //debug 1<BR> MOV C,DQ<BR> RRC A<BR> MOV R7,#7<BR> DJNZ R7,$ ;DQ=1,9*2=18us <BR> //debug 1 <BR> NOP<BR> DJNZ R6,RD1820_1<BR> RET <BR>;----------------------------------------------------------------------<BR>;**********************************************************************</P> <P><STRONG>DS18B20testcode:</STRONG></P>
<P>//*******************************************<BR>//DS18B20 with 51 core driver<BR>//use 6MHZ osc<BR>//Create Time: 2005 08 18 <BR>//Modify Time: <BR>//********************************************<BR> <BR>#include"REG51.h"<BR>#include"Uart.h"<BR>#include "INTRINS.h"<BR><BR>sbit DS18B20Pin = P3^5;<BR>unsigned char TempBuffer;<BR><BR>//#define SYSTEMDELAY(unsigned int wDelayIndex) {for(wDelayIndex = 100; <BR>wDelayIndex > 0; wDelayIndex-- );}<BR>//********************************************<BR>// Function declare <BR>//********************************************<BR>void SystemDelay( int t);<BR>unsigned char BusWireReset(void);<BR>unsigned char DS18B20ReadSingleByte();<BR>void DS18B20WireSingleByte( unsigned char);<BR>void Read_Temperature(void);<BR><BR><BR>//========================================================<BR><BR>void SystemDelay(int t )<BR>{<BR> <BR> while(t--);<BR>}<BR>//========================================================<BR><BR><BR>void InitMCUSet(void)<BR>{<BR> P0 = 0xff;<BR> <BR> DS18B20Pin = 1;<BR> TMOD = 0x21; //TIME1 use mode 2 reload count ; Time0 use mode 1<BR> TCON = 0x40;<BR> SCON = 0x50;<BR> PCON = 0x80;//SMOD = 1;<BR> TL1= 0xf3;//BaudRate is 2400bps<BR> TH1= 0xf3;<BR> TH0 = 0;<BR> TL0 = 0; <BR> IE = 0x90; //EA = 1; ET0 = 0;<BR> // ET0 = 1;<BR> // EX0 = 1;<BR>}<BR>//========================================================<BR><BR>unsigned char BusWireReset()<BR>{<BR> <BR>unsigned char ucFlag = 0;<BR>DS18B20Pin = 0;<BR> <BR>SystemDelay(23);<BR>DS18B20Pin = 1;<BR>SystemDelay(2);<BR>//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();<BR>ucFlag =DS18B20Pin ;// if DS18B20PIN == 0 then find device<BR>SystemDelay(18);<BR>return ucFlag; <BR>}<BR>//========================================================<BR><BR>unsigned char DS18B20ReadSingleByte()<BR>{<BR> unsigned char ucData ;<BR> unsigned char i;<BR><BR> for( i = 0; i < 8; i++)<BR> {<BR>DS18B20Pin = 0;<BR>_nop_();<BR>DS18B20Pin = 1;<BR>_nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); <BR>ucData >>= 1;<BR>ucData |= (DS18B20Pin == 1)? 0x80:0x00;<BR><BR>SystemDelay(3);<BR> }<BR>// SystemDelay(3);<BR> return ucData;<BR>}<BR>//========================================================<BR><BR>void DS18B20WireSingleByte( unsigned char ucData)<BR>{<BR> unsigned char i;<BR> for( i = 0; i < 8; i++)<BR> {<BR> DS18B20Pin = 0;<BR> DS18B20Pin =((ucData & 0x01) == 0x01);<BR> ucData >>=1; <BR> <BR> SystemDelay(3);<BR> DS18B20Pin = 1;<BR> }<BR><BR> // SystemDelay(3);<BR>}<BR><BR>//========================================================<BR><BR>void Read_Temperature(void)<BR>{<BR> unsigned char i;<BR> <BR> if(BusWireReset() == 0) UART_SendMultiByte(SucessTable,3 );<BR> DS18B20WireSingleByte(0xCC); //Skip ROM<BR> DS18B20WireSingleByte(0x44); // Start Conversion<BR> //SYSTEMDELAY(2);<BR> SystemDelay(2);<BR> <BR> if(BusWireReset()==0) UART_SendMultiByte(SucessTable,3 );<BR> DS18B20WireSingleByte(0xcc); // Skip ROM<BR> DS18B20WireSingleByte(0xBE);// Read Scratch Pad<BR> for( i = 0; i < 8; i++)<BR> {<BR> TempBuffer = DS18B20ReadSingleByte();<BR> }<BR> UART_SendMultiByte(TempBuffer,2);<BR>}<BR> <BR>//========================================================<BR><BR>void main(void)<BR>{<BR> InitMCUSet();<BR> UART_SendMultiByte(HexTable,16);<BR><BR> while(1)<BR>{ <BR> Read_Temperature();<BR> SystemDelay(30000);<BR> <BR> }<BR>}<BR><BR><BR><BR>#ifndef __UART_H__ <BR>#define __UART_H__ <BR><BR><BR>//#include"Definetype.h"<BR><BR>//#define SYSCLK 11059200 <BR>#define SYSCLK 20000000 <BR>#define BAUDRATE0 9600<BR>#define DB_SENDMAXSIZE 0x10<BR>#define DB_RECMAXSIZE0x10<BR><BR><BR>#define UART_LENGTH_R 1<BR>#define UART_COMMEND_R2<BR>#define UART_DATA_R 3<BR>#define UART_VERIFY_R 4<BR><BR>#define UART_LENGTH_SEND 1<BR>#define UART_COMMEND_SEND2<BR>#define UART_DATA_SEND 3<BR>#define UART_VERIFY_SEND 4 <BR><BR>bitg_bReceiveSuccess= 0;<BR>unsigned char g_ucReceiveIndex = 0; <BR>unsigned char g_ucRecvStyle = UART_LENGTH_R; <BR><BR>unsigned char g_ucSendIndex = 0;<BR>unsigned char g_ucSendStyle ;<BR>unsigned charg_ucVerifySum;<BR><BR>#define UART_BUFFERSIZE0x0f // Length + Commend + Datas + SumVerify<BR>#define COMMEND 0x0A<BR><BR>char code HexTable[]={"0123456789ABCDEF"}; <BR>unsigned char code SucessTable[]= {0x00,0x01,0x02};<BR><BR>struct UartPackage <BR>{<BR>unsigned char ucLength;<BR>unsigned char ucCommend;<BR>unsigned char ucDataBuffers;<BR>unsigned char ucVerifySum; <BR>};<BR><BR>struct UartPackageUartRX,UartTX; <BR><BR>//void UART_SendMultiByte( unsigned char*Buffer ,unsigned ucLenth); <BR>void UART_SendMultiByte( unsigned char*Buffer ,unsigned ucLenth)<BR>{<BR> unsigned char i;<BR> ES = 0;<BR> for(i = 0; i < ucLenth; i++)<BR> {<BR> SBUF = Buffer;<BR> while(!TI); TI = 0;<BR> }<BR> ES = 1;<BR><BR>}<BR><BR><BR><BR><BR>#endif<BR></P>
页:
[1]