-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTIMER.asm
462 lines (390 loc) · 13.4 KB
/
TIMER.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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
; week timer scheduler.
; Control 4 relays on a periode of a week
; 127 programs/week saved in flash (254 octets).
; for each program we choose: day, hour, min (multiple of 4) and the relay to turn ON/OFF.
; 2 bytes per programme:
; - 1 byte day (3bits) and hour (5 lower bits)
; - 1 byte minutes in multiple of 4 (high nible) and relays to control (low nible)
; minutes 4, 8, 12 ....56.
; each minute we scan the program array in flash.
; we use the variable schedul to point the location in the array and R1 as a counter (254 MAX).
; 16F84 @ 32,768 KHz (crystal from a clock)
; ************************************************
LIST p=16F84A
#INCLUDE <P16F84A.inc>
__config _CP_OFF & _WDT_OFF & _PWRTE_ON & _LP_OSC
;------------------------------------------------------------------
; vars:
CBLOCK 0x0C
min, heur, day, secondes, tmp, tmp2, tmp3, CounterA, schedul, r1, r2, r3, r4, r5, r6
ENDC
;----------------------------------
; LCD Module commands
;
LINE1 EQU 0x080 ; Set display to line 1 character 0
LINE2 EQU 0x0C0 ; Set display to line 2 character 0
FUNCTION_SET EQU 0x028 ; 4 bits, 2 lines, 5x7 Font
DISP_ON EQU 0x00C ; Display on
DISP_ON_C EQU 0x00E ; Display on, Cursor on
DISP_ON_B EQU 0x00F ; Display on, Cursor on, Blink cursor
DISP_OFF EQU 0x008 ; Display off
CLR_DISP EQU 0x001 ; Clear the Display
ENTRY_INC EQU 0x006 ;
ENTRY_INC_S EQU 0x007 ;
ENTRY_DEC EQU 0x004 ;
ENTRY_DEC_S EQU 0x005 ;
DD_RAM_ADDR EQU 0x080 ; Least Significant 7-bit are for address
DD_RAM_UL EQU 0x080 ; Upper Left coner of the Display
;
LCD_DATA EQU PORTB ; LCD data on PORT B, RB0-RB3
LCD_CNTL EQU PORTA ; LCD data on PORT A,RA3= E, RA2= RS
;
;
;
; LCD Display Commands and Control Signal names.
;
E EQU 3 ; LCD Enable control line on RA3
RS EQU 2 ; LCD Register Select control line on RA2
;
;***********************************
ORG 0000 ; RESET VECTOR
goto init
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine d'interruption
; 1 source d'interruption
; - TMR0 en mode timer
; Cette interruption a lieu toutes les secondes exactement
; quartz 32768 Hz prescaler 1:32
;
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
org H'0004' ; vecteur d'interruption
;-------------------------
; routine executé chaque seconde
; mise à jour de l'heure
; increment minute, hour and day counters
incf secondes,f ; increment secondes
movlw D'60' ; 60 secondes (for test purpose use lower value ex 2)
subwf secondes,W
btfss STATUS,Z ; on a compté 60s ??
goto fin1 ; Non : sortir
clrf secondes ; Oui: on efface le compteur
incf min ; et on incremente les minutes
movlw D'30' ; for test, must be 60
subwf min,W ; 60 minutes passées?
btfss STATUS,Z
goto scheduler ; Non est-ce que c l'heure du programme
clrf min ; OUi: remise à zero du compteur minutes
incf heur ; et on incrémente l'heure
movlw D'24' ; 24 hours (use 3 for test)
subwf heur,W ; 24 heures passées?
btfss STATUS,Z
goto scheduler ; Non est-ce que c l'heure du programme
clrf heur ; OUi: remise à zero du compteur heures
incf day ; increment day counter
movlw D'07'
subwf day,W ; 7 days passées?
btfss STATUS,Z
goto scheduler ; Non est-ce que c l'heure du programme
clrf day ; OUi: remise à zero du compteur jours
scheduler
movlw 0x80 ; goto Line1
call Send_Cmd
movf day, w ;
call convert
call Send_Char
movlw ' '
call Send_Char
swapf heur, w
andlw 0x0F
call convert
call Send_Char
movf heur, w ;
andlw 0x0F
call convert
call Send_Char
movlw ' '
call Send_Char
swapf min, w
andlw 0x0F
call convert
call Send_Char
movf min, w ;
andlw 0x0F
call convert
call Send_Char
;--------------------------------
;read flash and display
movlw 0xFE ; 254 bytes for program
movwf r1 ; array pointer
read
movlw 0xC0 ; Set display to line 2 character 0
call Send_Cmd
movf pclath,w ; save PCLATH
movwf r5
movlw 3 ; cause array is at 0x300
movwf PCLATH
movf schedul, w
call TAB ;
movwf tmp2 ; save W
movwf tmp3
movf r5,w ; restore PCLATH
movwf pclath
swapf tmp3
rrf tmp3 ; shift right
movf tmp3, w
andlw 0x07 ; get day (3bits)
subwf day, w
btfss status, z
goto skip
movf tmp2, w
andlw 0x1F ; get hour (5bits)
subwf heur, w
btfss status, z
goto skip
decfsz r1 ; get next byte is it the last one?
goto mins ; no: then next byte (minutes + relays)
goto fin1 ; yes: quit
mins
movf pclath,w ; save PCLATH
movwf r5
movlw 3 ; cause array is at 0x300
movwf PCLATH
incf schedul
movf schedul, w
call TAB ;
movwf tmp2 ; save W
movf r5,w ; restore PCLATH
movwf pclath
movf tmp2,w
andlw 0x0F ; Low nible (min)
movwf tmp3
BCF status,C ; C=0
RLF tmp3,F ; tmp3= tmp3X2
BCF status,C
RLF tmp3,w ; W= tmp3X2 (so tmp3X4)
subwf min, w ; actual min = prgrammed min?
btfss status, z ; Yes:
goto nextp ; No: chek next program
btfss tmp2,7 ; Relay ON?
goto zero ; No
movlw 'O'
call Send_Char
movlw 'N'
call Send_Char
bsf porta, 1
goto fin1 ; quit
zero
movlw 'O'
call Send_Char
movlw 'F'
call Send_Char
bcf porta, 1
goto fin1
skip ; skip byte (minutes + relays)
decfsz r1 ; r1 - 1 =0?
goto suite ; No then skip
goto fin1 ; Yes: quit
suite
incf schedul ; skip byte
nextp
decfsz r1 ; next program: 64 bytes tested?
goto again ; No: then continue
goto fin1 ; oui: alors fin
again
incf schedul ; next program
goto read ;
;---------------------------
fin1
clrf schedul ; start from begining of EEPROM
bcf INTCON,T0IF ; on efface le drapeau T0IF
retfie ; retour d'interruption
;*********************************************
; RESET VECTOR
;********************************************
; INITALISE PORTS AND TMR0
init
clrf PORTA ; ALL PORT output should output Low.
clrf PORTB
BSF STATUS, RP0 ; SELECT BANK 1
MOVLW 0xF1 ; 11110001
MOVWF TRISA ; SET pins RA0 and 4 AS input and RA1, RA2, RA3 outputs
movlw 0xF0
movwf TRISB ; RB7 - 4 inputs, RB3 - 0 outputs for LCD data
movlw B'00000100'
movwf OPTION_REG
; bit 7 (/RBPU) = 0 : activation des résistances de pull-up du port B
; bit 6 (INTEDG)= 0 : (non utilisée)
; bit 5 (T0CS) = 0 : TMR0 Clock Source Select = internal CLK/4
; bit 4 (T0SE) = 0 :
; bit 3 (PSA) = 0 : Prescaler attribué au timer
; bit 2 (PS2)= 1
; bit 1 (PS1) = 0
; bit 0 (PS0) = 1 : 100 --> Facteur de division du prescaler = 1/32
; (32768/4)/32 = 256Hz --> 256/256 (TIMER0)= 1s
BCF STATUS, RP0 ; SELECT BANK 0
;----------------------------------------------
call LCD_Init ; Set up the LCD Module
;Display a message
movlw 'C'
call Send_Char
movlw 'L'
call Send_Char
movlw 'O'
call Send_Char
movlw 'C'
call Send_Char
movlw 'K'
call Send_Char
;------------
clrf min
clrf heur
clrf day
clrf secondes
clrf schedul ; scheduler indice
; Autoriser les interruptions en general et celui du Timer0
movlw B'10100000'
movwf INTCON
; bit 7 (GIE) = 1 : autorisation globale des interruptions
; bit 5 (T0IE) = 1 : autorisation de l'interruption TMR0
; bit 2 (T0IF)= 0 : on efface le drapeau de l'interruption TMR0
; les autres bits sont inutilisés (valeur par défaut = 0)
clrf TMR0 ; mise à zero du timer0
;===================================================================
hang
goto hang ; loop for ever
;***************************************************************
; binary to hex converter
convert
addwf pcl,f
dt "0123456789ABCDEF"
;*******************************************************************
;* The LCD Module Subroutines *
;*******************************************************************
;
; Initilize the LCD Display Module
;
LCD_Init
call Delay15 ; Wait for 30ms for LCD to get powered up
call Delay15
movlw 0x02 ; Command for 4-bit interface
movwf LCD_DATA ; Send data to LCD
call e_pulse
call Delay5
movlw FUNCTION_SET ; 0x28: 0b00101000 = Function set, 4 wire, 2 lines, 5x7 font
call Send_Cmd ; Can now use the Send_Cmd routine since in 4bit mode.
movlw DISP_ON ; 0x0c: 0b00001100 = Display on, no cursor, no blink
call Send_Cmd
movlw ENTRY_INC ; 0x06: 0b00000110 = Address increment, no scrolling
call Send_Cmd
movlw CLR_DISP ; 0x01: Clear LCD
call Send_Cmd
; LCD Module is now initalized
return
;*******************************************************************
;*SendChar - Sends character to LCD *
;*This routine splits the character into the upper and lower *
;*nibbles and sends them to the LCD, upper nibble first.
;* Character to be sent is in W *
;*******************************************************************
;
Send_Char
movwf tmp ; save W
swapf tmp, w ; msb: upper 4bits
movwf LCD_DATA
call e_pulse
movf tmp, w ; lsb: lower 4bits
movwf LCD_DATA
call e_pulse
call Delay5
return
;
;*******************************************************************
;* Send_Cmd - Sends command to LCD *
;* This routine splits the command into the upper and lower *
;* nibbles and sends them to the LCD, upper nibble first. *
;* command to be sent is in W *
;*******************************************************************
Send_Cmd
movwf tmp ; save W
swapf tmp, w ; msb: upper 4bits
movwf LCD_DATA
bcf LCD_CNTL,RS ; Set LCD to command mode
call e_pulse
movf tmp, w ; lsb: lower 4bits
movwf LCD_DATA
call e_pulse
call Delay5
bsf LCD_CNTL,RS ; quit command mode
return
;*******************************************
; Send pulse on E
;***********************
e_pulse
;nop
bsf LCD_CNTL,E
;nop
bcf LCD_CNTL,E
return
;*******************************************
; Delay routines. based on 32768 Hz
Delay15 ;15 ms
;PIC Time Delay = 0.014892578 s with Osc = 32768 Hz
movlw D'39'
movwf CounterA
loop1
decfsz CounterA,1
goto loop1
return
Delay5 ;5 ms
;PIC Time Delay = 0.004638672 s with Osc = 32768 Hz
movlw D'11'
movwf CounterA
loop2
decfsz CounterA,1
goto loop2
return
;------------------------
; 2 octets par programme:
; - 1 octet jour (3bits haut) et heure (5bits)
; - 1 octet minutes en multiple de 4 (low nible) et relais à actionner (high nible)
; dans cet exemple: jour 0 heure 0 et 4 minute relais ON puis à 12 minutes OFF (regarder la fin du tableau)
; ensuite ON à 20 min et OFF à 28 min
; on passe au jour 1 heure 1 et 8 min relais ON puis à 16 min OFF
; noubliez pas qu'on miltuplie les minutes par 4
; pas besoin de mettre le programme en ordre
; le dernier octet n'est pas utilisable
org 0x300
TAB
addwf PCL, F
dt 0x00, 0xF1, 0xFF, 0xFF,0x00, 0xF5, 0x00, 0x07,0x21, 0xF2, 0x21, 0x04,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF
dt 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,0x00, 0x03, 0xFF
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Initialisation de la mémoire EEPROM (facultatif)
; Cela met dans l'EEPROM le message :
; (C) Mahmoud LAOUAR 25/09/2015
; (en code ASCII)
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
org H'2100' ; début de zone EEPROM du PIC 16F84A
DE '(' ; ou DE H'28' (code ASCII correspondant)
DE 'C'
DE ')',' '
DE 'M' ,'a','h','m','o','u','d',' '
DE 'L','O','U','A','R',' '
DE '2','5','/','0','9','/','2','0','1','5',' '
DE 'V' ,'0','.','1'
;***********
END