|
ds18b20 c程序
//DS1820 C51 子程序 //这里以11.0592M晶体为例,不同的晶体速度可能需要调整延时的时间 //sbit DQ =P2^1;//根据实际情况定义端口
typedef unsigned char byte; typedef unsigned int word;
//延时 void delay(word useconds) { for(;useconds>0;useconds--); }
//复位 byte ow_reset(void) { byte presence; DQ = 0; //pull DQ line low delay(29); // leave it low for 480us DQ = 1; // allow line to return high delay(3); // wait for presence presence = DQ; // get presence signal delay(25); // wait for end of timeslot return(presence); // presence signal returned } // 0=presence, 1 = no part
//从 1-wire 总线上读取一个字节 byte read_byte(void) { byte i; byte value = 0; for (i=8;i>0;i--) { value>>=1; DQ = 0; // pull DQ low to start timeslot DQ = 1; // then return high delay(1); //for (i=0; i<3; i++); if(DQ)value|=0x80; delay(6); // wait for rest of timeslot } return(value); }
//向 1-WIRE 总线上写一个字节 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; }
ds18b20汇编程序:
本汇编程序仅适合单个DS18B20和51单片机的连接,晶振为12MHZ左右 DQ:DS18B20的数据总线接脚 FLAG1:标志位,为"1"时表示检测到DS18B20 TEMPER_NUM:保存读出的温度数据 TEMPER_LEQU36H TEMPER_HEQU35H
DQBITP1.7
; DS18B20初始化汇编程序 ;//*****************************************// INIT_1820: SETBDQ NOP CLRDQ MOVR0,#06BH TSR1: DJNZR0,TSR1; 延时 SETBDQ MOVR0,#25H TSR2: JNBDQ,TSR3 DJNZR0,TSR2 LJMPTSR4; 延时 TSR3: SETBFLAG1; 置标志位,表示DS1820存在 LJMPTSR5 TSR4: CLRFLAG1; 清标志位,表示DS1820不存在 LJMPTSR7 TSR5: MOVR0,#06BH TSR6: DJNZR0,TSR6; 延时 TSR7: SETBDQ RET ;//*****************************************//
; 重新写DS18B20暂存存储器设定值 ;//*****************************************// RE_CONFIG: JBFLAG1,RE_CONFIG1; 若DS18B20存在,转RE_CONFIG1 RET RE_CONFIG1: MOVA,#0CCH; 发SKIP ROM命令 LCALLWRITE_1820 MOVA,#4EH; 发写暂存存储器命令 LCALLWRITE_1820 MOVA,#00H; TH(报警上限)中写入00H LCALLWRITE_1820 MOVA,#00H; TL(报警下限)中写入00H LCALLWRITE_1820 MOVA,#1FH; 选择9位温度分辨率 LCALLWRITE_1820 RET ;//*****************************************//
; 读出转换后的温度值 ;//*****************************************// GET_TEMPER: SETBDQ; 定时入口
LCALLINIT_1820 JBFLAG1,TSS2 RET; 若DS18B20不存在则返回 TSS2: MOVA,#0CCH; 跳过ROM匹配 LCALLWRITE_1820 MOVA,#44H; 发出温度转换命令 LCALLWRITE_1820
LCALLINIT_1820 MOVA,#0CCH; 跳过ROM匹配 LCALLWRITE_1820 MOVA,#0BEH; 发出读温度命令 LCALLWRITE_1820 LCALLREAD_1820 MOVTEMPER_NUM,A; 将读出的温度数据保存 RET ;//*****************************************//
; 读DS18B20的程序,从DS18B20中读出一个字节的数据 ;//*****************************************// READ_1820: MOVR2,#8 RE1: CLRC SETBDQ NOP NOP CLRDQ NOP NOP NOP SETBDQ MOVR3,#7 DJNZR3,$ MOVC,DQ MOVR3,#23 DJNZR3,$ RRCA DJNZR2,RE1 RET ;//*****************************************//
; 写DS18B20的程序 ;//*****************************************// WRITE_1820: MOVR2,#8 CLRC WR1: CLRDQ MOVR3,#6 DJNZR3,$ RRCA MOVDQ,C MOVR3,#23 DJNZR3,$ SETBDQ NOP DJNZR2,WR1 SETBDQ RET ;//*****************************************//
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据 ;//*****************************************// READ_18200: MOVR4,#2; 将温度高位和低位从DS18B20中读出 MOVR1,#36H; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE00: MOVR2,#8 RE01: CLRC SETBDQ NOP NOP CLRDQ NOP NOP NOP SETBDQ MOVR3,#7 DJNZR3,$ MOVC,DQ MOVR3,#23 DJNZR3,$ RRCA DJNZR2,RE01 MOV@R1,A DECR1 DJNZR4,RE00 RET ;//*****************************************//
; 将从DS18B20中读出的温度数据进行转换 ;//*****************************************// TEMPER_COV: MOVA,#0F0H ANLA,TEMPER_L; 舍去温度低位中小数点后的四位温度数值 SWAPA MOVTEMPER_NUM,A MOVA,TEMPER_L JNBACC.3,TEMPER_COV1; 四舍五入去温度值 INCTEMPER_NUM
TEMPER_COV1: MOVA,TEMPER_H ANLA,#07H SWAPA ORLA,TEMPER_NUM MOVTEMPER_NUM,A; 保存变换后的温度数据 LCALLBIN_BCD RET ;//*****************************************//
; 将16进制的温度数据转换成压缩BCD码 ;//*****************************************// BIN_BCD: MOVDPTR,#TEMP_TAB MOVA,TEMPER_NUM MOVCA,@A+DPTR MOVTEMPER_NUM,A RET
TEMP_TAB: DB00H,01H,02H,03H,04H,05H,06H,07H DB08H,09H,10H,11H,12H,13H,14H,15H DB16H,17H,18H,19H,20H,21H,22H,23H DB24H,25H,26H,27H,28H,29H,30H,31H DB32H,33H,34H,35H,36H,37H,38H,39H DB40H,41H,42H,43H,44H,45H,46H,47H DB48H,49H,50H,51H,52H,53H,54H,55H DB56H,57H,58H,59H,60H,61H,62H,63H DB64H,65H,66H,67H,68H,69H,70H ;//*****************************************//
下面还介绍一个ds18b20汇编程序 ;********************************** FLAG1 BIT F0 ;DS18B20存在标志位 DQ BIT P1.7 TEMPER_L EQU 29H TEMPER_H EQU 28H A_BIT EQU 35H B_BIT EQU 36H ;************ds18b20汇编程序起始******************** ORG 0000H AJMP MAIN ORG 0100H ;**************主程序开始************ MAIN: LCALL INIT_18B20 ;LCALL RE_CONFIG LCALL GET_TEMPER AJMP CHANGE
;**********DS18B20复位程序***************** INIT_18B20: SETB DQ NOP CLR DQ MOV R0,#0FBH TSR1: DJNZ R0,TSR1 ;延时 SETB DQ MOV R0,#25H TSR2: JNB DQ ,TSR3 DJNZ R0,TSR2 TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在 CLR P2.0 ;二极管指示 AJMP TSR5 TSR4: CLR FLAG1 LJMP TSR7 TSR5: MOV R0,#06BH TSR6: DJNZ R0,TSR6 TSR7: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 DQ LCALL INIT_18B20 JB FLAG1,TSS2 RET ;若不存在则返回 TSS2: MOV A,#0CCH ;跳过ROM LCALL WRITE_18B20 MOV A,#44H ;发出温度转换命令 LCALL WRITE_18B20
LCALL DISPLAY ;延时 LCALL INIT_18B20 MOV A,#0CCH ;跳过ROM LCALL WRITE_18B20 MOV A,#0BEH ;发出读温度换命令 LCALL WRITE_18B20 LCALL READ2_18B20 ;读两个字节的温度 RET ;***************写ds18b20汇编程序************ WRITE_18B20: MOV R2,#8 CLR C WR1: CLR DQ
MOV R3,#6 DJNZ R3,$ RRC A MOV DQ,C MOV R3,#23 DJNZ R3,$ SETB DQ NOP DJNZ R2,WR1 SETB DQ RET
;***********读18B20程序,读出两个字节的温度********* READ2_18B20: MOV R4,#2 ;低位存在29 H,高位存在28H
MOV R1,#29H RE00: MOV R2,#8 RE01: CLR C SETB C NOP NOP
CLR DQ NOP NOP NOP SETB DQ MOV R3,#7 DJNZ R3,$ MOV C,DQ MOV R3,#23 DJNZ R3,$ RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET ;************读出的温度进行数据转换**************
CHANGE: MOV A,29H MOV C,28H.0 ;将28H中的最低位移入C RRC A MOV C,28H.1 RRC A MOV C,28H.2 RRC A MOV C,28H.3 RRC A MOV 29H,A ;setb p2.0 LCALL DISPLAY ;调用数码管显示子程序
; setb P2.0 LJMP MAIN ;*******************DISPLAY****** DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制 mov b,#10 ;10进制/10=10进制 div ab mov b_bit,a ;十位在a mov a_bit,b ;个位在b mov dptr,#TAB ;指定查表启始地址 mov r0,#4 dpl1: mov r1,#250 ;显示1000次 dplop: mov a,a_bit ;取个位数 MOVC A,@A+DPTR ;查个位数的7段代码 mov p0,a ;送出个位的7段代码 clr p2.5;开个位显示 acall d1ms ;显示1ms setb p2.5 mov a,b_bit ;取十位数 MOVC A,@A+DPTR ;查十位数的7段代码 mov p0,a ;送出十位的7段代码 clr p2.4;开十位显示 acall d1ms ;显示1ms setb p2.4 djnz 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
|