ds18b20的完整程序(c51)
C51DS18B20数字温度计C语言
C51--DS18B20数字温度计--C语言#include;#include;#define uint unsigned int#define uchar unsigned charsbit DQ=P2^6;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit lcden=P1^2;void disp(uint a);void init(void);void delay(uint i);uchar ds18b20_init(void);void write_byte(uchar byte);uchar read_byte(void);uint read_ds18b20(void);void delay50us(void);void delayms(uint a);void lcd1602_wr_com(uchar com);void lcd1602_wr_data(uchar dat);void lcd_init(void);uchar code str[]="temperature"; void main(void){init();while(1){disp(read_ds18b20());delayms(50);}}void init(void)uchar i;lcd_init();lcd1602_wr_com(0x80+0x02); //显示的地址for(i=0;i;>;=1; //右移一位DQ=1;}delay(4);}uchar read_byte(void){uchar i,temp;for(i=0;i;>;=1; //右移一位DQ=1; //主机释放信号线_nop_();if(DQ)temp|=0x80; //将读出数据放在最高位,如果是0,信号线会设备继续拉低,1则为高delay(4);}return temp; //返回读出的一字节数据}uint read_ds18b20(void)uchar numh,numl;uint value;if(ds18b20_init()==0) //判断设置是否正常,0为正常{write_byte(0xcc); //跳过ROM序列号读取write_byte(0x44); //启动温度转换if(ds18b20_init()==0) //再次初始化{write_byte(0xcc);//跳过ROM序列号读取write_byte(0xbe);//读温度寄存器numl=read_byte();//读低位数据numh=read_byte();//读高位数据value=numh;value=value;0;i--)for(j=122;j>;0;j--);}void lcd1602_wr_com(uchar com){lcdrs=0;P0=com;delayms(2);lcden=1;delay50us();lcden=0;}void lcd1602_wr_data(uchar dat){lcdrs=1;P0=dat;delayms(2);lcden=1;delay50us();lcden=0;}void lcd_init(void){lcden=0;lcdrw=0;lcd1602_wr_com(0x38); //显示模式设置lcd1602_wr_com(0x0c); //开显示,不显示光标lcd1602_wr_com(0x06); //写字符后地址指针加1,整屏显示不移动lcd1602_wr_com(0x01); //清屏}。
#DS18B20多点测温(51_C程序)
DS18B20多点测温<读序列,匹配序列,51 C程序,1602显示)因为本人在前两天找DS18B20多点测温<51C程序),网上下载了很多,但是都不是很理想,后来,自己总结前人的知识,重新写了这个程序。
其中包括程序一:单个读序列号。
程序二,匹配并且读两个DS18B20,当然,读多个与读两个基本原理一样,只要加上其序列号等即可。
本程序所有显示都是用LCD160 2显示。
程序一:度序列号,并用1602显示,1602从左到右分别是低到高位。
#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7。
//ds18b20与单片机连接口sbit RS=P3^0。
sbit RW=P3^1。
sbit EN=P3^2。
unsigned char code str1[]={""}。
unsigned char code str2[]={" "}。
uchar fCode[8]。
uchar data disdata[5]。
uint tvalue。
//温度值uchar tflag。
//温度正负标志/*************************lcd1602程序**************************/void delay1ms(unsigned int ms>//延时1毫秒<不够精确的){unsigned int i,j。
for(i=0。
i<ms。
i++>for(j=0。
j<100。
j++>。
}void wr_com(unsigned char com>//写指令//{ delay1ms(1>。
RS=0。
RW=0。
EN=0。
P2=com。
delay1ms(1>。
EN=1。
delay1ms(1>。
DS18B20汇编程序(完整版)
DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE<P16F877A.INC>#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSCCBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
51单片机与ds18b20程序
#include <>#include <>#define uchar unsigned char#define uint unsigned intsbit DQ = P2^2; //数据口define interfacesbit dula = P2^6; //数码管段选sbit wela = P2^7; //数码管位选uint temp; //温度值 variable of temperature//不带小数点unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//带小数点unsigned char code table1[] ={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};/*************精确延时函数*****************/void delay(unsigned char i){while(--i);}/******************************************此延时函数针对的是12Mhz的晶振delay(0):延时518us 误差:518-2*256=6delay(1):延时7us (原帖写"5us"是错的)delay(10):延时25us 误差:25-20=5delay(20):延时45us 误差:45-40=5delay(100):延时205us 误差:205-200=5delay(200):延时405us 误差:405-400=5*******************************************//*****************DS18B20******************/void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command{DQ = 1; //DQ复位,不要也可行。
单片机设计 温度测量 ds18b20 C51 源程序
/*********************************************************************///// DS18B20温度计C程序/*********************************************************************///使用AT89C2051单片机,12MHZ晶振,用共阳LED数码管//P1口输出段码,P3口扫描//#pragma src(d:\aa.asm)#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P1 //段码输出口#define discan P3 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7; //温度输入口sbit DIN=P1^7; //LED小数点控制uint h;//////*******温度小数部分用查表法**********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x 09};//uchar code dis_7[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};/* 共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" */ uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; // 列扫描控制字uchar data temp_data[2]={0x00,0x00}; // 读出温度暂放uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据,一个运算暂存用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){char k;for(k=0;k<4;k++) //四位LED扫描控制{Disdata=dis_7[display[k]];if(k==1){DIN=0;}discan=scan_con[k];delay(90);discan=0xff;}}/////***********18B20复位函数**********/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence=0继续下一步}delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********///向1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4usif(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********///read_temp(){ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}///***********温度数据处理函数**********/work_temp(){uchar n=0; //if(temp_data[1]>127){temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1;}//负温度求补码display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//display[3]=display[4]/100;display[1]=display[4]%100;display[2]=display[1]/10;display[1]=display[1]%10;if(!display[3]){display[3]=0x0A;if(!display[2]){display[2]=0x0A;}}//最高位为0时都不显示if(n){display[3]=0x0B;}//负温度时最高位显示"-"}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;for(h=0;h<4;h++){display[h]=8;}//开机显示8888ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"8888"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据for(h=0;h<500;h++){scan();} //显示温度值2秒}}////*********************结束**************************//。
DS18B20数字温度计使用与C51程序
1.DS18B20基本知识DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1、DS18B20产品的特点(1)、只要求一个端口即可实现通信。
(2)、在DS18B20中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55。
C到+125。
C之间。
(5)、数字温度计的分辨率用户可以从9位到12位选择。
(6)、内部有温度上、下限告警设置。
2、DS18B20的引脚介绍TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。
(底视图)图1表1 DS18B20详细引脚功能描述3.DS18B20的使用方法由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
DS18B20的复位时序DS18B20的读时序对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时序是从主机把单总线拉低之后,在15us之内就得释放单总线,以让DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
51单片机Ds18b20温度传感器程序
* 实验名 : 18B20温度显示试验* 实验说明 : 数码管显示温度值,并且将温度值通过串口发送到电脑上。
* 连接方式 : 见连接图temp.h#ifndef __TEMP_H_#define __TEMP_H_#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//--定义使用的IO口--//sbit DSPORT=P3^7;//--声明全局函数--//void Delay1ms(uint );uchar Ds18b20Init();void Ds18b20WriteByte(uchar com);uchar Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadTemp();#endiftemp.c#include"temp.h"/******************************************************************************** 函数名: Delay1ms* 函数功能: 延时函数* 输入: 无* 输出: 无*******************************************************************************/void Delay1ms(uint y){uint x;for( ; y>0; y--){for(x=110; x>0; x--);}}/******************************************************************************** 函数名: Ds18b20Init* 函数功能: 初始化* 输入: 无* 输出: 初始化成功返回1,失败返回0*******************************************************************************/ uchar Ds18b20Init(){uchar i;DSPORT = 0;//将总线拉低480us~960usi = 70;while(i--);//延时642usDSPORT = 1;//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低i = 0;while(DSPORT)//等待DS18B20拉低总线{Delay1ms(1);i++;if(i>5)//等待>5MS{return 0;//初始化失败}}return 1;//初始化成功}/******************************************************************************** 函数名: Ds18b20WriteByte* 函数功能: 向18B20写入一个字节* 输入: com* 输出: 无*******************************************************************************/void Ds18b20WriteByte(uchar dat){uint i, j;for(j=0; j<8; j++){DSPORT = 0;//每写入一位数据之前先把总线拉低1usi++;DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始i=6;while(i--); //延时68us,持续时间最少60usDSPORT = 1;//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;}}/******************************************************************************** 函数名: Ds18b20ReadByte* 函数功能: 读取一个字节* 输入: com* 输出: 无*******************************************************************************/ uchar Ds18b20ReadByte(){uchar byte, bi;uint i, j;for(j=8; j>0; j--){DSPORT = 0;//先将总线拉低1usi++;DSPORT = 1;//然后释放总线i++;i++;//延时6us等待数据稳定bi = DSPORT;//读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。
ds18b20的 C51例子
*----------------------------------------------------*/
unsigned int tmrtemp_all(void)
{
unsigned char a,b;
unsigned int y3;
}
/*----------------------------------------------------
* Read a byte from 1820
*----------------------------------------------------*/
void tmwbyte(unsigned char dat)
for(;;)
{
RUN_LED=!RUN_LED;
/* Read_Id();*/
TX_C =!TX_C ;
currSensorNo=(currSensorNo==1)?0:1;
Display_AllTemp();
/*Change();*/
void Delay_Count (unsigned char Count )
{
while(Count>0) Count--;
}
/*----------------------------------------------------
* start Reset Pulse
void send(unsigned char count,unsigned char SEND_Buf[])
{
unsigned char i;
for(i=0;i<count;i++)
DS18B20汇编程序(完整版)
DS18B20汇编程序(完整版)DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSC CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
DS18b20 51汇编源程序
TSR5:MOVR0,#06BH
TSR6:DJNZR0,TSR6
TSR7:SETBDQ;表明不存在
RET
;********************设定DS18B20暂存器设定值**************
;RE_CONFIG:
;JBFLAG1,RE_CONFIG1
;RET
;RE_CONFIG1:MOVA,#0CCH;放跳过ROM命令
MOVCA,@A+DPTR;查十位数的7段代码
movp0,a;送出十位的7段代码
clrp2.4;开十位显示
acalld1ms;显示1ms
setbp2.4
djnzr1,dplop;100次没完循环
djnzr0,dpl1;4个100次没完循环
ret
;***********************************
LCALLWRITE_18B20
LCALLDISPLAY;延时
LCALLINIT_18B20
MOVA,#0CCH;跳过ROM
LCALLWRITE_18B20
MOVA,#0BEH;发出读温度换命令
LCALLWRITE_18B20
LCALLREAD2_18B20;读两个字节的温度
RET
;***************写DS18B20程序************
DECR1
DJNZR4,RE00
RET
;************读出的温度进行数据转换**************
CHANGE:MOVA,29H
MOVC,28H.0;将28H中的最低位移入C
RRCA
MOVC,28H.1
RRCA
MOVC,28H.2
18b20测温c51程序
18b20测温c51程序#include <reg51.h>#include<intrins.h>#define BUSY1 (DQ1==0)sbit DQ1 = P0^4;unsigned char idata TMP;unsigned char idata TMP_d;unsigned char f;void wr_ds18_1(char dat);unsigned char rd_ds18_1();/***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time){time=time-10;time=time/6;while(time!=0)time--;}/*****************************************************/ /* reset ds18b20 *//*****************************************************/ void ds_reset_1(void){unsigned char idata count=0;DQ1=0;time_delay(240);time_delay(240);DQ1=1;return;}void check_pre_1(void){while(DQ1);while(~DQ1);time_delay(30);}void read_ROM(void){int n;ds_reset_1();check_pre_1();wr_ds18_1(0x33);for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}}/*****************************************************/ /* Read a bit from 1820 位读取 *//*****************************************************/ bit tmrbit_1(void){idata char i=0;bi t dat;DQ1=0;_nop_();DQ1=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();dat = DQ1;time_delay(50);return dat;}/*****************************************************/ /* read a bety from ds18b20 字节读取 *//*****************************************************/ unsigned char rd_ds18_1(){unsigned char idata i,j,dat=0;for(i=1;i<=8;i++){j=tmrbi t_1();dat=(j<<(i-1))|dat;}return dat;}/*****************************************************/ /* write a bety from ds18b20 写字节 *//****************************************************/ void wr_ds18_1(char dat){signed char idata i=0;unsigned char idata j;bi t testb;for(j=1;j<=8;j++){testb=dat & 0x01;dat = dat>>1;if(testb){DQ1=0;_nop_();_nop_();DQ1=1;time_delay(60);}else{DQ1=0;time_delay(50);DQ1=1;_nop_();_nop_();}}}int get_temp_1(void){unsigned char idata a=0,b=0; unsigned char idata i;EA=0;ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温 */ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);if (a>8){TMP=(TMP+1);}}else{f=1;a=a>>4;b=b<<4;TMP=(a|b);TMP=~TMP;TMP=(TMP+1);}EA=1;return(TMP);}int get_temp_d(void){unsigned char idata a=0,b=0; unsigned char idata i,m;EA=0;ds_reset_1();//复位check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温 */ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);TMP_d=a;}else{f=1;a=~a;a=(a+1);b=~b;b=(b+1);m=a;a=a>>4;b=b<<4;TMP=(a|b); m=(m&0x0f); TMP_d=m; }EA=1;return(TMP); }。
51开发板DS18B20温度显示程序
#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define display1 0xfe //数码管1从右至左#define display2 0xfd //数码管2从右至左#define display3 0xfb //数码管3从右至左#define display4 0xf7 //数码管4从右至左#define display5 0xef //数码管5从右至左#define display6 0xdf //数码管6从右至左//===以下IO定义请根据您硬件的连接修改===sbit dula=P2^6;sbit wela=P2^7;sbit led=P2^5;sbit TMDAT=P2^2; //根据实实际情况设定sbit set=P3^4;//设定sbit up=P3^5;//加sbit down=P3^6;//减sbit ld7=P2^4; //输出指示//负温度标志ledsbit point=P0^7; //小数点显示uchar tempint,f,bb,tempth,settemp;//温度整数部分和小数部分int tempdf,c;code unsigned char ledmap[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//7段数码管0~9数字的共阳显示代码和负号位代码(最后一位)void set_ds18b20(); //初始化DS18B20子程序void get_temperature(); //获得温度子程序void read_ds18b20(); //读DS18B20子程序void write_ds18b20(uchar command);//向DS18B20写1字节子程序void delayms(uchar count); //延时count毫秒子程序void disp_temp(); //显示温度子程序void keyscan();void main(){ set_ds18b20();write_ds18b20(0xcc); //发跳过ROM匹配命令write_ds18b20(0xbe); //发出读温度命令read_ds18b20(); //将读出的数据settemp=tempth; //将TH读到单片机SP=0x60; //设置堆栈指针bb=0;led=0;while(1){keyscan();if(bb==0){get_temperature(); //获得温度}disp_temp(); //显示温度}}//***********************初始化DS18B20子程序********************************** //**************************************************************************** void set_ds18b20(){while(1){uchar delay,flag;flag=0;TMDAT=1;delay=1;while(--delay);TMDAT=0; //数据线置低电平delay=250;while(--delay); //低电平保持500usTMDAT=1; //数据线置高电平delay=30;while(--delay); //高电平保持60uswhile(TMDA T==0) //判断DS18B20是否发出低电平信号{delay=210; //DS18B20响应,延时420uswhile(--delay);if(TMDA T) //DS18B20发出高电平初始化成功,返回{flag=1; //DS18B20初始化成功标志//初始化成功LED标志break;}}if(flag) //初始化成功,再延时480us,时序要求{delay=240;while(--delay);break;}}}//***********************获得温度子程序*************************************** //**************************************************************************** void get_temperature() //温度转换、获得温度子程序{set_ds18b20(); //初始化DS18B20write_ds18b20(0xcc); //发跳过ROM匹配命令write_ds18b20(0x44); //发温度转换命令disp_temp(); //显示温度,等待AD转换set_ds18b20();write_ds18b20(0xcc); //发跳过ROM匹配命令write_ds18b20(0xbe); //发出读温度命令read_ds18b20(); //将读出的温度数据保存到tempint和tempdf处}//***********************读DS18B20子程序***************************************//**************************************************************************** void read_ds18b20(){uchar delay,i,j,k,temp,temph,templ;j=3; //读2位字节数据do{for(i=8;i>0;i--) //一个字节分8位读取{temp>>=1; //读取1位右移1位TMDAT=0; //数据线置低电平delay=1;while(--delay);TMDAT=1; //数据线置高电平delay=4;while(--delay); //延时8usif(TMDA T) //读取1位数据temp|=0x80;delay=25; //读取1位数据后延时50uswhile(--delay);}if(j==3)templ=temp;//读取的第一字节存templif(j==2)temph=temp; //读取的第二字节存temphif(j==1)tempth=temp; //读取的第3字节存tempth TH的值}while(--j);f=0;if((temph & 0xf8)!=0x00) //若温度为负的处理,对二进制补码的处理{f=1; //为负温度f置1temph=~temph;templ=~templ;k=templ+1;templ=k;if(k>255){temph++;}}tempdf=templ & 0x0f; //将读取的数据转换成温度值,整数部分存tempint,小数部分存tempdfc=(tempdf*625);tempdf=c;templ>>=4;temph<<=4;tempint=temph|templ;//两字节合并为一个字节}//***********************写DS18B20子程序***************************************//**************************************************************************** void write_ds18b20(uchar command){uchar delay,i;for(i=8;i>0;i--) //将一字节数据一位一位写入{TMDAT=0; //数据线置低电平delay=6; //延时12uswhile(--delay);TMDAT=command&0x01; //将数据放置在数据线上delay=25; //延时50uswhile(--delay);command=command>>1; //准备发送下一位数据TMDAT=1; //发送完一位数据,数据线置高电平}}//***********************显示子程序***************************************//**************************************************************************** void disp_temp(){uchar tempinth,tempintl,cnt,tempinbai,shifen,baifen,gefen,mi;if(bb!=0){tempint=settemp;tempdf=0;cnt=2;}else{cnt=100;}tempinbai=tempint/100;tempinth=tempint%100/10; //整数取模tempintl=tempint%10; //整数取模baifen =tempdf%10000/1000;shifen=tempdf%1000/100;gefen=tempdf%100/10; //小数取模mi=tempdf%10;while(--cnt){if(tempth>tempint)ld7=1;elseld7=1;while(f==1){dula=1;P0=ledmap[10];dula=0;if(tempinth==0){ wela=1;P0=display1;wela=0;delayms(1);goto loop;}else{P0=0xdf;}}delayms(1);P0=ledmap[tempinbai];dula=0;wela=1;P0=display1;//开百位wela=0;delayms(2);dula=1;P0=ledmap[tempinth];dula=0;wela=1;P0=display2;//开十位wela=0;delayms(2);loop:dula=1;P0=ledmap[tempintl];point=1;//小数点显示dula=0;wela=1;P0=display3; //开个位wela=0;delayms(2);dula=1;P0=ledmap[baifen];dula=0;wela=1;P0=display4; //开分位wela=0;delayms(2);dula=1;P0=ledmap[shifen];dula=0;wela=1;P0=display5; //开十分位wela=0;delayms(2);dula=1;P0=ledmap[gefen];dula=0;P0=display6; //开百分位wela=0;delayms(2);}}//***********************延时count ms子程序***************************************//**************************************************************************** void delayms(uchar count) //延时count ms子程序{uchar i,j;do{for(i=5;i>0;i--)for(j=98;j>0;j--);}while(--count);}//***********************键盘扫描子程序*************************************** //****************************************************************************void keyscan() //键盘扫描{if(set==0){delayms(1);}if(set==0){bb++;while(!set); //循环在此非0=1}if(bb==1){if(up==0){delayms(1);}if(up==0){disp_temp();if(settemp<125){settemp++;}while(!up)//非0=1{disp_temp();}}if(down==0){delayms(1);}if(down==0){disp_temp();if(settemp!=0) //不等于0为真执行{settemp--;while(!down) // down为(非0=1)循环执行{disp_temp();}}}}if(bb==2){bb=0;set_ds18b20(); //初始化DS18B20write_ds18b20(0xcc); //发跳过ROM匹配命令write_ds18b20(0x4e); //发温度转换命令write_ds18b20(settemp); //写TH 3//write_ds18b20(settemp); 写到TL 4// write_ds18b20(settemp); 写分辨率 5set_ds18b20(); //初始化DS18B20write_ds18b20(0xcc); //发跳过ROM匹配命令write_ds18b20(0x48);} }。
ds18b20 51单片机测温 自我总结+源程序
DS18B20总结复位时序/****************************************************************** - 功能描述:DS18B20复位- 隶属模块:DS18B20模块- 函数属性:内部- 参数说明:无- 返回说明:返回值为0说明复位成功,否则失败- 注:初始化是正确操作DS18B20是重要一步,必须复位成功******************************************************************/unsigned char DS18B20_Reset(){unsigned char x=0;DQ=1; //DQ拉高DQ=0; //单片机将DQ拉低delay(1800);//延时480us~960usDQ=1; //DQ拉高//以上是由单片机产生“复位脉冲”delay(100); //延时15us~60usx=DQ; //DS18B20产生“存在脉冲”//检测DQ 如果为低,说明复位成功,DS18B20存在//如果为高,说明复位失败,DS18B20损坏或不存在while(!DQ); //直到DQ为高return x; //返回复位结果}写时序/****************************************************************** - 功能描述:向DS18B20写入一个位(DS18B20的写时间片)- 隶属模块:DS18B20模块- 函数属性:内部- 参数说明:bdat:要写入的值,非0为1- 返回说明:无- 注:DS18B20的写时间片对时间的要求较为严格。
因此将此代码移植到其它CPU或场合时要注意延时函数******************************************************************/void DS18B20_WriteSlot(unsigned char bdat){DQ=1; //将数据线置为高电平delay(10); //两次写时间片间隔大于1usDQ=0; //开始一个写时间片delay(10); //写时间片的低电平保持1us以上DQ=bdat;delay(180); //写时间片开始15us后DS18B20对数据线进行采样//写时间片最短60usDQ=1;}/****************************************************************** - 功能描述:向DS18B20写入一个字节- 隶属模块:DS18B20模块- 函数属性:内部- 参数说明:dat:将要向DS18B20写入字节- 返回说明:无- 注:此函数调用写时间片来实现字节的写入******************************************************************/void DS18B20_WriteByte(unsigned char dat){unsigned char i=0;for(i=0;i<8;i++) //调用8次写时间片实现写入字节(8个位){DS18B20_WriteSlot(dat&(1<<i));}}读时序/****************************************************************** - 功能描述:从DS18B20读取一个位(DS18B20的读时间片)- 隶属模块:DS18B20模块- 函数属性:内部- 参数说明:无- 返回说明:读到的值,1或0- 注:DS18B20的读时间片对时间的要求较为严格。
DS18B201602多点测温(51_C程序)解析
DS18B20多点测温(读序列,匹配序列,51 C程序,1602显示)由于本人在前两天找DS18B20多点测温(51 C程序),网上下载了很多,但是都不是很理想,后来,自己总结前人的知识,重新写了这个程序。
其中包括程序一:单个读序列号。
程序二,匹配并且读两个DS18B20,当然,读多个与读两个基本原理一样,只要加上其序列号等即可。
本程序所有显示都是用LCD1602显示。
程序一:度序列号,并用1602显示,1602从左到右分别是低到高位。
#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P2^3;//ds18b20与单片机连接口sbit RS=P2^5;sbit RW=P2^6;sbit EN=P2^7;unsigned char code str1[]={" "};unsigned char code str2[]={" "};uchar fCode[8];uchar data disdata[5];uint tvalue;//温度值uchar tflag;//温度正负标志/*************************lcd1602程序**************************/void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void wr_com(unsigned char com)//写指令//{ delay1ms(1);RS=0;RW=0;EN=0;P0=com;delay1ms(1);EN=1;delay1ms(1);EN=0;}void wr_dat(unsigned char dat)//写数据//{ delay1ms(1);;RS=1;RW=0;EN=0;P0=dat;delay1ms(1);EN=1;delay1ms(1);EN=0;}void lcd_init()//初始化设置//{delay1ms(15);wr_com(0x38);delay1ms(5);wr_com(0x08);delay1ms(5);wr_com(0x01);delay1ms(5);wr_com(0x06);delay1ms(5);wr_com(0x0c);delay1ms(5);}void display(unsigned char *p)//显示//{while(*p!='\0'){wr_dat(*p);p++;delay1ms(1);}}void init_play()//初始化显示{ lcd_init();wr_com(0x80);display(str1);wr_com(0xc0);display(str2);}/******************************ds1820 *********************/ void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ uchar x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480us DQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ uchar i=0;uchar dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {uchar i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/ {uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数return(tvalue);}/*******************************************************************/ void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}wr_com(0xc0);wr_dat(flagdat);//显示符号位wr_com(0xc1);wr_dat(disdata[0]);//显示百位wr_com(0xc2);wr_dat(disdata[1]);//显示十位wr_com(0xc3);wr_dat(disdata[2]);//显示个位wr_com(0xc4);wr_dat(0x2e);//显示小数点wr_com(0xc5);wr_dat(disdata[3]);//显示小数位}void DispCode(){unsigned char i,temp;ds1820rst();ds1820wr(0x33);for (i=0;i<8;i++){fCode[i]=ds1820rd();}wr_com(0x80+0x40);for (i=0;i<8;i++){temp = fCode[i]>>4; //显示高四位if (temp<10)wr_dat(temp + 0x30);elsewr_dat(temp + 0x37);temp = fCode[i]&0x0f;//显示低四位if (temp<10)wr_dat(temp+ 0x30);elsewr_dat(temp + 0x37);}}/********************主程序***********************************/ void main(){init_play();//初始化显示DispCode(); //系列号显示delay1ms(1000);while(1){//read_temp();//读取温度// ds1820disp();//显示;}}程序二:匹配序列号,并读温度。
DS18B20-51单片机汇编程序
DS18B20程序,51单片机汇编程序,仅需修改前几行即可。
晶振大小12M,转换完全正确。
DQ BIT P1.3 ;温度传感器接口TEMP_L EQU 29H ;用于保存读出温度的低字节TEMP_H EQU 28H ;用于保存读出温度的高字节TEMP_XIAO EQU 27H ;用于保存温度的小数部分TEMP_GE EQU 26H ;用于保存温度的个位部分TEMP_SHI EQU 25H ;用于保存温度的十位部分DQ_DELAY EQU 40H/*****************************************DS18B20温度转换程序,包括转换成小数、个位、十位*****************************************/// lOOP:// ACALL DS_GET_TEMP ;读取DS18B20温度// ACALL DOFOR_TEMP ;转换为十进制的十位、各位和小树部分// AJMP lOOPDS_RST: ;DS18B20复位函数SETB DQNOPCLR DQMOV DQ_DELAY,#66 ;延时约660usACALL DELAYSETB DQMOV DQ_DELAY,#6 ;延时约60usACALL DELAYMOV C,DQJC DS_RSTMOV DQ_DELAY , #24 ;延时约240usACALL DELAYSETB DQRETDS_WR_BYTE: ;写指令函数SETB DQMOV R4,#8CLR CDS_WR_LOOP:CLR DQMOV DQ_DELAY , #1 ;延时10us,短一些较好ACALL DELAYRRC AMOV DQ , CMOV DQ_DELAY , #5 ;延时50us,因为采样有效期为15-45usACALL DELAYSETB DQNOPDJNZ R4,DS_WR_LOOPRETDS_RD_BYTE: ;读指令函数MOV R4,#8DS_RD_LOOP:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV DQ_DELAY,#1 ;延时约10usACALL DELAYMOV C,DQMOV DQ_DELAY,#5 ;延时50usACALL DELAYRRC ADJNZ R4,DS_RD_LOOPMOV @R1,ARETDS_GET_TEMP: ;读取温度函数CLR EA ;由于DS18B20对时序要求较严格,所以采样期间关中断SETB DQACALL DS_RST ;执行指令之前,必须复位MOV A,#0CCH ;忽略64位ROM地址,直接发送存储器指令ACALL DS_WR_BYTEMOV A,#044H ;发送开始转换指令ACALL DS_WR_BYTESETB EA ;转换期间可以开中断MOV DQ_DELAY,#200 ;转换时间最长750ms,延时了800ms。
基于51单片机的DS18B20温度传感器驱动程序加详解
基于51单片机的DS18B20温度传感器驱动程序加详解//此部分为18B20的驱动程序//本程序验证通过,晶振为12MHz#include <reg52.H>#include <intrins.h>sbit D18B20=P3^7; //DQ接P3^7#define NOP() _nop_()#define _Nop() _nop_()void TempDelay (unsigned char idata us); //延时函数定义void Init18b20 (void); //初始化函数定义void WriteByte (unsigned char idata wr); //单字节写入void read_bytes (unsigned char idata j); //定义多字节数据读取unsigned char CRC (unsigned char j);//定义校验码数组void GemTemp (void); //数据处理void Config18b20 (void); //配置上下限即处理位数(9/10/11) void ReadID (void); //读取器件ID,即ROM中的数据void TemperatuerResult(void); //最终数据输出//bit flag;unsigned int idata Temperature,D[10]; //定义温度数组unsigned char idata temp_buff[9]; //定义RAM数据暂存数组//存储读取的字节,read scratchpad为9字节,read rom ID为8字节unsigned char idata id_buff[8]; //定义ROM数据暂存数组unsigned char idata *p,TIM; //指针变量unsigned char idata crc_data; //CRC计算变量定义unsigned char code CrcTable [256]={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, 12 8, 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, 2 05,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, 2 38,50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 1 45, 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, 2 44, 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, 2 15, 137, 107, 53};//CRC数据表//Function:延时处理void TempDelay (unsigned char idata us){while(us--);}//Function:18B20初始化void Init18b20 (void){D18B20=1; //侦测到下跳沿,初始化_nop_();D18B20=0;TempDelay(160); //delay480 us (480)_nop_();D18B20=1; //释放总线TempDelay(30); //delay 96 us (60-112)_nop_();_nop_();_nop_(); //18B20侦测到此上升沿,会自动应答//发送presence信号//if(D18B20==0)// flag = 1; //detect 1820 success!//else// flag = 0; //detect 1820 fail!TempDelay(30); //delay 96 us(60-240)_nop_(); //发送应答脉冲_nop_();D18B20 = 1; //释放总线}//Function:向18B20写入一个字节void WriteByte (unsigned char idata wr) //单字节写入{unsigned char idata i;for (i=0;i<8;i++){D18B20 = 1;_nop_();D18B20 = 0; //侦测到下跳沿,初始化_nop_();D18B20=wr&0x01; //写数据在(60-120)us内TempDelay(30); //delay 96(60-120)us_nop_();_nop_(); //至少大于1us恢复时间D18B20=1; //释放总线wr >>= 1; //一个字节8位,总共写8次}}//Function:读18B20的一个字节unsigned char ReadByte (void) //读取单字节{unsigned char idata i,u=0;for(i=0;i<8;i++){D18B20 = 1;_nop_();D18B20 = 0; //负跳沿,初始化u >>= 1;D18B20 = 1; //释放总线if(D18B20==1)u |= 0x80;TempDelay (3); //15us内采样_nop_();}return(u);}//Function:读18B20void read_bytes (unsigned char idata j){unsigned char idata i;for(i=0;i<j;i++){*p = ReadByte();p++;}}//Function:CRC校验unsigned char CRC (unsigned char j){unsigned char idata i,crc_data=0;for(i=0;i<j;i++) //查表校验crc_data = CrcTable[crc_data^temp_buff[i]]; return (crc_data);//返回i=8时的crc_data}//若为0,校验正确,即此时的temp_buff[8]=0x00; //Function:读取温度void GemTemp (void){read_bytes (9);if (CRC(9)==0) //校验正确{ //暂存器第0字节低8位,第一字节为高8位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void write_byte(char val) { byte i; for (i=8; i>0; i--) // writes byte, one bit at a time { DQ = 0; // pull DQ low to start timeslot DQ = val&0x01; delay(5); // hold value for remainder of timeslot DQ = 1; val=val/2; } delay(5); } //读取温度 char Read_Temperature(void) { union{ byte c[2]; int x; }temp; ow_reset(); write_byte(0xCC); // Skip ROM write_byte(0xBE); // Read Scratch Pad temp.c[1]=read_byte(); temp.c[0]=read_byte(); ow_reset(); write_byte(0xCC); //Skip ROM write_byte(0x44); // Start Conversion return temp.x/2; }