前言:使用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不支持浮點運算,對應的數據可以通過手冊的公式和表格另行計算: