forked from Anobium/Great-Cow-BASIC-Demonstration-Sources
-
Notifications
You must be signed in to change notification settings - Fork 0
/
i2c_DS1307_16F1938_Serial.gcb
588 lines (475 loc) · 15 KB
/
i2c_DS1307_16F1938_Serial.gcb
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
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
'''A demonstration program for GCGB and GCB.
'''--------------------------------------------------------------------------------------------------------------------------------
'''This program shows the real time clock on a serial terminal.
''':
'''The DS1307 is attached to the I2C ports with appropiate resistors to the supply voltage. Typically a 5k or 2.2k resistor 'pulling up' to the supply voltage can be used.
''':
''': There are two pushbuttons: Mode and Set equates to Key1 and Key2. Connected to portb.0 and portb.1 resepectively.
''':
''': During normal operation, the Mode button will toggle
''': between 12- and 24-hours modes.
''':
''': This has two modes US date and UK date style.
''': Change ''':clocktype''': to 0 for US and 1 for UK
''':
''': To set a new date and time, press the Set button
''': which will take you consecutively to Month, Day, Year,
''': Day of the Week, Hour, Minute and Second. Within each of
''': these, press Mode to cycle through the possible values.
''': You may hold the Mode button to increment automatically,
''': or press momentarily for a single increment. Time is
''': always set in 24-hour clock format.
'''@author EvanV
'''@licence GPL
'''@version 1.2a
'''@date 23.02.15
'''********************************************************************************
; ----- Configuration
#chip 16F1938, 32
#option explicit
#config Osc = intOSC, MCLRE_ON, PLLEN_ON, VCAPEN_OFF
#include <DS1307.h>
; ----- Define Hardware settings
dir setBut in
dir modeBut in
; Define Hardware I2C settings for SSP module
#define HI2C_BAUD_RATE 100
#define HI2C_DATA PORTC.4
#define HI2C_CLOCK PORTC.3
;I2C pins need to be input for SSP module
Dir HI2C_DATA in
Dir HI2C_CLOCK in
;MASTER I2C Device for SSP module
HI2CMode Master
; Define I2C settings - CHANGE PORTS
' #define I2C_MODE Master
' #define I2C_DATA PORTC.4
' #define I2C_CLOCK PORTC.3
' #define I2C_DISABLE_INTERRUPTS ON
' ;#define I2C_BIT_DELAY 20 us ;width of data bit on SDA
' ;#define I2C_CLOCK_DELAY 10 us ;width of clock pulse on SCL
' ;#define I2C_END_DELAY 10 us ;interval between clock pulses
' THIS CONFIG OF THE SERIAL PORT WORKS WITH max232 THEN TO PC
' USART settings
#define USART_BAUD_RATE 9600
Dir PORTc.6 Out
Dir PORTc.7 In
#define USART_DELAY 10 ms
#define USART_BLOCKING
wait 500 ms
HSerSend 7
#define clocktype 0 ;0 is US or 1 is UK style
#define debounce 50 mS ;settling time for switches
#define delay 150 mS ;delay time for pushbutton
#define pressed 1 ;flag for pressed pushbutton
#define setBut portb.0 ;Set pushbutton
#define modeBut portb.1 ;Mode pushbutton
#define Alarm0 0x00 ;a reference to the alarm 0
#define Alarm1 0x01 ;a reference to the alarm 1
;----- Variables
Dim DAYSMAX, DAYSMAX as Byte
dim changed as bit
dim hour, min, sec, am_pm as byte
dim oldsec as byte
dim date, month, year, DOW as byte
dim mode, Oldmode, dayMax as byte
oldsec = 255 ; init value
;----- Tables
table monthDays ;# of days in months
31
29 ;leap years only
31
30
31
30
31
31
30
31
30
31
end table
;----- Program
#ifdef HI2C_DATA
Locate 0, 12
Print "i2cHW"
HI2CStart ; is device present?
HI2CSend(DS_AddrWrite)
HI2CStop
if HI2CAckPollState = True then ; is device present?
CLS
Print "No DS1307" ; user message
locate 1,0
Print "Stopped" ; user message
wait 2 s
end
end if
#endif
#ifdef I2C_DATA
Locate 0, 12
Print "i2cSW"
I2CStart ; is device present?
I2CSend(DS_AddrWrite)
I2CStop
if I2CSendState = False then ; is device present?
CLS
Print "No DS1307" ; user message
locate 1,0
Print "Stopped" ; user message
end
end if
#endif
' DS1307_SetClock(14, 13, 0, 2, 23, 2, 15)
locate 0,0
Print "DS1307"
locate 1,0
Print "Great Cow Basic"
wait 2 s
CLS
; example uses of the new functions
DS1307_ReadDate(DOW, date, month, year) ;get initial date
DS1307_ReadHourMode(mode) ;and the current mode
DS1307_SetHourMode(mode) ;update hour mode from RTC
DS1307_EnableOscillator( true ) ;and, ensure the clock is running
DS1307_SetSQW 0 ;and, turn off output
;Main body of program commences here.
DS1307_ReadDate(DOW, date, month, year) ;get initial date
DS1307_ReadHourMode(mode) ;and the current mode
do
updateDisp ;show time and date
if setBut = pressed then
changeSetting ;change time and date
end if
if modeBut = pressed then
changeMode ;12 or 24 hour mode
end if
loop
end
;----- Subroutines
sub printTime
if mode = 24 then
if hour < 10 then ;left pad with zero
Print "0"
end if
end if
Print hour
Print ":"
if min < 10 then ;left pad with zero
Print "0"
end if
Print min
Print ":"
if sec < 10 then ;left pad with zero
Print "0"
end if
Print sec
if mode = 12 then ;Print a.m or p.m
if am_pm then ;only in 12-hour mode
Print " p.m. "
else
Print " a.m. "
end if
else
Print " " ;wipe out garbage
end if
end sub
;-----
sub printDate
select case DOW ;day of the week
case 1:
Print "Sun."
case 2:
Print "Mon."
case 3:
Print "Tue."
case 4:
Print "Wed."
case 5:
Print "Thu."
case 6:
Print "Fri."
case 7:
Print "Sat."
case else
Print "Err."
end select
if clocktype = 0 then
Print month
Print "/"
Print date
Print "/20" ;make four-digit year
if year < 10 then
Print "0"
end if
else
Print date
Print "/"
Print month
Print "/20" ;make four-digit year
if year < 10 then
Print "0"
end if
end if
Print year
Print " " ;blank any garbage
end sub
;-----
sub updateDisp
;for best efficiency, date is only updated once a day
DS1307_ReadTime(hour, min, sec, am_pm)
if oldsec <> sec then
if !(hour | min | sec) then ;time to update
DS1307_ReadDate(DOW, date, month, year)
end if
locate 0,0 ;home the cursor
printTime ;show time
locate 1,0 ;show the date
printDate
oldsec = sec
end if
end sub
;-----
sub changeSetting
changed = false ;assume no change will be made
DS1307_ReadHourMode(Oldmode) ;and the current mode
mode = 24 ;ensure the display is correct
DS1307_SetHourMode(24) ;change settings in 24-hour mode
do while setBut = pressed ;wait for Set release
wait debounce
loop
wait while ( setBut = pressed ) or ( modeBut = pressed )
if clocktype = 0 then ; handle US and UK clock type
SetMonth
SetDate
else
SetDate
SetMonth
end if
SetYear
;***** Day of the Week
cls
Print "Set Weekday:"
locate 1,0
printDate
do
do while modeBut = pressed ;Mode button held
DOW++ ;increment while pressed
if DOW > 7 then ;1 = Sunday, etc.
DOW = 1
end if
locate 1,0 ;Print updated display
printDate
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
;***** Hour
cls
Print "Set Hours:"
locate 1,0
if OldMode = 12 and am_pm then ; make correction of AM_PM mode by adding 12 hours to handle mode changes
hour = hour + 12
end if
printTime
do
do while modeBut = pressed ;Mode button held
hour++ ;increment while pressed
if hour > 23 then ;remember, set in 24-hour mode
hour = 0
end if
locate 1,0 ;Print updated display
printTime
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
;***** Minutes
cls
Print "Set Minutes:"
locate 1,0
printTime
do
do while modeBut = pressed ;Mode button held
min++ ;increment while pressed
if min > 59 then ;0 to 59 minutes
min = 0
end if
locate 1,0 ;Print updated display
printTime
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
;***** Second
cls
Print "Set Seconds:"
locate 1,0
printTime
do
do while modeBut = pressed ;Mode button held
sec++ ;increment while pressed
if sec > 59 then ;0 to 59 seconds
sec = 0
end if
locate 1,0 ;Print updated display
printTime
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
;***** Execute the new settings
if changed then
cls
Print "Press Set, or"
locate 1,0
Print "Mode to revert"
do while (setBut <> pressed) ;wait for the Set button
wait debounce
if ModeBut = pressed then
cls ;clear last message
DS1307_SetHourMode(Oldmode) ;restore current mode
exit Sub ;do not set, exit set routine
end if
loop
DS1307_SetHourMode(24) ;change settings in 24-hour mode
DS1307_SetClock(hour, min, sec, DOW, date, month, year)
end if
do while (setBut = pressed) ;wait for Set release
loop
wait debounce ;let it settle
cls ;clear last message
DS1307_SetHourMode(Oldmode) ;restore current mode
DS1307_EnableOscillator( true ) ;ensure the clock is running
mode = Oldmode ;restore mode
end sub
;-----
sub changeMode
DS1307_SetHourMode(24) ;change settings in 24-hour mode
if mode = 12 then ;toggle between 12 and 24
mode = 24
else
mode = 12
end if
DS1307_SetHourMode(mode) ;change to new mode
do while modeBut = pressed ;wait for a release
wait debounce
loop
end sub
sub setMonth
;***** Month
cls
Print "Set Month:"
locate 1,0
printDate
do
do while modeBut = pressed ;Mode button held
month++ ;increment while pressed
if month > 12 then
month = 1
end if
locate 1,0 ;Print updated display
printDate
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
wait debounce
loop while setBut <> pressed ;Set moves you on
readTable monthDays, month, daysMax
do while setBut = pressed ;wait for Set release
wait debounce
loop
end Sub
sub SetDate
;***** Date
cls
Print "Set Date:"
locate 1,0
printDate
readTable monthDays, month, daysMax
do
do while modeBut = pressed ;Mode button held
date++ ;increment while pressed
if date > daysMax then ;stay within legal days
date = 1
end if
locate 1,0 ;Print updated display
printDate
wait while modeBut = pressed ;wait for repeatt
changed = true ;a change was made
loop
wait debounce
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
end sub
sub SetYear
;***** Year
cls
Print "Set Year:"
locate 1,0
printDate
do
do while modeBut = pressed ;Mode button held
year++ ;increment while pressed
if year > 99 then ;this millennium only
year = 0
end if
locate 1,0 ;Print updated display
printDate
wait while modeBut = pressed ;wait for repeat
changed = true ;a change was made
loop
wait debounce
loop while setBut <> pressed
do while setBut = pressed ;wait for Set release
wait debounce
loop
end sub
#define locate ANSI_rev
#define CLS ANSIERASECREEN
#define print hserprint
' Position cursor on Terminal
Sub ANSI ( IN xpos, IN ypos )
HSerSend 27
HSerPrint "["
HSerPrint ypos
HSerSend 59
HSerPrint xpos
HSerPrint "H"
End Sub
' Position cursor on Terminal
Sub ANSI_rev ( IN ypos, IN xpos )
ypos++
HSerSend 27
HSerPrint "["
HSerPrint ypos
HSerSend 59
HSerPrint xpos
HSerPrint "H"
End Sub
' Eraase Terminal
Sub ANSIERASECREEN
HSerSend 27
HSerPrint "["
HSerPrint "2"
HSerPrint "J"
Ansi ( 0, 0 )
HSerSend 27
HSerPrint "["
HSerPrint "?"
HSerPrint "25"
HSerPrint "l"
end Sub