使用8086汇编驱动SHT11传感器
前言:使用Proteus 7.8仿真软件实现8086接入SHT11温湿度传感器(实现读取温度数据部分功能),并学习如何在没有集成硬件控制下串行总线的驱动方式,汇编的精髓就是寄存器的操作、各种寻址方式、位操作、对内存和栈的理解。
本文参考博客:
https://www.cnblogs.com/zhaoming510/p/3935248.html
关于串行总线通信协议,推荐比较好的帖子:
http://m.elecfans.com/article/574049.html
一、电路连接:
首先按照如图所示的电路实现8086最小系统和SHT11驱动与显示电路(一片8255a):
二、数据手册关键信息提取:
说明一下,从SHT11读取的信息并不能直接得到温度信息,还要经过公式转换,校验的工作也比较复杂,所以这里就省略了。
1、SHT11电路连接:SHT11接口类似与IIC,硬件是可以兼容的,但是协议不兼容
2、SHT11启动时序:SHT11启动时序比IIC的START信号要复杂的多了
3、SHT11命令集:这里我们只要温度测量的命令也就是00011
4、直接复位的时序,每次读取完数据还要读CRC-8 Checksum,这个就有点麻烦了,仿真软件基本可以确保数据有效性,但实际中校验还是有必要的。
5、手册中推荐的工作时序:我们直接用上图的重启时序跳过Checksum,注意这里有主机要接受ACK信号,程序里没有体现出来,但这里处理一下比较好
三、编写代码:
经验总结:
1、结合时序图,可以先写小段程序验证一下,看是否能够得到想要的波形,这里需要用到虚拟示波器。
2、实现数据到波形或者波形到数据需要灵活运用位操作。
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;
3 ;;;;程序功能 :8086 驱动SHT11温湿传感器 (用I/O口对串行总线时序进行模拟)
4 ;
5 ;;;;传感器接入 :SCK 时钟信号(8255A PC0) DATA 数据信号(接8255A PC4) (与IIC总线时序的SCL、SDL不兼容)
6 ;
7 ;;;;运行模式 :12BIT数据读取(忽略CRC-8校验和、通讯复位命令截断)
8 ;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
11 IOY0 EQU 0C400H ;片选IOY0对应的端口始地址 0000 11000 1000 0000 0000 (A15,A14,A10=1)
12 IOY1 EQU 0C440H
13
14 IOA EQU IOY0+00H*4 ;8255的A口地址
15 IOB EQU IOY0+01H*4 ;8255的B口地址
16 IOC EQU IOY0+02H*4 ;8255的C口地址
17 CTRL EQU IOY0+03H*4 ;8255的控制寄存器地址
18
19 RH EQU 00000101B ;SHT11命令字
20
21 CODE SEGMENT
22 ASSUME CS:CODE,DS:CODE ;代码段定义
23
24 START: MOV AX,CODE
25 MOV DS,AX
26 LEA SP,SEGTAB ;取出偏移地址放入栈顶指针寄存器(使用栈)
27
28 MOV SI,5000H ;在缓存区(内存) 用于保存待显示在数码管上的信息
29 MOV WORD PTR [SI], 0AH
30 MOV WORD PTR [SI+2],0AH
31 MOV WORD PTR [SI+4],0AH
32 MOV WORD PTR [SI+6],0AH
33
34 MOV AL,10000000B ;C口输出
35 MOV DX,CTRL
36 OUT DX,AL
37 DISP:
38 CALL DALLY ;显示信息
39
40 CALL INIT_SHT11 ;SHT11启动时序
41
42 CALL WRITE_CW ;写入命令字
43 CALL ACK_CW ;传感器(SHT11)应答
44
45 CALL DALLY
46
47 CALL WAIT_DATA ;等待数据产生
48 CALL READ_DATA_H ;读取高4(8)位
49 CALL ACK_READ ;CPU(8086)应答
50 CALL READ_DATA_L ;读取低8位
51
52 CALL DALLY
53
54 CALL RESTART_SHT11 ;发送重连信号
56 CALL SEG_LED_DATA ;数据处理
57
58 JMP DISP
59
60 DALLY PROC NEAR ;软件延时子程序
61 CALL CLEAR
62 CALL DIS
63 PUSH CX
64 MOV CX,000FH
65 D1: MOV AX,000FH
66 D2: DEC AX
67 JNZ D2
68 LOOP D1
69 POP CX
70 RET
71 DALLY ENDP
72
73 CLEAR PROC NEAR ;清除数码管显示子程序
74 MOV DX,IOB ;段位置0即可清除数码管显示
75 MOV AL,00H
76 OUT DX,AL
77 RET
78 CLEAR ENDP
79
80 DIS PROC NEAR ;显示键值子程序
81 PUSH AX
82 PUSH SI
83 MOV SI,5006H
84 MOV DL,0F7H
85 MOV AL,DL
86 AGAIN: PUSH DX
87 MOV DX,IOA
88 OUT DX,AL ;设置X1~X4,选通一个数码管
89 MOV AL,[SI] ;取出缓冲区中存放键值
90 MOV BX,OFFSET SEGTAB
91 AND AX,00FFH
92 ADD BX,AX
93 MOV AL,[BX]
94 MOV DX,IOB
95 OUT DX,AL ;写入数码管A~DP
96 CALL DALLY1
97 DEC SI
98 DEC SI ;取下一个键值
99 POP DX
100 MOV AL,DL
101 TEST AL,01H ;判断是否显示完?
102 JZ OUT1 ;显示完,返回
103 ROR AL,1
104 MOV DL,AL
105 JMP AGAIN ;未显示完,跳回继续
106 OUT1: POP SI
107 POP AX
108 RET
109 DIS ENDP
110
111 DALLY1 PROC NEAR ;软件延时子程序
112 PUSH CX
113 MOV CX,002FH
114 D3: MOV AX,002FH
115 D4: DEC AX
116 JNZ D4
117 LOOP D3
118 POP CX
119 RET
120 DALLY1 ENDP
121
122
123 INIT_SHT11 PROC NEAR ;启动时序生成
124
125 MOV DX,IOC
126 MOV AL,11H
127 OUT DX,AL
128
129 MOV AL,01H
130 OUT DX,AL
131
132 MOV AL,00H
133 OUT DX,AL
134
135 MOV AL,01H
136 OUT DX,AL
137
138 MOV AL,11H
139 OUT DX,AL
140
141 MOV AL,10H
142 OUT DX,AL
143
144 RET
145
146 INIT_SHT11 ENDP
147
148 WRITE_CW PROC NEAR ;(手动加精)发送控制字
149
150 MOV CX,08
151 MOV DX,IOC
152 MOV BL,RH
153 LP0:
154 SHL BL,1
155 MOV AL,00H
156 JNC EXIT0
157 MOV AL,10H
158 EXIT0:
159 OUT DX,AL
160
161 AND AL,10H
162 OUT DX,AL ;写完1位数据将时钟线拉低,等待发送
163
164 OR AL,01H
165 OUT DX,AL ;时钟线上升沿,发送1位数据
166 ;等待1位数据发送完成
167 LOOP LP0
168
169 RET
170
171 WRITE_CW ENDP
172
173 ACK_CW PROC NEAR ;写入控制字后SHT11发送应答型号
174 ;C口高四位输入,C口低四位输出
175 MOV AL,10001000B
176 MOV DX,CTRL
177 OUT DX,AL
178
179 MOV DX,IOC
180
181 MOV AL,10H
182 OUT DX,AL ;8位数据发送完成,DATA线拉高
183
184 MOV AL,11H ;时钟线拉高
185 OUT DX,AL
186
187 MOV AL,10H
188 OUT DX,AL ;数据线拉高,时钟线拉低,等待转换完成
189
190 RET
191
192 ACK_CW ENDP
193
194 WAIT_DATA PROC NEAR
195
196 MOV DX,IOC
197 R:
198 IN AL,DX
199 TEST AL,10H ;等待数据线被拉低
200 JNZ R
201
202 RET
203
204 WAIT_DATA ENDP
205
206 READ_DATA_H PROC NEAR ;读取高4(8)位
207
208 MOV CX,08
209 MOV DX,IOC
210 LP1:
211 MOV AL,01H
212 OUT DX,AL ;时钟上升沿后,读取数据线
213
214 IN AL,DX
215 TEST AL,10H ;数据有效位C4
216 MOV AL,0
217 JZ EXIT1
218 INC AL
219 EXIT1:
220 DEC CL
221 SHL AL,CL
222 ADD DATA_H,AL
223 INC CL
224
225 MOV AL,00H ;时钟下降沿
226 OUT DX,AL
227 OUT DX,AL
228 OUT DX,AL ;维持低电平
229
230 LOOP LP1
231
232 RET
233
234 READ_DATA_H ENDP
235
236
237 ACK_READ PROC NEAR ;CPU(8086)应答
238
239 MOV AL,10000000B ;C口输出
240 MOV DX,CTRL
241 OUT DX,AL
242
243 MOV DX,IOC
244
245 MOV AL,00H
246 OUT DX,AL
247
248 MOV AL,01H ;数据线拉低,时钟线拉高才生应答信号
249 OUT DX,AL
250 OUT DX,AL
251 OUT DX,AL
252
253 MOV AL,00H
254 OUT DX,AL
255
256 MOV AL,10001000B ;C口高四位输入,C口低四位输出
257 MOV DX,CTRL
258 OUT DX,AL
259 RET
260
261 ACK_READ ENDP
262
263 READ_DATA_L PROC NEAR ;读取低8位
264
265 MOV CX,08
266 MOV DX,IOC
267 LP2:
268 MOV AL,01H
269 OUT DX,AL
270
271 IN AL,DX
272 TEST AL,10H
273 MOV AL,0
274 JZ EXIT2
275 INC AL
276 EXIT2:
277 DEC CL
278 SHL AL,CL
279 ADD DATA_L,AL
280 INC CL
281
282 MOV AL,00H
283 OUT DX,AL
284 OUT DX,AL
285 OUT DX,AL
286 LOOP LP2
287
288 RET
289
290 READ_DATA_L ENDP
291
292 RESTART_SHT11 PROC NEAR
293
294 MOV AL,10000000B ;C口输出
295 MOV DX,CTRL
296 OUT DX,AL
297
298 MOV DX,IOC
299 MOV CX,9
300 LP3:
301 MOV AL,10H
302 OUT DX,AL
303
304 MOV AL,11H
305 OUT DX,AL ;数据线保持高电平,时钟9次触发以复位串口
306
307 LOOP LP3
308
309 RET
310
311 RESTART_SHT11 ENDP
312
313 SEG_LED_DATA PROC NEAR
314
315 MOV AH,DATA_H
316 MOV AL,DATA_L
317
318 MOV CX,4
319 MOV BX,10
320 MOV SI,5006H
321 LP4:
322 XOR DX,DX
323 DIV BX
324
325 MOV [SI],DL
326 DEC SI
327 DEC SI
328
329 LOOP LP4
330
331 MOV DATA_H,0
332 MOV DATA_L,0
333
334 RET
335
336 SEG_LED_DATA ENDP
337
338 DW 256 DUP(?)
339 SEGTAB DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
340
341 DATA_H DB 00H
342 DATA_L DB 00H
343 DATA_T DB 01H
344 DATA_S DW 0000H
345
346 CODE ENDS
347 END START
运行效果:
由于8086不支持浮点运算,对应的数据可以通过手册的公式和表格另行计算:
使用8086汇编驱动SHT11传感器的更多相关文章
- 【8086汇编-Day1】预备知识
菜鸟的8086汇编入门之旅,偶有错处恭请大佬们指正. Ⅰ· 闲说一下 我为什么学汇编?相对于晦涩难懂的01010101011010机器语言(高低电平变化驱动机器做出不同反应),汇编语言用更便于记忆和使 ...
- 8086汇编——Introduction(8086内部寄存器,段寄存器,存储器分段)
8086汇编--Introduction 一.8086CPU的三种工作模式 实模式:只有低20位地址线起作用,仅能寻址第一个1MB的内存空间.MS DOS运行于该模式下. 保护模式:在该模式下,机器可 ...
- 8086汇编和Win32汇编
8086汇编是指在某环境下汇编编译产生的程序,用机器去执行每条指令的长度为16位(可小于16),如DOS操作系统:WIN32汇编是32位环境下的汇编,如Windows(Windows也有64位的,XP ...
- 8086汇编语言学习(二) 8086汇编开发环境搭建和Debug模式介绍
1. 8086汇编开发环境搭建 在上篇博客中简单的介绍了8086汇编语言.工欲善其事,必先利其器,在8086汇编语言正式开始学习之前,先介绍一下如何搭建8086汇编的开发环境. 汇编语言设计之初是用于 ...
- Win10下C语言转8086汇编
目录 Win10下C语言转8086汇编 简介 开始 写C代码 转换成汇编代码 Win10下C语言转8086汇编 简介 最近学习<王爽汇编>,然后突发奇想,想一边写C语言用编译器将其翻译成汇 ...
- 【8086汇编-Day2】dosbox实验环境配置及测试
我学习汇编用的是王爽的<汇编语言>第三版,书中是以8086处理器为例,是工作在实模式下的,而当下的个人电脑处理器都是工作在保护模式下的.所以需要一个虚拟的工作在实模式下的处理器,这里主要用 ...
- 【8086汇编-Day3】用debug做实验时的技巧与坑
Ⅰ· 无病呻吟 学一门语言,不动手实验是学不好的,在实验中不断遇坑然后解决,才有进益.所以写一下我在第一次汇编实验中的所思所想(王爽<汇编语言>第二章章末实验). Ⅱ · 实验内容 题解思 ...
- 8086汇编之 CALL 和 RET指令
Ret 和 call 也是转移指令,可是他们跟jmp不同的是,这两个转移指令都跟栈有关系. <1> ret 用栈中的数据改动IP的地址,从而实现近转移 ( ip ) = ( (ss)*16 ...
- 【8086汇编-Day8】实验九
Lab1 代码 ; 在屏幕上输出内存单元中的十进制两位数 assume cs:code, ds:data data segment db db , ; 前一个字节用于保存商,后一个字节用于保存余数 d ...
- 【8086汇编-Day7】关于多个段的程序的实验
实验一 实验二 实验三 实验四 实验五 实验六 总结 在集成环境下,内存从0770段开始按照段的先后顺序和内容多少分配,并且分配的都是16的倍数 关于实际占用的空间公式的话其实极容易想到(假设有N个字 ...
随机推荐
- 记一个 Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 编译问题引发的案例
某天将项目 kotlin 版本升级到了 1.8.0 ,然后编译报错了, Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 然后开始寻求解决方案 ...
- HashMap,TreeMap,LinkedHashMap的默认排序
简单描述 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,HashTable以及LinkedHashMap等. TreeMap:能够把它保存的记录根据键(key)排序,默 ...
- 【Azure Developer】使用 Powershell az account get-access-token 命令获取Access Token (使用用户名+密码)
问题描述 在上篇的文章中,我们使用了JAVA SDK,根据用户名和密码来获取Azure AD的Access Token,这节,我们将使用Powershell az 命令来获取Access Token. ...
- 【Filament】基于物理的光照(PBR)
1 前言 自定义Blinn Phong光照模型中实现了基础的自定义光照,与现实的光照还是有些差别,本文将实现更逼真的光照效果,即基于物理的光照(PBR). 读者如果对 Filament 不太熟 ...
- 深入解析ASP.NET Core MVC应用的模块化设计[上篇]
ASP.NET Core MVC的"模块化"设计使我们可以构成应用的基本单元Controller定义在任意的模块(程序集)中,并在运行时动态加载和卸载.这种为"飞行中的飞 ...
- C++ //vector容器嵌套容器
1 //vector容器嵌套容器 2 #include <iostream> 3 #include <string> 4 #include<fstream> 5 # ...
- nginx设置访问账号密码
第一:为kibana加上了用户登陆访问 第二:不暴露服务器上5601端口,只开放80端口即可.这对服务器的安全也是一个很大的保护. 接下来我们就开始配置nginx与kibana. 一.配置nginx ...
- Lucene轻量级搜索引擎,真的太强了!!!Solr 和 ES 都是基于它
一.基础知识 1.Lucene 是什么 Lucene 是一个本地全文搜索引擎,Solr 和 ElasticSearch 都是基于 Lucene 的封装 Lucene 适合那种轻量级的全文搜索,我就是服 ...
- springboot参数据校验
什么是Hibernate Validator? Hibernate Validator是Hibernate提供的一个开源框架,使用注解方式非常方便的实现服务端的数据校验. 官网:http://hibe ...
- 深入浅出Java多线程(十二):线程池
引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第十二篇内容:线程池.大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在现代软件开发中,多线程编程已经成为应对 ...