-
Notifications
You must be signed in to change notification settings - Fork 0
/
slave.a51
303 lines (256 loc) · 8.84 KB
/
slave.a51
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
;declaration
RGS bit P0.5
RW bit P0.6
E bit P0.7
LED bit P1.0
Laser bit P1.2
Sirene bit P1.3
DATABUS equ P2
BUSY_FLAG bit P2.7
CNT equ R7
; R6 => utilisé comme registre tampon
MARCHE_ARRET bit 20h
RECU data 7Fh
NB_TOUR data 7Eh
DDRAM_NB_TOUR equ 8Bh
NB_TIR_DROITE data 7Dh
DDRAM_DROITE equ 11000101b
NB_TIR_CENTRE data 7Ch
DDRAM_CENTRE equ 11001001b
NB_TIR_GAUCHE data 7Bh
DDRAM_GAUCHE equ 11001101b
MAGIC_INIT equ 00110000b
CFG_5x8 equ 00111000b
CFG_CURSOR equ 00001100b
CFG_OFF equ 00001000b
CFG_CLEAR equ 00000001b
CFG_MODESET equ 00000110b
;valeurs utiles pour le LCD
debut_ligne equ 11000000b
saut_de_ligne equ 10000000b
;vtable
org 0000h
SJMP debut
org 0023h ;adresse de l'interruption série
LJMP interrupt ;interrupt i.e. RI=1 flag de réception
org 0030h
;Définition des chaines de caractère à envoyer
ligne_H: DB ' Tour(s): 0/3 ',0
ligne_L: DB ' D=0 C=0 G=0 ',0
;main
debut: MOV SP,#2Fh
LCALL init
rpt: SJMP rpt
fin:
;==============================================================================================================
init:
CLR LASER ;on coupe le laser au démarrage
CLR SIRENE ;on coupe la sirène au démarrage
CLR MARCHE_ARRET ;On met le marche arrêt à 0
SETB LED ;On éteint la LED
MOV RECU,#00h ;init de la donnee recu
MOV NB_TOUR,#30h ;init du nombre de tours à 0 (ascii)
MOV NB_TIR_DROITE,#30h ;init du nombre de tir à droite à 0 (ascii)
MOV NB_TIR_CENTRE,#30h ;init du nombre de tir à centre à 0 (ascii)
MOV NB_TIR_GAUCHE,#30h ;init du nombre de tir à gauche à 0 (ascii)
MOV PCON,#0
MOV SCON,#01010000b ;On initialise la liaison série, asynchrone 1200Bd sans parité
MOV IE,#10010000b ;validation de l'interruption sur la série
MOV PCON,#0h
MOV TMOD,#00100001b
MOV TH1,#0E6h
MOV TL1,#0E6h
;Affichage du message de départ sur l'écran LCD
LCALL LCD_INIT
;ligne haute
MOV DATABUS,#saut_de_ligne
LCALL LCD_Code
MOV DPTR,#ligne_H
LCALL LCD_MSG
;ligne basse
MOV DATABUS,#debut_ligne
LCALL LCD_Code
MOV DPTR,#ligne_L
LCALL LCD_MSG
SETB TR1
RET
;==============================================================================================================
;interrupt i.e. RI=1 flag de reception
interrupt:
PUSH Acc
JNB RI,fsi_recu ;gestion de la deuxième interruption déclenchée par l'envoie de données à la carte maitre sur la liaison série
CLR RI
MOV A,SBUF
si_parite: JB P,fsi_parite ;test du bit de parité
CLR ACC.7 ;clear du bit de poids fort = bit de parité
CJNE A,RECU,si_recu ;On traite la valeur reçue si elle est différente de la précédente reçue
SJMP fsi_recu; ;On saute la mise à jour si la valeur n'a pas été déjà reçue
si_recu:
si_egal_0: CJNE A,#'0',si_egal_4
LCALL cas_0
fsi_egal_0: LJMP fcase
si_egal_4: CJNE A,#'4',si_egal_D
LCALL cas_4
fsi_egal_4: LJMP fcase
si_egal_D: CJNE A,#'D',si_egal_C
LCALL cas_D
fsi_egal_D: LJMP fcase
si_egal_C: CJNE A,#'C',si_egal_G
LCALL cas_C
fsi_egal_C: LJMP fcase
si_egal_G: CJNE A,#'G',fcase
LCALL cas_G
fsi_egal_G:
fcase:
MOV RECU,A
fsi_recu:
fsi_parite:
POP Acc
RETI
;==============================================================================================================
;Le caractère envoyé est contenu dans l'accumulateur lors de l'appel à cette fonction
cas_0:
si_MA_0: JB MARCHE_ARRET,sinon_MA_0
MOV R6,NB_TOUR
CJNE R6,#'3',si_tour_diff_3
SJMP fsi_tour_diff_3
si_tour_diff_3:
;envoyer "G" a la carte maitre
MOV SBUF,#'G' ;On charge la donnée dans le serial buffer
tq_send_G: JNB TI,tq_send_G ;On attend la fin de l'envoie du message
CLR TI
CLR LED ;test start led
SETB MARCHE_ARRET
fsi_tour_diff_3:
finsi_MA_0:
LJMP fsn_MA_0
sinon_MA_0:
;envoyer "S" à la carte maitre
MOV SBUF,#'S' ;On charge la donnée dans le serial buffer
tq_send_S: JNB TI,tq_send_S ;On attend la fin de l'envoie du message
CLR TI
CLR MARCHE_ARRET
MOV A,#0h ;permet de recevoir un deuxième zéro après la tempo de 2s puisque MOV RECU,A ensuite
INC NB_TOUR
MOV DATABUS,#DDRAM_NB_TOUR
LCALL LCD_Code
MOV DATABUS,NB_TOUR
LCALL LCD_DATA
MOV R6,#100
att_depart: LCALL timer_50ms
DJNZ R6,att_depart
fsn_MA_0:
RET
;==============================================================================================================
cas_4:
MOV R6,RECU
si_old_0: CJNE R6,#'0',fsi_old_0
SETB LED ;test stop led
SETB LASER
SETB SIRENE
fsi_old_0:
RET
;==============================================================================================================
cas_D:
INC NB_TIR_DROITE
MOV DATABUS,#DDRAM_DROITE
LCALL LCD_Code
MOV DATABUS,NB_TIR_DROITE
LCALL LCD_DATA
RET
;==============================================================================================================
cas_C:
INC NB_TIR_CENTRE
MOV DATABUS,#DDRAM_CENTRE
LCALL LCD_Code
MOV DATABUS,NB_TIR_CENTRE
LCALL LCD_DATA
RET
;==============================================================================================================
cas_G:
INC NB_TIR_GAUCHE
MOV DATABUS,#DDRAM_GAUCHE
LCALL LCD_Code
MOV DATABUS,NB_TIR_GAUCHE
LCALL LCD_DATA
CLR LASER
CLR SIRENE
RET
;==============================================================================================================
LCD_MSG:
PUSH ACC
MOV CNT,#0
tq_string: MOV A,CNT
MOVC A,@A+DPTR
JZ tq_string_fin
MOV DATABUS,A
LCALL LCD_DATA
INC CNT
SJMP tq_string
tq_string_fin:
POP ACC
LCD_MSG_fin: RET
;==============================================================================================================
LCD_BF:
MOV DATABUS,#0FFh ;P2 en lecture
SETB RW
CLR RGS
tq_busy: CLR E ;tq busy_flag==1, on attend
SETB E
JB BUSY_FLAG,tq_busy
tq_busy_fin:
CLR E
LCD_BF_fin: RET
;==============================================================================================================
;Envoi le contenu de databus à l'ecran LCD en tant qu'ordre
LCD_CODE:
CLR RGS
CLR RW
SETB E
CLR E
LCALL LCD_BF
LCD_CODE_fin: RET
;==============================================================================================================
;Envoi le contenu de databus à l'ecran LCD en tant que donnée
LCD_DATA:
SETB RGS
CLR RW
SETB E
CLR E
LCALL LCD_BF
LCD_DATA_fin: RET
;==============================================================================================================
LCD_INIT:
CLR RGS
CLR RW
MOV R6,#3
rpt3x:
LCALL timer_50ms
MOV DATABUS,#MAGIC_INIT
SETB E
CLR E
DJNZ R6,rpt3x
rpt3x_fin:
LCALL timer_50ms
MOV DATABUS,#CFG_5x8
LCALL LCD_CODE
MOV DATABUS,#CFG_OFF
LCALL LCD_CODE
MOV DATABUS,#CFG_CLEAR
LCALL LCD_CODE
MOV DATABUS,#CFG_MODESET
LCALL LCD_CODE
MOV DATABUS,#CFG_CURSOR
LCALL LCD_CODE
LCD_INIT_fin: RET
;==============================================================================================================
timer_50ms:
MOV TL0,#0B0h ; Et on le sauvegarde dans le timer L
MOV TH0,#3Ch ; On charge la partie haute du chargement
SETB TR0
boucle_timer: JNB TF0,boucle_timer
CLR TF0
CLR TR0
fin_timer_50ms:
RET
end