-
Notifications
You must be signed in to change notification settings - Fork 0
/
humidity_sensor.asm
308 lines (226 loc) · 5.51 KB
/
humidity_sensor.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
DATA SEGMENT
; PORT ADDRESSES
PORTA EQU 00H
PORTB EQU 02H
PORTC EQU 04H
CONTROL_REG EQU 06H
; TEXT TO DISPLAY ON LCD
HUMIDITY DB "Humidity: $"
PPM DB "ppm$"
; VARIABLES TO KEEP TRACK OF PORT DATA
PORTB_VAL DB 00H
PORTC_VAL DB 00H
; MISC VARS
QUOTIENT DB 31H
REMAINDER DB 32H
DECIMAL_POINT DB '.'
MAX_PPM DB 56
ENDS
STACK SEGMENT
DW 128 DUP(0)
ENDS
CODE SEGMENT
START:
; SETTING SEGMENT REGISTERS
MOV AX, DATA
MOV DS, AX
MOV ES, AX
; INITIALISING 8255 WITH PORT-A AS INPUT PORT AND PORT-B, PORT-C AS OUTPUT PORTS
MOV AL, 10010000B
OUT CONTROL_REG, AL
CALL LCD_INIT
MOV DL, 01H
MOV DH, 01H
CALL LCD_SET_CUR
; GET DATA FROM ADC AND DISPLAY ON LCD
CALL DISPLAY_HUMIDITY
HLT
; END OF MAIN PROCEDURE
; ============= DISPLAY HUMIDITY VALUE PROCEDURE =============
PROC DISPLAY_HUMIDITY
X1:
IN AL, PORTA
MOV QUOTIENT, AL
CALL CHANGE_TO_PPM
MOV AL, 00H
OUT PORTC, AL
MOV CX, 20000
CALL DELAY
MOV AL, 01H
OUT PORTC, AL
CALL LCD_CLEAR
LEA SI, HUMIDITY
CALL LCD_PRINTSTR
MOV AH, QUOTIENT
CALL LCD_WRITE_CHAR
MOV AH, DECIMAL_POINT
CALL LCD_WRITE_CHAR
MOV AH, REMAINDER
CALL LCD_WRITE_CHAR
LEA SI, PPM
CALL LCD_PRINTSTR
MOV CX, 20000
CALL DELAY
JMP X1
RET
ENDP DISPLAY_HUMIDITY
; ============= DELAY PROCEDURE =============
PROC DELAY
; HERE CX CONTROLS THE AMOUNT OF DELAY, CX=50 MEANS A DELAY OF 1 MS.
JCXZ @DELAY_END
@DEL_LOOP:
LOOP @DEL_LOOP
@DELAY_END:
RET
ENDP DELAY
; ============= ADC VALUE CONVERSION TO PPM VALUE =============
PROC CHANGE_TO_PPM
; QUOTIENT HAS THE VALUE TO BE CONVERTED INTO PPM
; LET VALUE FROM ADC BE X
; MAX_PPM STORES THE MAXIMUM PPM TO BE SHOWN * 10
; VALUE TO BE SHOWN IN PPM = (MAX_PPM) * X / 2550
; EG. X = 255 CORRESPONDS TO MAX_PPM
; DIGIT BEFORE DECIMAL IS STORED IN QUOTIENT
; DIGIT AFTER DECIMAL IS STORED IN REMAINDER
MOV AL, QUOTIENT
MOV AH, 00H ; AX = AH:AL
MOV CL, MAX_PPM
MOV CH, 00H
MUL CX ; AX = AX * MAX_PPM
MOV BX, 2550
DIV BX ; AX = AX / 2550 AND DX = AX % 2550
; AX STORES THE QUOTIENT, DX STORES THE REMAINDER
ADD AL, 30H ; CONVERTING HEX VALUE TO ASCII
MOV QUOTIENT, AL ; STORING FIRST DECIMAL ASCII
MOV AX, DX ; REMAINDER TRANSFERRED TO AX
MOV CX, 10
MUL CX ; AX = AX * 10
DIV BX ; AX = AX / 2550
; AX STORES THE QUOTIENT, FOR THIS CASE ALL THE QUOTIENTS ARE ONLY 8 BIT SO IT IS STORED IN AL
ADD AL, 30H ; CONVERTING HEX VALUE TO ASCII
MOV REMAINDER, AL ; STORING SECOND DECIMAL ASCII
RET
ENDP CHANGE_TO_PPM
; ============= ALL LCD PROCEDURES INVOLVED =============
PROC LCD_INIT
MOV AL, 01H
CALL OUT_C ; MAKING LCD INPUT RS = RW = E = LOW (00H) AT THE START
MOV CX, 1000
CALL DELAY ; 20 MS DELAY
; RESET SEQUENCE
MOV AH, 30H
CALL LCD_CMD
MOV CX, 250
CALL DELAY ; 250 MS DELAY
MOV AH, 30H
CALL LCD_CMD
MOV CX, 50
CALL DELAY ; 1 MS DELAY
MOV AH, 30H
CALL LCD_CMD
MOV CX, 500
CALL DELAY ; 10 MS DELAY
; SET FUNCTION
MOV AH, 38H
CALL LCD_CMD
MOV AH, 0CH
CALL LCD_CMD
MOV AH, 01H
CALL LCD_CMD
MOV AH, 06H
CALL LCD_CMD
RET
ENDP LCD_INIT
PROC LCD_CMD
; AH CONTAINS THE COMMAND CODE
PUSH DX
PUSH AX
MOV AL, PORTC_VAL
AND AL, 0FDH ; RESET RS, AL = 1111 1101B, SINCE RS IS AT PIN PC1 OF 8255
CALL OUT_C
; SET OUT DATA PINS
MOV AL, AH
CALL OUT_B
MOV AL, PORTC_VAL
OR AL, 1000B ; SET E, AL = 0000 1000B, SINCE EN IS AT PIN PC3 OF 8255
CALL OUT_C
MOV CX, 50
CALL DELAY ; 1 MS DELAY
MOV AL, PORTC_VAL
AND AL, 0F7H ; RESET E, AL = 1111 0111B, SINCE E IS AT PIN PC3 OF 8255
CALL OUT_C
MOV CX, 50
CALL DELAY ; 1 MS DELAY
POP AX
POP DX
RET
ENDP LCD_CMD
PROC LCD_CLEAR
MOV AH, 01H
CALL LCD_CMD
RET
ENDP LCD_CLEAR
PROC LCD_WRITE_CHAR
; AH CONTAINS THE INFO TO DISPLAY
PUSH AX
MOV AL, PORTC_VAL
OR AL, 10B ; SET RS, AL = 0000 0010B, SINCE RS IS AT PIN PC1 OF 8255
CALL OUT_C
; SET OUT DATA PINS
MOV AL, AH
CALL OUT_B
MOV AL, PORTC_VAL
OR AL, 1000B ; SET E, AL = 0000 1000B, SINCE EN IS AT PIN PC3 OF 8255
CALL OUT_C
MOV CX, 50
CALL DELAY ; 1 MS DELAY
MOV AL, PORTC_VAL
AND AL, 0F7H ; RESET E, AL = 1111 0111B, SINCE E IS AT PIN PC3 OF 8255
CALL OUT_C
POP AX
RET
ENDP LCD_WRITE_CHAR
PROC LCD_PRINTSTR
; SI CONTAINS THE ADDRESS OF THE STRING ENDING WITH '$'
PUSH SI
PUSH AX
@LCD_PRINTSTR_LT:
LODSB
CMP AL, '$'
JE @LCD_PRINTSTR_EXIT
MOV AH, AL
CALL LCD_WRITE_CHAR
JMP @LCD_PRINTSTR_LT
@LCD_PRINTSTR_EXIT:
POP AX
POP SI
RET
ENDP LCD_PRINTSTR
PROC LCD_SET_CUR
; DH = ROW, DL = COL
PUSH AX
; LCD USES 0 INDEXING FOR COLUMNS
DEC DH
; DL = 1
MOV AH, 80H
JMP @LCD_SET_CUR_ENDCASE
@LCD_SET_CUR_ENDCASE:
ADD AH, DH
CALL LCD_CMD
POP AX
RET
ENDP LCD_SET_CUR
PROC OUT_B
; AL CONTAINS THE DATA TO OUTPUT AND THIS IS STORED IN PORTB_VAL
OUT PORTB, AL
MOV PORTB_VAL, AL
RET
ENDP OUT_B
PROC OUT_C
; AL CONTAINS THE DATA TO OUTPUT AND THIS IS STORED IN PORTC_VAL
OUT PORTC, AL
MOV PORTC_VAL, AL
RET
ENDP OUT_C
CODE ENDS
END START