一个usb系统,其控制芯片的程序是C写的,现在想加入温度传感器,已有现成的汇编代码(伟纳ME300A+产品提供)
代码就三个函数,reset,write,read。分别是没有参数和返回值、有参数没返回值、无参数有返回值。为了研究相应的C函数的结构,可以编译一个C程序看看
用Keil 的c51编译
c51 test.c
可以得到一个TEST.SRC的文件
NAME THERMOMETER
?PR?ds18b20_reset?THERMOMETER SEGMENT CODE
?PR?_ds18b20_write?THERMOMETER SEGMENT CODE
?DT?_ds18b20_write?THERMOMETER SEGMENT DATA OVERLAYABLE
?PR?ds18b20_read?THERMOMETER SEGMENT CODE
?DT?ds18b20_read?THERMOMETER SEGMENT DATA OVERLAYABLE
PUBLIC ds18b20_read
PUBLIC _ds18b20_write
PUBLIC ds18b20_reset
RSEG ?DT?ds18b20_read?THERMOMETER
?ds18b20_read?BYTE:
nTpr?241: DS 2
RSEG ?DT?_ds18b20_write?THERMOMETER
?_ds18b20_write?BYTE:
sz?140: DS 1
; #pragma SRC
; void ds18b20_reset()
RSEG ?PR?ds18b20_reset?THERMOMETER
ds18b20_reset:
; SOURCE LINE # 2
; {
; SOURCE LINE # 3
;
; }
; SOURCE LINE # 5
RET
; END OF ds18b20_reset
; void ds18b20_write( char sz)
RSEG ?PR?_ds18b20_write?THERMOMETER
_ds18b20_write:
; SOURCE LINE # 6
MOV sz?140,R7
; {
; SOURCE LINE # 7
;
; }
; SOURCE LINE # 9
RET
; END OF _ds18b20_write
; int ds18b20_read( )
RSEG ?PR?ds18b20_read?THERMOMETER
ds18b20_read:
USING 0
; SOURCE LINE # 10
; {
; SOURCE LINE # 11
; int nTpr;
; return nTpr;
; SOURCE LINE # 13
MOV R6,nTpr?241
MOV R7,nTpr?241+01H
; } ; SOURCE LINE # 14
?C0003:
RET
; END OF ds18b20_read
END
其中write函数用下划线前缀做了修饰,表示函数将通过寄存器传递参数。
最后给出改造后可以用与c程序的ds18b20代码:
; thermometer.SRC generated from: thermometer.c
; COMPILER INVOKED BY:
; D:\Keil\C51\BIN\c51.exe thermometer.c
NAME THERMOMETER
DATE_LINE EQU P1.4 ;接到ds18b20数据线引脚
?PR?ds18b20_reset?THERMOMETER SEGMENT CODE
?PR?_ds18b20_write?THERMOMETER SEGMENT CODE
;?DT?_ds18b20_write?THERMOMETER SEGMENT DATA OVERLAYABLE
?PR?ds18b20_read?THERMOMETER SEGMENT CODE
?DT?ds18b20_read?THERMOMETER SEGMENT DATA OVERLAYABLE
PUBLIC ds18b20_read
PUBLIC _ds18b20_write
PUBLIC ds18b20_reset
;RSEG ?DT?_ds18b20_write?THERMOMETER
;?_ds18b20_write?BYTE:
; sz?140: DS 1
RSEG ?DT?ds18b20_read?THERMOMETER
?ds18b20_read?BYTE:
nTpr?241: DS 2
; #pragma SRC
; void ds18b20_reset()
RSEG ?PR?ds18b20_reset?THERMOMETER
ds18b20_reset:
; SOURCE LINE # 2
; {
SETB DATE_LINE
NOP
CLR DATE_LINE
MOV R0,#0D6H ;主机发出延时642微秒的复位低脉冲
MOV R1,#03H
TSR1: DJNZ R0,$
MOV R0,#0D6H
DJNZ R1,TSR1
SETB DATE_LINE ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#4AH
TSR2: JNB DATE_LINE,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
JMP TSR4 ; 延时
TSR3: SETB c ; 置标志位,表示DS1820存在
JMP TSR5
TSR4: CLR c ; 清标志位,表示DS1820不存在
JMP TSR7
TSR5: MOV R0,#06BH
TSR6: DJNZ R0,$ ; 时序要求延时一段时间
TSR7: SETB DATE_LINE
;
; }
; SOURCE LINE # 5
RET
; END OF ds18b20_reset
; void ds18b20_write( char sz)
RSEG ?PR?_ds18b20_write?THERMOMETER
_ds18b20_write:
; SOURCE LINE # 6
MOV a,R7
; {
MOV R2,#8 ;一共8位数据
CLR CY
WR1:
CLR DATE_LINE ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#10
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV DATE_LINE,C ;写入一个BIT
MOV R3,#2EH
DJNZ R3,$ ;等待46微妙
SETB DATE_LINE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DATE_LINE;
; }
; SOURCE LINE # 9
RET
; END OF _ds18b20_write
; int ds18b20_read( )
RSEG ?PR?ds18b20_read?THERMOMETER
ds18b20_read:
USING 0
; SOURCE LINE # 10
; {
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#nTpr?241 ; 存入26H 27H
RE00: MOV R2,#8
RE01: CLR CY
SETB DATE_LINE
NOP
NOP
CLR DATE_LINE ;读前总线保持为低
NOP
NOP
NOP
SETB DATE_LINE ;开始读总线释放
MOV R3,#18 ;延时18微妙
DJNZ R3,$
MOV C,DATE_LINE ;从DS18B20总线读得一个BIT
MOV R3,#46
DJNZ R3,$ ;等待46微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00;
MOV R6,nTpr?241
MOV R7,nTpr?241+01H
;} ; SOURCE LINE # 13
RET
; END OF ds18b20_read
END
TEMPL DATA 26H
TEMPH DATA 27H
FLAG1 EQU 38H ;是否有ds18b20
DATE_LINE EQU P3.6 ;接到ds18b20数据线引脚
;**************************************************
ORG 0000H
MAIN: MOV SP,#30H
START: CALL RESET
SETB P3.2
CALL RESET
JNB FLAG1,MAIN
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#044H ; 发出温度转换命令
CALL WRITE
CALL RESET
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#0BEH ; 发出读温度命令
CALL WRITE
CALL READ ; 将读出的温度数据保存到26H/27H
;CALL CONVTEMP
;CALL DISPBCD
;CALL DISP1
JMP MAIN
;*************************************************
RESET: SETB DATE_LINE
NOP
CLR DATE_LINE
MOV R0,#0D6H ;主机发出延时642微秒的复位低脉冲
MOV R1,#03H
TSR1: DJNZ R0,$
MOV R0,#0D6H
DJNZ R1,TSR1
SETB DATE_LINE ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#4AH
TSR2: JNB DATE_LINE,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
JMP TSR4 ; 延时
TSR3: SETB FLAG1 ; 置标志位,表示DS1820存在
JMP TSR5
TSR4: CLR FLAG1 ; 清标志位,表示DS1820不存在
JMP TSR7
TSR5: MOV R0,#06BH
TSR6: DJNZ R0,$ ; 时序要求延时一段时间
TSR7: SETB DATE_LINE
RET
;********************************************************************
WRITE: MOV R2,#8 ;一共8位数据
CLR CY
WR1:
CLR DATE_LINE ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#10
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV DATE_LINE,C ;写入一个BIT
MOV R3,#2EH
DJNZ R3,$ ;等待46微妙
SETB DATE_LINE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DATE_LINE
RET
;******************************************************
READ: MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#26H ; 存入26H 27H
RE00: MOV R2,#8
RE01: CLR CY
SETB DATE_LINE
NOP
NOP
CLR DATE_LINE ;读前总线保持为低
NOP
NOP
NOP
SETB DATE_LINE ;开始读总线释放
MOV R3,#18 ;延时18微妙
DJNZ R3,$
MOV C,DATE_LINE ;从DS18B20总线读得一个BIT
MOV R3,#46
DJNZ R3,$ ;等待46微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
END
TEMPH DATA 27H
FLAG1 EQU 38H ;是否有ds18b20
DATE_LINE EQU P3.6 ;接到ds18b20数据线引脚
;**************************************************
ORG 0000H
MAIN: MOV SP,#30H
START: CALL RESET
SETB P3.2
CALL RESET
JNB FLAG1,MAIN
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#044H ; 发出温度转换命令
CALL WRITE
CALL RESET
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#0BEH ; 发出读温度命令
CALL WRITE
CALL READ ; 将读出的温度数据保存到26H/27H
;CALL CONVTEMP
;CALL DISPBCD
;CALL DISP1
JMP MAIN
;*************************************************
RESET: SETB DATE_LINE
NOP
CLR DATE_LINE
MOV R0,#0D6H ;主机发出延时642微秒的复位低脉冲
MOV R1,#03H
TSR1: DJNZ R0,$
MOV R0,#0D6H
DJNZ R1,TSR1
SETB DATE_LINE ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#4AH
TSR2: JNB DATE_LINE,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
JMP TSR4 ; 延时
TSR3: SETB FLAG1 ; 置标志位,表示DS1820存在
JMP TSR5
TSR4: CLR FLAG1 ; 清标志位,表示DS1820不存在
JMP TSR7
TSR5: MOV R0,#06BH
TSR6: DJNZ R0,$ ; 时序要求延时一段时间
TSR7: SETB DATE_LINE
RET
;********************************************************************
WRITE: MOV R2,#8 ;一共8位数据
CLR CY
WR1:
CLR DATE_LINE ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#10
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV DATE_LINE,C ;写入一个BIT
MOV R3,#2EH
DJNZ R3,$ ;等待46微妙
SETB DATE_LINE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DATE_LINE
RET
;******************************************************
READ: MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#26H ; 存入26H 27H
RE00: MOV R2,#8
RE01: CLR CY
SETB DATE_LINE
NOP
NOP
CLR DATE_LINE ;读前总线保持为低
NOP
NOP
NOP
SETB DATE_LINE ;开始读总线释放
MOV R3,#18 ;延时18微妙
DJNZ R3,$
MOV C,DATE_LINE ;从DS18B20总线读得一个BIT
MOV R3,#46
DJNZ R3,$ ;等待46微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
END
代码就三个函数,reset,write,read。分别是没有参数和返回值、有参数没返回值、无参数有返回值。为了研究相应的C函数的结构,可以编译一个C程序看看
#pragma SRC
void ds18b20_reset()
{
}
void ds18b20_write( char sz)
{
}
int ds18b20_read( )
{
int nTpr;
return nTpr;
}
void ds18b20_reset()
{
}
void ds18b20_write( char sz)
{
}
int ds18b20_read( )
{
int nTpr;
return nTpr;
}
用Keil 的c51编译
c51 test.c
可以得到一个TEST.SRC的文件
; thermometer.SRC generated from: thermometer.c
; COMPILER INVOKED BY:
; D:\Keil\C51\BIN\c51.exe thermometer.c
; COMPILER INVOKED BY:
; D:\Keil\C51\BIN\c51.exe thermometer.c
NAME THERMOMETER
?PR?ds18b20_reset?THERMOMETER SEGMENT CODE
?PR?_ds18b20_write?THERMOMETER SEGMENT CODE
?DT?_ds18b20_write?THERMOMETER SEGMENT DATA OVERLAYABLE
?PR?ds18b20_read?THERMOMETER SEGMENT CODE
?DT?ds18b20_read?THERMOMETER SEGMENT DATA OVERLAYABLE
PUBLIC ds18b20_read
PUBLIC _ds18b20_write
PUBLIC ds18b20_reset
RSEG ?DT?ds18b20_read?THERMOMETER
?ds18b20_read?BYTE:
nTpr?241: DS 2
RSEG ?DT?_ds18b20_write?THERMOMETER
?_ds18b20_write?BYTE:
sz?140: DS 1
; #pragma SRC
; void ds18b20_reset()
RSEG ?PR?ds18b20_reset?THERMOMETER
ds18b20_reset:
; SOURCE LINE # 2
; {
; SOURCE LINE # 3
;
; }
; SOURCE LINE # 5
RET
; END OF ds18b20_reset
; void ds18b20_write( char sz)
RSEG ?PR?_ds18b20_write?THERMOMETER
_ds18b20_write:
; SOURCE LINE # 6
MOV sz?140,R7
; {
; SOURCE LINE # 7
;
; }
; SOURCE LINE # 9
RET
; END OF _ds18b20_write
; int ds18b20_read( )
RSEG ?PR?ds18b20_read?THERMOMETER
ds18b20_read:
USING 0
; SOURCE LINE # 10
; {
; SOURCE LINE # 11
; int nTpr;
; return nTpr;
; SOURCE LINE # 13
MOV R6,nTpr?241
MOV R7,nTpr?241+01H
; } ; SOURCE LINE # 14
?C0003:
RET
; END OF ds18b20_read
END
其中write函数用下划线前缀做了修饰,表示函数将通过寄存器传递参数。
最后给出改造后可以用与c程序的ds18b20代码:
; thermometer.SRC generated from: thermometer.c
; COMPILER INVOKED BY:
; D:\Keil\C51\BIN\c51.exe thermometer.c
NAME THERMOMETER
DATE_LINE EQU P1.4 ;接到ds18b20数据线引脚
?PR?ds18b20_reset?THERMOMETER SEGMENT CODE
?PR?_ds18b20_write?THERMOMETER SEGMENT CODE
;?DT?_ds18b20_write?THERMOMETER SEGMENT DATA OVERLAYABLE
?PR?ds18b20_read?THERMOMETER SEGMENT CODE
?DT?ds18b20_read?THERMOMETER SEGMENT DATA OVERLAYABLE
PUBLIC ds18b20_read
PUBLIC _ds18b20_write
PUBLIC ds18b20_reset
;RSEG ?DT?_ds18b20_write?THERMOMETER
;?_ds18b20_write?BYTE:
; sz?140: DS 1
RSEG ?DT?ds18b20_read?THERMOMETER
?ds18b20_read?BYTE:
nTpr?241: DS 2
; #pragma SRC
; void ds18b20_reset()
RSEG ?PR?ds18b20_reset?THERMOMETER
ds18b20_reset:
; SOURCE LINE # 2
; {
SETB DATE_LINE
NOP
CLR DATE_LINE
MOV R0,#0D6H ;主机发出延时642微秒的复位低脉冲
MOV R1,#03H
TSR1: DJNZ R0,$
MOV R0,#0D6H
DJNZ R1,TSR1
SETB DATE_LINE ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#4AH
TSR2: JNB DATE_LINE,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
JMP TSR4 ; 延时
TSR3: SETB c ; 置标志位,表示DS1820存在
JMP TSR5
TSR4: CLR c ; 清标志位,表示DS1820不存在
JMP TSR7
TSR5: MOV R0,#06BH
TSR6: DJNZ R0,$ ; 时序要求延时一段时间
TSR7: SETB DATE_LINE
;
; }
; SOURCE LINE # 5
RET
; END OF ds18b20_reset
; void ds18b20_write( char sz)
RSEG ?PR?_ds18b20_write?THERMOMETER
_ds18b20_write:
; SOURCE LINE # 6
MOV a,R7
; {
MOV R2,#8 ;一共8位数据
CLR CY
WR1:
CLR DATE_LINE ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#10
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV DATE_LINE,C ;写入一个BIT
MOV R3,#2EH
DJNZ R3,$ ;等待46微妙
SETB DATE_LINE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DATE_LINE;
; }
; SOURCE LINE # 9
RET
; END OF _ds18b20_write
; int ds18b20_read( )
RSEG ?PR?ds18b20_read?THERMOMETER
ds18b20_read:
USING 0
; SOURCE LINE # 10
; {
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#nTpr?241 ; 存入26H 27H
RE00: MOV R2,#8
RE01: CLR CY
SETB DATE_LINE
NOP
NOP
CLR DATE_LINE ;读前总线保持为低
NOP
NOP
NOP
SETB DATE_LINE ;开始读总线释放
MOV R3,#18 ;延时18微妙
DJNZ R3,$
MOV C,DATE_LINE ;从DS18B20总线读得一个BIT
MOV R3,#46
DJNZ R3,$ ;等待46微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00;
MOV R6,nTpr?241
MOV R7,nTpr?241+01H
;} ; SOURCE LINE # 13
RET
; END OF ds18b20_read
END
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/1532/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
评论列表