DS18B20编程
- 格式:doc
- 大小:95.00 KB
- 文档页数:8
DS18B20 Instruction注意:1、即使是在时序图中电阻上拉阶段,也需要用软件令PORTxn|=BIT(I)。
2、初始化中,由于期间反馈回来的存在脉冲不定时发出,所以,可以用“while(PINxn)”;,当存在脉冲已发到(PINxn 拉高),则可以结束死循环。
读数:将读入的16进制数转换为10进制数,再乘以0.0625得到实际的温度值(10进制摄氏温度表示)配置寄存器:低五位一直都是"1",TM是用于设置DS18B20在工作模式还是在测试模式。
在DS18B20出厂时该位被设置为0,用户不要去改动。
R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)。
高速暂存寄存器:温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节,读取时低位在前,高位在后。
共9个字节,分配如下图:通信协议:步骤:1.每一次读写之前都要对DS18B20进行复位操作,2.复位成功后发送一条ROM 指令,3.最后发送RAM指令。
复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
(即76~300us后cpu收到存在低脉冲,即成功)0x。
所有写时间隙必须最少持续60μs,包括两个写周期间至少1μs 的恢复时间。
(写完之后,自动会将其拉高(through pullup resistor),而无需软件拉高)对于写1时隙,必须在写时间隙开始后的15μs内允许数据线拉到高电平。
The data line must remain at a low logic level for a minimum of 1s; The host therefore must stop driving the DQ pin low in order to read its state 15s from the start of the read slot. By the end of the read time slot, the DQ pin will pull back high via the external pullup resistor (pull it high automatically).。
DS18B20温度传感器实现代码平台: freescale CodeWarriorMCU:MC9S12G128(汽车级芯⽚)#include "Ds18b20.h"/************************************************************* DS18B20 status initialization************************************************************/#pragma MESSAGE DISABLE C12056 //屏蔽警告INT8U Ds18b20StsInit(void){INT8U ack = DB_OK;INT16U outTime = 500;//DisableInterrupts/* 初始化状态 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);/* 拉低BUS,延时500us */BUS = LOW;DelayUs(480);/* BUS上拉,延时15us-60us */BUS = HIGH;DelayUs(30);/* BUS设置为输⼊ */BUS_DIR = LOW;/* 等待DS18B20存在脉冲做出回应,0正常,60-240us */DelayUs(8);while(BUS){--outTime; //超时处理if(outTime == 0){ack = DB_ERR;break;}}/* 等待DS18B20恢复稳定 */DelayUs(128);/* BUS上拉 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(280);//EnableInterruptsreturn (ack);}/************************************************************* Write data to ds18b20************************************************************/PRIVATE void Ds18b20WriteData(INT8U cmd){INT8U i;DisableInterruptsfor(i = 0; i < 8; i++){//BUS = LOW; //HIGH->LOW 启动写时序//Tim_Delay8Us(2);if(cmd & 0x01) //从低位开始发送数据,15us完成 {BUS = 0; //写1时序DelayUs(5);BUS = 1;}else{BUS = 0; //写0时序DelayUs(5);}DelayUs(60); //等待从器件采集数据BUS = HIGH; //拉⾼总线,起始状态DelayUs(8);cmd >>= 0x01;}EnableInterrupts}#if 1/************************************************************* Read data from ds18b20************************************************************/ PRIVATE INT8U Ds18b20ReadData(void){INT8U i;INT8U data = 0x00;BUS = HIGH;DelayUs(8);DisableInterruptsfor(i = 0; i < 8; i++){data >>= 0x01;BUS = LOW; //拉低总线,进⾏读时序操作 DelayUs(8);BUS = HIGH; //拉低总线,进⾏读时序操作 DelayUs(8);BUS_DIR = LOW; //配置为输⼊asm("nop");//Tim_Delay8Us(1);if(BUS){data |= 0x80;}DelayUs(60); //等待数据读缓存BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);}EnableInterruptsreturn (data);#endifINT8U Dt = 0, Dt1 = 0;/************************************************************* Get data from ds18b20************************************************************/INT16U Ds18b20GetTemperature(void){INT16U data = CLEAR;INT8U temp[2] = {0};Dt = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0x44); //启动温度转换Dt1 = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0xbe); //读暂存寄存器temp[0] = Ds18b20ReadData();temp[1] = Ds18b20ReadData();data = (temp[1] << 8) | temp[0];return (data);}调试DS18B20遇到采集数据不稳定情况: 不稳定现象:每读到⼏个正常数据后会有⼏个不正常的数据 不稳定原因:因为中断在打断我数据的读写以及采集 解决办法:因为DS18B20单总线读写时对时序要求很严格,每次读写时关闭中断即可得到稳定数据。
ds18b20c语言程序DS18B20驱动程序(C语言)//#include"reg51.h"sbit DQ =P1^4; //定义通信端口//延时函数/*void delay(unsigned inti){while(i--);}*///初始化函数Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ 复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于 480usDQ = 1; //拉高总线delay(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(20);}//读一个字节ReadOneChar(void){unsigned chari=0;unsigned char dat = 0;for (i=8;i>;0;i--){DQ = 0; // 给脉冲信号dat>;>;=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay(4);}return(dat);}//写一个字节WriteOneChar(unsigned chardat){unsigned char i=0;for (i=8; i>;0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ =1;dat>;>;=1;}//delay(4);}//DS18B20程序读取温度ReadTemperature(void){unsigned char a=0;unsignedchar b=0;unsigned int t=0;floattt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar();b=ReadOneChar();t=b;t<<=8;t=t|a;t t=t*0.0625;//t= tt*10+0.5; //放大10倍输出并四舍五入---此行没用return(t);}//DS18B20主程序main(){unsigned chari=0;while(1){i=ReadTemperature();//读温度}}ds18b20c语言程序完毕。
ds18b20汇编程序:本汇编程序仅适合单个DS18B20和51单片机的连接,晶振为12 MHZ左右DQ:DS18B20的数据总线接脚FLAG1:标志位,为"1"时表示检测到DS18B20TEMPER_NUM:保存读出的温度数据TEMPER_LEQU36HTEMPER_HEQU35HDQBITP1.7; DS18B20初始化汇编程序;//*****************************************//INIT_1820:SETBDQNOPCLRDQMOVR0,#06BHTSR1:DJNZR0,TSR1; 延时SETBDQMOVR0,#25HTSR2:JNBDQ,TSR3DJNZR0,TSR2LJMPTSR4; 延时TSR3:SETBFLAG1; 置标志位,表示DS1820存在LJMPTSR5TSR4:CLRFLAG1; 清标志位,表示DS1820不存在LJMPTSR7TSR5:MOVR0,#06BHTSR6:DJNZR0,TSR6; 延时TSR7:SETBDQRET;//*****************************************// ; 重新写DS18B20暂存存储器设定值;//*****************************************//RE_CONFIG:JBFLAG1,RE_CONFIG1; 若DS18B20存在,转RE_CONFIG1 RETRE_CONFIG1:MOVA,#0CCH; 发SKIP ROM命令LCALLWRITE_1820MOVA,#4EH; 发写暂存存储器命令LCALLWRITE_1820MOVA,#00H; TH(报警上限)中写入00HLCALLWRITE_1820MOVA,#00H; TL(报警下限)中写入00HLCALLWRITE_1820MOVA,#1FH; 选择9位温度分辨率LCALLWRITE_1820RET;//*****************************************//; 读出转换后的温度值;//*****************************************//GET_TEMPER:SETBDQ; 定时入口LCALLINIT_1820JBFLAG1,TSS2RET; 若DS18B20不存在则返回TSS2:MOVA,#0CCH; 跳过ROM匹配LCALLWRITE_1820MOVA,#44H; 发出温度转换命令LCALLWRITE_1820LCALLINIT_1820MOVA,#0CCH; 跳过ROM匹配LCALLWRITE_1820MOVA,#0BEH; 发出读温度命令LCALLWRITE_1820LCALLREAD_1820MOVTEMPER_NUM,A; 将读出的温度数据保存RET;//*****************************************//; 读DS18B20的程序,从DS18B20中读出一个字节的数据;//*****************************************// READ_1820:MOVR2,#8RE1:CLRCSETBDQNOPNOPCLRDQNOPNOPNOPSETBDQMOVR3,#7DJNZR3,$MOVC,DQMOVR3,#23DJNZR3,$RRCADJNZR2,RE1RET;//*****************************************//; 写DS18B20的程序;//*****************************************// WRITE_1820:MOVR2,#8CLRCWR1:CLRDQMOVR3,#6DJNZR3,$RRCAMOVDQ,CMOVR3,#23DJNZR3,$SETBDQNOPDJNZR2,WR1SETBDQ RET;//*****************************************//; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据;//*****************************************//READ_18200:MOVR4,#2; 将温度高位和低位从DS18B20中读出MOVR1,#36H; 低位存入36H(TEMPER_L),高位存入35H(TEMP ER_H)RE00:MOVR2,#8RE01:CLRCSETBDQNOPNOPCLRDQNOPNOPNOPSETBDQMOVR3,#7DJNZR3,$MOVC,DQMOVR3,#23DJNZR3,$RRCADJNZR2,RE01MOV@R1,ADECR1DJNZR4,RE00RET;//*****************************************//; 将从DS18B20中读出的温度数据进行转换;//*****************************************//TEMPER_COV:MOVA,#0F0HANLA,TEMPER_L; 舍去温度低位中小数点后的四位温度数值SWAPAMOVTEMPER_NUM,AMOVA,TEMPER_LJNBACC.3,TEMPER_COV1; 四舍五入去温度值INCTEMPER_NUMTEMPER_COV1:MOVA,TEMPER_HANLA,#07HSWAPAORLA,TEMPER_NUMMOVTEMPER_NUM,A; 保存变换后的温度数据LCALLBIN_BCDRET;//*****************************************//; 将16进制的温度数据转换成压缩BCD码;//*****************************************//BIN_BCD:MOVDPTR,#TEMP_TABMOVA,TEMPER_NUMMOVCA,@A+DPTRMOVTEMPER_NUM,ARETTEMP_TAB:DB00H,01H,02H,03H,04H,05H,06H,07HDB08H,09H,10H,11H,12H,13H,14H,15HDB16H,17H,18H,19H,20H,21H,22H,23HDB24H,25H,26H,27H,28H,29H,30H,31HDB32H,33H,34H,35H,36H,37H,38H,39HDB40H,41H,42H,43H,44H,45H,46H,47HDB48H,49H,50H,51H,52H,53H,54H,55HDB56H,57H,58H,59H,60H,61H,62H,63HDB64H,65H,66H,67H,68H,69H,70H;//*****************************************//下面还介绍一个ds18b20汇编程序;**********************************FLAG1 BIT F0 ;DS18B20存在标志位DQ BIT P1.7TEMPER_L EQU 29HTEMPER_H EQU 28HA_BIT EQU 35HB_BIT EQU 36H;************ds18b20汇编程序起始******************** ORG 0000HAJMP MAINORG 0100H;**************主程序开始************MAIN:LCALL INIT_18B20;LCALL RE_CONFIGLCALL GET_TEMPERAJMP CHANGE;**********DS18B20复位程序*****************INIT_18B20: SETB DQNOPCLR DQMOV R0,#0FBHTSR1: DJNZ R0,TSR1 ;延时SETB DQMOV R0,#25HTSR2: JNB DQ ,TSR3DJNZ R0,TSR2TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在CLR P2.0 ;二极管指示AJMP TSR5TSR4: CLR FLAG1LJMP TSR7TSR5: MOV R0,#06BHTSR6: DJNZ R0,TSR6TSR7:SETB DQ ;表明不存在RET;********************设定DS18B20暂存器设定值********** ****;RE_CONFIG:;JB FLAG1,RE_CONFIG1;RET;RE_CONFIG1: MOV A,#0CCH ;放跳过ROM命令;LCALL WRITE_18B20;MOV A,#4EH;LCALL WRITE_18B20 ;写暂存器命令;MOV A,#00H ;报警上限中写入00H;LCALL WRITE_18B20;MOV A,#00H ;报警下限中写入00H; LCALL WRITE_18B20;MOV A,#1FH ;选择九位温度分辨率; LCALL WRITE_18B20; RET;*****************读转换后的温度值****************GET_TEMPER:SETB DQLCALL INIT_18B20JB FLAG1,TSS2RET ;若不存在则返回TSS2: MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#44H ;发出温度转换命令LCALL WRITE_18B20LCALL DISPLAY ;延时LCALL INIT_18B20MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#0BEH ;发出读温度换命令LCALL WRITE_18B20LCALL READ2_18B20 ;读两个字节的温度RET;***************写ds18b20汇编程序************WRITE_18B20:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;***********读18B20程序,读出两个字节的温度********* READ2_18B20:MOV R4,#2 ;低位存在29 H,高位存在28HMOV R1,#29HRE00: MOV R2,#8RE01: CLR CSETB CNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;************读出的温度进行数据转换**************CHANGE: MOV A,29HMOV C,28H.0 ;将28H中的最低位移入CRRC AMOV C,28H.1RRC AMOV C,28H.2RRC AMOV C,28H.3RRC AMOV 29H,A;setb p2.0LCALL DISPLAY ;调用数码管显示子程序; setb P2.0LJMP MAIN;*******************DISPLAY******DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制mov b,#10 ;10进制/10=10进制div abmov b_bit,a ;十位在amov a_bit,b ;个位在bmov dptr,#TAB ;指定查表启始地址mov r0,#4dpl1: mov r1,#250 ;显示1000次dplop: mov a,a_bit ;取个位数MOVC A,@A+DPTR ;查个位数的7段代码mov p0,a ;送出个位的7段代码clr p2.5;开个位显示acall d1ms ;显示1mssetb p2.5mov a,b_bit ;取十位数MOVC A,@A+DPTR ;查十位数的7段代码mov p0,a ;送出十位的7段代码clr p2.4;开十位显示acall d1ms ;显示1mssetb p2.4djnz r1,dplop ;100次没完循环djnz r0,dpl1 ;4个100次没完循环ret;***********************************D1MS: MOV R7,#80 ;1MS延时(按12MHZ算)DJNZ R7,$RET;*************************TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H, 90H。
ORG 0000HAJMP MAINORG 0030HMAIN: MOV R5,#0FFHMAIN1:MOV P0,#00H ;系统自检。
自高位向低位带小数点显示8扫描256次CLR P2.4LCALL DELAYSETB P2.4CLR P2.5LCALL DELAYSETB P2.5CLR P2.6LCALL DELAYSETB P2.6CLR P2.7LCALL DELAYSETB P2.7DJNZ R5,MAIN1SETB P2.4 ;关显示SETB P2.5SETB P2.6SETB P2.7SJMP MAIN2DELAY:MOV R7 ,#05H //;延时LP8: MOV R6,#19HLP7:DJNZ R6,LP7DJNZ R7,LP8RET; DS18B20初始化汇编程序;*****************************************//MAIN2:LCALL DISP //;主程序SETB P3.2 // ;18B20DQ置1拉高LCALL INIT // ;调初始化MOV A,#0CCH //;跳过ROM匹配------0CCLCALL WRITE // ;调写DS18B20的程序MOV A,#44H // ;发出温度转换命令LCALL WRITE // ;调写DS18B20的程序MOV R6,#34H //;延时136微秒转换时间,写一个字约需70微秒。
DJNZ R6,$LCALL DISPLCALL INITMOV A,#0CCHLCALL WRITEMOV A,#0BEH // ;发出读温度命令LCALL WRITELCALL READCLR CLCALL CONVTEMPLCALL DISPBCDLCALL DISPSJMP MAIN2WRITE:MOV R0,#8 // ;写子程序CLR CWR1: CLR P3.2MOV 20H,#3 // ;延时17微秒DJNZ 20H,$RRC AMOV P3.2,CMOV 21H,#10 // ;发送后延时45微秒DJNZ 21H,$SETB P3.2NOPDJNZ R0,WR1 // ;8位未发送完转SETB P3.2RETREAD: MOV R6,#2 // ;读子程序CLR PSW.5 // ;清清标志F0RE0:MOV R2,#8RE1:CLR CSETB P3.2 // ;拉高DQNOP // ;延时2微秒CLR P3.2 // ;拉低DQSETB P3.2MOV 22H,#3RE2:DJNZ 22H,RE2MOV C,P3.2MOV 23H,#10RE3:DJNZ 23H,RE3RRC ADJNZ R2,RE1 //;8位未读完继续读CPL PSW.5JNB PSW.5,RE4 // ;高8位保存至28HMOV 29H,A // ;低8位及小数保存至29HRE4:MOV 28H,ADJNZ R6,RE0 //;高8位未读继续RETINIT:SETB P3.2 // ;初始化开始DQ置1(整个时隙和理论值不是很准确)NOP //;延时L0:CLR P3.2 // ;DQ拉低MOV 24H,#100 // ;延时400微秒DJNZ 24H,$SETB P3.2 // ;DQ拉高MOV 25H,#10 // ;置40微秒延时常数L01:JNB P3.2,L2 // ;有18B20响应转L2DJNZ 25H,L01 // ;无18B20响应等待40微秒SJMP L0 // ;无18B20重新初始化L2:MOV R7,#60 // ,延时240微秒L3:DJNZ R7,L3SETB P3.2 //;DQ拉高、退出RETCONVTEMP:MOV A,28H //;温度转换ANL A,#80H //;温度正负判别JZ TEMPC1 //;温度为正转CLR C // ;温度为负调整MOV A,29HCPL AADD A,#01HMOV 29H,AMOV A,28HCPL AADDC A,#00HMOV 28H,AMOV 26H,#0BH // ;温度为负26H内送#0BHSJMP TEMPC11TEMPC1:MOV 26H,#0AH //;温度为正26H内送#0AHTEMPC11:MOV A,26HSWAP AMOV 26H,A // ;26H高4位为温度符号MOV A,29H // ;取温度小数部分ANL A,#0FH ;去整数个位MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV 27H,A // ;查表得小数值,并保存至27H单元MOV A,29H // ;温度整数部分拼装后暂时存入AANL A,#0F0H // ;留下整数个位SWAP AMOV 29H,AMOV A,28HANL A,#0FHSWAP AHEX2BCD1:MOV B,#64H // ;温度整数部分除100得整数百位,并存入R7中DIV ABMOV R7,A // ;R7中为百位,B中为十位和个位MOV A,#0AH // ;温度整数部分除10得整数十位和个位XCH A,B // ;除数与被除数交换DIV ABSWAP AORL A,BTEMPC10:MOV 29H,A // ;温度十位和个位存入29H单元中,十位在高4位,个位在低4位ANL A,#0F0H // ;取温度十位SWAP AORL A,26H //;十位加温度符号存入26H单元;高4位为符号MOV 26H,AMOV A,29HANL A,#0FH // ;取温度个位SWAP AORL A,27HMOV 27H,A // ;27H单元中高4位为个位,低4位为小数MOV A,R7JZ TEMPC12 // ;百位为0退出ANL A,#0FH // ;百位不为0即温度为正和十位重新拼装后存入26H,高4位为百位SWAP A // ;MOV R7,AMOV A,26HANL A,#0FH ; // ;去除26H单元的符号ORL A,R7 //;百位和十位拼装,放入26H单元高4位为百位MOV 26H,A // ;低4位为十位TEMPC12:RETDOTTAB:DB 00H,01H,01H,02H,03HDB 03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09HDISPBCD:MOV A,27H // ;BCD码转换ANL A,#0FHMOV 70H,A // ;取小数,并保存在70H中SWAP AANL A,#0FHMOV 71H,A // ;取整数个位,并保存在71H中MOV A,26HANL A,#0FHMOV 72H,A //;取整数十位,并保存在72H中MOV A,26HSWAP AANL A,#0FHMOV 73H,A // ;取整数百位,并保存在73H中MOV A,72H //;取整数十位ANL A,#0F0HCJNE A,#00H,DISPBCD2SJMP DISPBCD2DISPBCD0:MOV A,26H // ;取整数百位ANL A,#0F0HCJNE A,#00H,DISPBCD2 //;百位不等于0退出MOV A,26HSW AP AANL A,#0FH //;十位保留符号MOV 73H,#0AHMOV 72H,ADISPBCD2:RETDISP:MOV R1,#70H // ;显示子程序MOV R5,#11101111B // ;送Y4位码PLAY:MOV P0,#0FFH // ;关段码MOV A,R5 // ;取Yn位码MOV P2,A // ;送位码MOV A,@R1 //;取段码MOV DPTR,#TABMOVC A,@A+DPTRMOV P0,A // ;送段码MOV A,R5JB ACC.5,LOOP1 // ;位码未指向Y2(整数个位)转CLR P0.7 ;;开小数点LOOP1:LCALL DL1MS //;调显示延时INC R1 // ;指向下一位显示段码MOV A,R5 ;取显示位码JNB ACC.7,ENDOUTRL A // ;向下一位位码MOV R5,AAJMP PLAYENDOUT:MOV P0,#0FFHMOV P3,#0FFHRETTAB: DB 0C0H,0F9H,0A4H,0B0HDB 99H,92H,82H,0F8HDB 80H,90H,0FFH,0BFHDL1MS:MOV R6,#14H // ;延时1mS DL1: MOV R7,#19HDL2: DJNZ R7,DL2DJNZ R6,DL1RETEND。
DS18B20原理及程序编写(一)概述DS18B20为单总线12位(二进制)温度读数。
内部有64位唯一的ID编码。
工作电压从3.0~5.5V。
测量温度范围从-55℃~125℃。
最高±0.0625℃分辩率。
其内部结构如下图所示。
DS18B20的核心功能是直接数字温度传感器。
温度传感器可以配置成9、10、11和12位方式。
相应的精度分别为:0.5℃、0.25℃、0.125℃和0.0625℃。
默认的分辨率为12位。
DS18B20在空闲低功耗状态下加电(寄生电源工作方式)。
主机必须发出Convert T [44h]命令使其对测量温度进行A-D转换。
接下来进行采集转换,结果存于两字节高速温度寄存器并返回到空闲低功耗状态。
如果DS18B20在外部VDD供电方式下,单片机可以在发出Convert T 命令并总线为1时(总线为0表示正在转换)发出“read time slots”命令。
DS18B20芯片内部共有8字节的寄存器,其中地址编号0,1为温度寄存器,里面存储着DS18B20温度转换后的AD值,其格式如表1所示。
地址编号2,3为温度报警寄存器,里面为报警设定值,地址编号4为配置寄存器(这三个寄存器在读取之前请使用“重新调入EEPROM”命令将存储在EEPROM里的内容调出,同样,在向温度报警寄存器里写入内容后,也要使用“复制到存储器”命令48H将温度报警寄存器内的内容存入EEPROM当中,以免掉电丢失数据)。
DS18B20内部寄存器映射如下图所示。
配置寄存器的格式如表2和表3所示。
DS18B20内部寄存器映射表1 温度寄存器的格式表2 配置寄存器的格式表3 温度分辨率配置DS18B20使用单总线工作方式,其通信协议以电平的高平时间作为依据,其基本时序有复位时序,写时序、读时序。
//********************************************************************** //** 文件名:DS18B20.c//** 说明:DS18B20驱动程序文件//----------------------------------------------------------------------//** 单位://** 创建人:张雅//** 创建时间:2010-01-20//** 联系方式:QQ:276564402//** 版本:V1.0//----------------------------------------------------------------------//**********************************************************************//----------------------------------------------------------------------//** 芯片:AT89S52//** 时钟:11.0592MHz//** 其它:这个文档为18B20的驱动程序,引用了数码管的驱动。
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内读区数据线上的状态。
基于FS4412的DS18B20温度采集编程实现一、DS18B20简介DS18B20是常用的数字温度计。
DS18B20数字温度计提供9至12位(可配置)温度读数,表明该设备的温度。
信息通过单总线接口被发送到DS18B20或从DS18B20发出,因此从中央微处理器到DS18B20只有需要一个线(和地线)。
读,写和进行温度转换所需要的电源,可以由数据线本身来提供,无需外部电源。
由于每个DS18B20含有唯一的序列号,多个DS18B20可以挂载在一条单总线上。
这允许在许多不同的地方,放置温度传感器。
这个功能是非常有用的,可以应用在包括HV AC环境控制,建筑物内部的温度感应,设备或机械,过程监测和控制等领域。
二、DS18B20硬件连接DS18B20引脚图 DS18B20 原理图DS18B20 有三个引脚。
根据原理图可知,DS18B20采用了外部供电的连接方式,而DQ引脚上拉10k电阻。
DQ引脚连接在4412芯片的GPK1_1 引脚上面。
GND 地DQ 数据线VDD 电源(可选)三、DS18B20时序分析DS18B20是一个单总线,输入和输出都是通过DQ引脚,我们需要根据时序图,不断的操作DQ这个引脚,实现具体的功能。
(一)ds18b20复位时序和函数实现通过复位信号,可以检测DS18B20是否工作正常,并通知DS18B20准备通信。
(1)4412拉低DQ引脚,复位周期开始。
(2)DQ引脚上的低电平保持480us—960us 的时间,然后释放总线。
(3)4412延时16us—60us等待DS18B20应答。
(4)DS18B20拉低DQ引脚60us—240us,表示应答。
4412读取DQ引脚电平,如果是低电平,表示初始化完成。
(5)DS18B20应答信号结束后,释放总线,DQ引脚被上拉电阻拉高,复位周期结束。
实现ds18b20的复位代码:void DS18_Reset(){GPK1.PUD = 0; //GPK1_1 禁止上下拉GPK1.CON = (GPK1.CON & ~(0xF << 4)) | 0x1 << 4; //设置GPK1_1为输出引脚GPK1.DA T &= ~(0x1 << 1); //设置GPK1_1 输出‘0’,拉低DQ引脚delay_us(700); //延时600usGPK1.DA T |= 0x1 << 1; //GPK1_1释放总线GPK1.CON &= ~(0xF << 4); //设置GPK1_1为输入引脚while(GPK1.DA T & (0x1 << 1)); //等待DS18B20应答信号(DQ引脚低电平)while(!(GPK1.DA T & (0x1 << 1))); //等待DS18B20应答信号结束(DQ引脚高电平)}(二)ds18b20写时序和函数实现当我们需要写DS18B20写数据的时候,必须严格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内读区数据线上的状态。
fpga_ds18b20温度传感器手册介绍以及接口代码编写思路DS18B20是一款数字温度传感器,它可以通过一个数据线与FPGA(现场可编程门阵列)进行通信。
以下是一个简单的介绍和接口代码编写思路。
DS18B20温度传感器手册介绍:DS18B20由美国Dallas公司生产,是一种数字温度传感器,具有单总线接口、温度测量范围为-55℃~+125℃、测量精度为±0.5℃等特点。
DS18B20的引脚定义如下:GND:接地;VCC:供电电源,通常为+5V;*DQ:数据线,用于与FPGA进行通信。
DS18B20通过DQ线与FPGA进行通信,通信协议为单总线协议。
在数据传输过程中,DQ线上的信号是低电平有效,每次通信过程都需要严格按照协议进行。
DS18B20的测温原理是利用内部的振荡器产生一个频率与温度成正比的脉冲信号,通过计数器计数来测量温度值。
接口代码编写思路:初始化DS18B20和FPGA的DQ线。
在初始化过程中,需要设置DQ线的输入/输出模式,并确保DQ线处于空闲状态。
发送DS18B20的初始化命令序列。
DS18B20需要先执行一系列初始化命令,包括选择温度分辨率、启动温度转换等。
这些命令可以通过向DQ线发送特定的序列来实现。
等待DS18B20的温度转换完成。
在DS18B20完成温度转换之前,DQ线处于空闲状态。
当温度转换完成后,DS18B20会通过DQ线发送一个低电平信号,表示可以读取温度值。
读取DS18B20的温度值。
通过向DQ线发送读取命令序列,可以读取DS18B20的温度值。
温度值以二进制补码的形式发送,需要通过代码进行解码并转换为实际温度值。
结束通信并释放资源。
在读取完温度值后,需要向DQ线发送一个复位序列来结束通信,并释放相关资源。
在实际编写代码时,需要注意以下几个问题:保证DQ线的稳定性和可靠性,避免因干扰或信号不稳定导致通信失败或数据错误;严格按照DS18B20的通信协议进行数据传输,确保数据正确无误;对读取的温度值进行校验和处理,以避免异常数据对系统造成影响。