使用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不支持浮点运算,对应的数据可以通过手册的公式和表格另行计算:

posted @ 2019-12-26 20:11  Kryo  阅读(1430)  评论(0编辑  收藏  举报