怎么用arduino单片机模拟一个ds18s20(ds1820)的信号
答案:1 悬赏:40 手机版
解决时间 2021-04-02 13:58
- 提问者网友:咪咪
- 2021-04-01 19:55
怎么用arduino单片机模拟一个ds18s20(ds1820)的信号
最佳答案
- 五星知识达人网友:酒者煙囻
- 2021-04-01 21:25
他靠单线端口通讯,就是它只需要一根线和单片机连接,剩下两根分别接电源正极和负极。
编程如下:
先使用一段汇编语言,将其保存为ds.asm
DSSP SEGMENT CODE ;程序段
PUBLIC DSS ;入口地址,跳转到DL标号处执行汇编程序
RSEG DSSP ;程序段
IN EQU P1.6
FLAG1 EQU 05H ;DS18B20器件存在标志
TTL EQU 07H ;温度读出值(高位在TTL-1中,低位在TTL中)
;-------------------------------------------DS18B20读数据程序(0~99度)
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB IN
NOP
CLR IN
;主机发出延时537微秒的复位低脉冲
MOV R1,#18;#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB IN;然后拉高数据线
NOP
NOP
NOP
NOP;12倍
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV R0,#0DEH;#25H
TSR2:
JNB IN,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R7,#6
TSR6:
MOV R0,#117
DJNZ R0,$ ; 时序要求延时一段时间 */
DJNZ R7,TSR6 ; 时序要求延时一段时间 */
TSR7:
SETB IN
RET
;------------------------------------------读出转换后的温度值
DSS:
DS1820PRO:
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
SETB IN
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
jmp BCD33 ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
CALL DL1MS
SETB IN
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200; 将读出的温度数据保存到35H/36H
MOV A,TTL
MOV B,TTL-1
MOV C,B.0;将28H中的最低位移入C
RRC A
MOV C,B.1
RRC A
MOV C,B.2
RRC A
MOV C,B.3
RRC A
MOV TTL,A
BCD33:
JB FLAG1,BCD44
mov R7,#0FFH
JMP TORET
BCD44:
MOV R7,TTL
TORET:
RET
;--------------------------------写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR IN
MOV R3,#36;#6
DJNZ R3,$
RRC A
MOV IN,C
MOV R3,#192;#23
DJNZ R3,$
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,WR1
SETB IN
RET
;-----------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TTL ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB IN
MOV R3,#54;#9
RE10:
DJNZ R3,RE10
MOV C,IN
MOV R3,#138;#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
DL1MS:
MOV R7,#6
DL1MS2:
MOV R6,#255
DJNZ R6,$
DJNZ R7,DL1MS2
RET
END
然后可以这样在C语言中调用(在Keil中,且主程序文件与ds.asm放于同一文件夹内,以下是配合带中文字符库的128×64LCD显示屏,完整程序Hi我)
sbit DQ = P1 ^ 6; //DS18B20温度传感器定义
unsigned char DSS (void); //汇编语言读18B20温度程序声明
i = DSS();//将DSS汇编程序取得的温度值放入温度寄存器变量
if(i < 60){//读不出温度数据时不显示温度字样
lcm_w_test(0,0x9C); //温度在LCM上的写入位置
lcm_w_word("温度"); //度C
lcm_w_test(1,i/10+0x30); //显示温度十位
lcm_w_test(1,i%10+0x30); //个位
lcm_w_word("℃"); //度C
}
}追问我是想模拟一个一样的信号发出,而不是读取信号,比如我在1602上输入25,然后发出一个25的温度信号,谢谢,可以继续加分
编程如下:
先使用一段汇编语言,将其保存为ds.asm
DSSP SEGMENT CODE ;程序段
PUBLIC DSS ;入口地址,跳转到DL标号处执行汇编程序
RSEG DSSP ;程序段
IN EQU P1.6
FLAG1 EQU 05H ;DS18B20器件存在标志
TTL EQU 07H ;温度读出值(高位在TTL-1中,低位在TTL中)
;-------------------------------------------DS18B20读数据程序(0~99度)
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB IN
NOP
CLR IN
;主机发出延时537微秒的复位低脉冲
MOV R1,#18;#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB IN;然后拉高数据线
NOP
NOP
NOP
NOP;12倍
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV R0,#0DEH;#25H
TSR2:
JNB IN,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R7,#6
TSR6:
MOV R0,#117
DJNZ R0,$ ; 时序要求延时一段时间 */
DJNZ R7,TSR6 ; 时序要求延时一段时间 */
TSR7:
SETB IN
RET
;------------------------------------------读出转换后的温度值
DSS:
DS1820PRO:
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
SETB IN
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
jmp BCD33 ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
CALL DL1MS
SETB IN
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200; 将读出的温度数据保存到35H/36H
MOV A,TTL
MOV B,TTL-1
MOV C,B.0;将28H中的最低位移入C
RRC A
MOV C,B.1
RRC A
MOV C,B.2
RRC A
MOV C,B.3
RRC A
MOV TTL,A
BCD33:
JB FLAG1,BCD44
mov R7,#0FFH
JMP TORET
BCD44:
MOV R7,TTL
TORET:
RET
;--------------------------------写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR IN
MOV R3,#36;#6
DJNZ R3,$
RRC A
MOV IN,C
MOV R3,#192;#23
DJNZ R3,$
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,WR1
SETB IN
RET
;-----------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TTL ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB IN
MOV R3,#54;#9
RE10:
DJNZ R3,RE10
MOV C,IN
MOV R3,#138;#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
DL1MS:
MOV R7,#6
DL1MS2:
MOV R6,#255
DJNZ R6,$
DJNZ R7,DL1MS2
RET
END
然后可以这样在C语言中调用(在Keil中,且主程序文件与ds.asm放于同一文件夹内,以下是配合带中文字符库的128×64LCD显示屏,完整程序Hi我)
sbit DQ = P1 ^ 6; //DS18B20温度传感器定义
unsigned char DSS (void); //汇编语言读18B20温度程序声明
i = DSS();//将DSS汇编程序取得的温度值放入温度寄存器变量
if(i < 60){//读不出温度数据时不显示温度字样
lcm_w_test(0,0x9C); //温度在LCM上的写入位置
lcm_w_word("温度"); //度C
lcm_w_test(1,i/10+0x30); //显示温度十位
lcm_w_test(1,i%10+0x30); //个位
lcm_w_word("℃"); //度C
}
}追问我是想模拟一个一样的信号发出,而不是读取信号,比如我在1602上输入25,然后发出一个25的温度信号,谢谢,可以继续加分
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯