?? ds18b20.asm
字號:
;===========================================================================
;DS18B20與77E58系列單片機的接口程序
;單片機晶振40MHz,機器周期為0.1uS
;此代碼已調試通過。
; 溫度轉換--->....→讀取溫度→CRC校驗→溫度轉換→數據處理→其他服務→
; ↑_________↓_____________________________↓
;===========================================================================
;1 wire 總線DQ
DQ bit P3^5
//DQ1 bit P0^0
;===========================================================================
NAME DS18B20 ;模塊名稱
;===========================================================================
;===========================================================================
;主機對1 wire 設備初始化子程序
;函數原型:bit reset_ds18b20(void)
;返回值Cy:1=設備存在;0=設備不存在
;===========================================================================
?PR?reset_ds18b20?DS18B20 SEGMENT CODE
PUBLIC reset_ds18b20
RSEG ?PR?reset_ds18b20?DS18B20
reset_ds18b20:
clr ea;
clr DQ;
call delay_500uS;
setb DQ;
call delay_90uS;
setb c; 設備存在
jnb DQ,i_ret;
clr c; 設備不存在
ajmp j_ret;
i_ret: call delay_400uS;
// clr DQ1
j_ret: setb ea;
ret
;==============================================================================
;主機向DS18B20寫一個字節數據
;入口:欲寫的數據在A中
;==============================================================================
write_byte:
push psw;
mov r4,#8;
clr c;
w_loop1:
rrc a; 數據的低位先發,后發高位
clr ea;//禁止中斷
jc write1;
clr DQ;
call delay_90uS;
setb DQ;
ajmp w_loop2;
write1: clr DQ;
; mov r7,#1; 恢復時間延時必須大于1uS
; djnz r7,$;
NOP
setb DQ;
call delay_90uS;
w_loop2:setb ea;開中斷
djnz r4,w_loop1;
pop psw;
ret
;==============================================================================
;主機從DS18B20讀取一個字節數據
;出口:數據在A中
;
;===============================================================================
read_byte:
push psw;
mov r4,#8;
clr a
read_loop:
clr ea;禁止中斷
clr DQ;
; mov r7,#1; 拉低總線時間應大于1uS
; djnz r7,$;
NOP
setb DQ;
mov r7,#5; //必須在從拉低總線開始的15uS以內采樣總線
djnz r7,$;
; mov c,DQ;
call DQ_select_responses1
rrc a;
mov r7,#25;延時50uS
djnz r7,$;
;mov r7,#1;3; 恢復時間延時必須大于1uS
;djnz r7,$;
NOP
setb ea;開中斷
djnz r4,read_loop;
pop psw;
ret
DQ_select_responses1:
PUSH acc
mov a,#2
anl a,P0 ;選擇對應的端口
setb c
jz c_next
sjmp c_next1
c_next: clr c
c_next1:
pop acc
ret
;===============================================================================
;讀取ROM序列碼
;函數原型:void read_rom(unsigned char data * buf)
?PR?_read_rom?DS18B20 SEGMENT CODE
PUBLIC _read_rom
RSEG ?PR?_read_rom?DS18B20
_read_rom:
mov a,r7;
mov r0,a;
mov r3,#8;
call reset_ds18b20;
mov a,#33h;
call write_byte;
read: call read_byte;
mov @r0,a;
inc r0;
djnz r3,read;
call reset_ds18b20;
ret
;=================================================================================
;單從設備溫度轉換函數
;函數原型:void temp_conver(void)
;
;=================================================================================
?PR?temp_conver?DS18B20 SEGMENT CODE
PUBLIC temp_conver
RSEG ?PR?temp_conver?DS18B20
temp_conver:
call reset_ds18b20;
mov A,#0cch; //跳躍ROM命令
call write_byte;
mov A,#044h; //溫度轉換命令
call write_byte;
ret
;=================================================================================
;主機讀取單從設備暫存器函數
;函數原型:void read_scrat(unsigned char data * buf,unsigned char n)
;入口:r7(buf):數據緩沖區首址
; R5(n):欲讀取的字節數
;================================================================================
?PR?_read_scrat?DS18B20 SEGMENT CODE
PUBLIC _read_scrat
RSEG ?PR?_read_scrat?DS18B20
_read_scrat:
mov a,r7;
mov r0,a;
mov a,r5;
mov r3,a;
call reset_ds18b20; //
mov A,#0cch; //跳躍ROM命令
call write_byte;
mov A,#0beh; //讀暫存器命令
call write_byte;
r_scrat_loop:
call read_byte;
mov @r0,a;
inc r0;
djnz r3,r_scrat_loop;
call reset_ds18b20;
ret
;================================================================================
;主機寫單從設備的3個暫存器函數
;函數原型:void write_scrat(unsigned char data * buf)
;入口:R7(buf)欲寫數據的首地址
;================================================================================
?PR?_write_scrat?DS18B20 SEGMENT CODE
PUBLIC _write_scrat
RSEG ?PR?_write_scrat?DS18B20
_write_scrat:
mov r3,#3;
mov a,r7;
mov r0,a;
call reset_ds18b20; //
mov a,#0cch; //跳躍ROM命令
call write_byte;
mov a,#04eh; //寫暫存器命令
call write_byte;
w_scrat_loop:
mov a,@r0;
call write_byte;//寫數據
inc r0;
djnz r3,w_scrat_loop;
ret
;===================================================================================
;===================================================================================
;溫度數據(HEX)轉換為8位(4字節)BCD碼
;函數原型:void hextobcd(unsigned char data * source ,unsigned char data * disten)
;入口:source(R7):需轉換數據的首地址指針;disten(R5):轉換后數據保存地址指針
;===================================================================================
?PR?_hextobcd?DS18B20 SEGMENT CODE
PUBLIC _hextobcd
RSEG ?PR?_hextobcd?DS18B20
_hextobcd:
mov a,r7;
mov r0,a;
mov a,r5;
mov r1,a;
mov a,@r0;
mov r5,a;//低字節
inc r0;
mov a,@r0;
mov r7,a;//高字節
call neg;//判負求補
call data_apart;整數與小數分離
call hbcd;//轉換為BCD碼
mov a,r0;//恢復數據指針
mov r7,a;
mov a,r1;
mov r5,a;
ret
;===================================================================================
;===================================================================================
;兩字節HEX數據轉換為兩字節BCD(
;入口:欲轉換的數據在R6R7,R6為整數,R7為小數部分;
; R1=轉換后BCD數據保存首地址
;出口:轉換后的BCD碼首地址在R1中,(R1),(R1)+1為整數部分,(R1)的第7位為數據符號位:1=負數;0=正數
; (R1)+2,(R1)+3為小數部分。
;=================================================================================
hbcd:
;整數部分轉換
mov a,r1;
push acc;
mov a,r6;
mov c,acc.7;
mov F0,c;//暫存符號位
mov b,#100;
div ab;
mov c,F0;
mov acc.7,c;恢復符號位
mov @r1,a;
mov a,#10;
xch a,b;
div ab;
swap a;
orl a,b;
inc r1;
mov @r1,a;
;小數部分BCD碼轉換
clr a;
mov r2,a;
mov r3,a;
mov a,r7;
jnb acc.7,hbcd_1;
mov r2,#50h;
hbcd_1: jnb acc.6,hbcd_2;
mov a,r2;
add a,#25h;
mov r2,a;
mov a,r7;
hbcd_2: jnb acc.5,hbcd_3;
mov a,r2;
add a,#12h;
mov r2,a;
mov r3,#50h;
mov a,r7;
hbcd_3: jnb acc.4,hbcd_4;
mov a,r2;
add a,#06h;
da a;
mov r2,a;
mov a,r3;
add a,#25h;
mov r3,a;
hbcd_4: mov a,r2;
inc r1;
mov @r1,a;
mov a,r3;
inc r1;
mov @r1,a;
pop acc;//恢復數據指針
mov r1,a;
ret
;===================================================================================
;數據求補運算子程序
;入口:R5,R7;R7為高字節
;出口:數據地址不變
;===================================================================================
neg:
mov a,r7;
jnb acc.7,neg_ret;//判斷數據是否是負數,若非負數則直接退出
mov a,r5; //否則求補
cpl a;
clr c;
add a,#1;
mov r5,a;
mov a,r7;
cpl a;
addc a,#0;
setb acc.3;//設置負數標志
mov r7,a;
neg_ret: ret
;==========================================================================================
;整數與小數部分的分離
;入口:數據在R6,R7中,R7為高字節
;出口:分離的整數在R6中,小數在R7中
;=========================================================================================
data_apart:
mov a,r7;//高字節
anl a,#0fh;
swap a;
mov b,a;//
mov a,r5;
anl a,#0f0h;
swap a;
orl a,b;
mov r6,a;//存整數部分
mov a,r5;
anl a,#0fh;
swap a;
mov r7,a;//存小數部分
ret
;=============================================================================================
;CRC校驗
;函數原型:bit tcrc(unsigned char data *buf,unsigned char len)
;入口:數據首址在R7;字節數在R5中
;出口:cy=1數據正確;ACC=0數據不正確,需重新讀取數據
;=============================================================================================
?PR?_tcrc?DS18B20 SEGMENT CODE
PUBLIC _tcrc
RSEG ?PR?_tcrc?DS18B20
_tcrc: ;字節計數單元賦初值
mov r2,#0; 移位寄存器清零
mov a,r7;
mov r0,a;
tcrc2: mov a,@r0;
mov r3,a;
mov r6,#8;移位次數單元賦初值
tcrc3: xrl a,r2;
anl a,#01h;
mov r4,a;
mov a,r2;
clr c;
rrc a;
cjne r4,#1,tcrc4;結果為1進行異或操作
xrl a,#8ch;
tcrc4: mov r2,a;
mov a,r3;
rrc a;
mov r3,a;
djnz r6,tcrc3;
inc r0;
djnz r5,tcrc2;
mov a,r2;
setb c;
jz tcrc5;
clr c;
tcrc5: ret
;=============================================================================================
;單字節BCD碼轉換為單字節HEX
;入口:ACC
;出口:ACC
;=============================================================================================
bcdh: mov b,#10;
div ab;
mov r4,b;
mov b,#10;
mul ab;
add a,r4;
ret;
;============================================================================================
;延時子程序
;===========延時值的計算=================
; mov r5,#x1; //2MC
;loop: mov r6,#x2;//2MC
; djnz r6,$; //2/3MC
; djnz r5,loop;//2/3MC
; ret //2
;time = x1(2/3*x2+2+2/3)/24.5;
;========================================
;;延時大于480u
delay_500uS: ;延時大于480uS
mov r5,#2;
d500_1: mov r6,#130;
djnz r6,$;
djnz r5,d500_1;
ret
delay_90uS:
MOV R5,#2;
d90_1: mov r6,#20;
DJNZ R6,$;
; jnb DQ,i_rett;
djnz R5,d90_1;
; ajmp i_rett1
;i_rett:nop
; clr DQ1;
;i_rett1:
ret
delay_400uS:
mov r5,#2;
d400_1: mov r6,#100;
djnz r6,$;
djnz r5,d400_1;
ret
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -