DS1307 and a LED array, need ideas
Hi, I want to do two things at once, and I don't know how :)
Let me explain, I want to update a led matrix (12x12) this needs to be done real fast so the eye, due to persistance of vision , thinks all the leds are on at the same time, but also I want to poll a DS1307 RTC to keep time.
So, how do I do both things at the same time? I mean if I pause between reads the led display does not show, and if I read the clock in the led matrix refresh loop I choke the DS1307 with too many requests.
Speed is no problem because Im going to use a 18F4550 or one of its relatives (depending on the amount of data I will need to store)
I think the solution is around interrupts, but I never programmed with interrupts, so Im kinda lost here... Im not asking for code (it wont hurt to read some thou) just some pointers so I can figure it out what to do with some datasheet reading.
thanks
Some sample interrupt code for DS1337
Quote:
Originally Posted by
peu
... Im not asking for code (it wont hurt to read some thou) ....
You're on the right track to consider an interrupt. Search this forum for how to use Darrel Taylor's Base Interrupt System...you need to download his DT_INTS-18.bas and ReEnterPBP-18.bas files and make them INCLUDEs in your code. Am currently working on an application that uses this approach for an 18F4550, but with a DS1337 real-time-clock rather than the DS1307. DS1307 is almost identical to DS1337 except for 2 pins and the register addressing...suggest you get the data sheets for both and compare and you should be able to quickly see how to modify this example code to make it work with DS1307.
Here is the setup from the example code. If you are interested in all the code I can email it to you...too long for this posting. Ask questions and I will try to help you. This forum has been very good to me so I welcome the opportunity to do some payback.
Code:
' [ Program Description ]
' This Program is for a PIC18F4550 & was tested in an EasyPic6 board. *
' Purpose: *
' 1) Monitors 1/min interrupt from external Real Time Clock *
' [ Device Declaration
; if you un-comment these, you must comment the ones in the .inc file--
ASM ; 18F2550/4550, 8mhz crystal
__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC4_PLL6_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _PBADEN_OFF_3H ; PortB resets as digital
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
ENDASM
Include "Modedefs.Bas"
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP high priority interrupts
INCLUDE "ALLDIGITAL.pbp" ' Sets all registers for digital ops.
DEFINE OSC 16
' Initialize Hardware
' =============
'Set registers
TRISA = 0 ' PORTA all outputs
TRISB =%00001100 ' RB2 & RB3 set as RTC Alarm1 & Alarm2 inputs
TRISC = 0
TRISD = 0
TRISE = 0
' Variables & Aliases for Pins other than RTC use
' ==================================
b0 VAR Byte ' LSB of range measurement when right justified
b1 VAR Byte ' MSB of range measurement when right justified
'SETUP FOR USING DS1337 Real Time Clock
' Setup Hardware for uart
' ==================
DEFINE HSER_BAUD 115200
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_CLROERR 1
' * NOTES for use with EasyPic6 development board:
'For interface to DS1337 RTC:
' - To provide battery backup place a Shottky diode between + battery
' terminal and Vcc (pin-8) of the DS1337.
' - I2C communication lines should be connected to 4.7K pull-up resistors.
' - INTA & INTB lines should be connected to pull-up resistsors.
' - Turn off LEDs connected to I2C communication lines.
' Aliased Variables for CLock
' ====================
Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337 INTB (pin-7)
SCL VAR PORTB.1 ' I2C clock pin
SDA VAR PORTB.0 ' I2C data pin
RTCdevice CON %11010000 ' RTC device write address(byte addressing)
' A list of possible clock contrl settings, one which must be
' setup in the SetTimeAndDate subroutine.
'contrl CON %00000101 ' Starts oscillator, enables INTA interrupt
' from A1F, INTA/SQW off.
'contrl CON %00000110 ' Starts oscillator, enables INTB interrupt
' from A2F. WORKS OK!
' RTC Address definitions
' =================
SecReg CON $00 ' seconds address (00 - 59)
' MSB of SecReg must be set to a 0 to enable RTC
MinReg CON $01 ' minutes address (00 - 59)
HrReg CON $02 ' hours address (01 - 12) or (00 - 23)
DayReg CON $03 ' day address (1 - 7)
DateReg CON $04 ' date address (01 - 28/29, 30, 31)
MonReg CON $05 ' month address (01 - 12)
YearReg CON $06 ' year address (00 - 99)
' Alarm 1 Address definitions
' ====================
Alm1sec CON $07 ' Alarm 1 seconds address (00 - 59)
Alm1min CON $08 ' Alarm 1 minutes address (00 - 59)
Alm1hr CON $09 ' Alarm 1 hours address (01 - 12) or (00 - 23)
Alm1Day CON $0A ' Alarm 1 day address (1 - 7)
' Alarm 2 Address definitions
' ====================
Alm2min CON $0B ' Alarm 2 minutes address (00 - 59)
Alm2hr CON $0C ' Alarm 2 hours address (01 - 12) or (00 - 23)
Alm2Day CON $0D ' Alarm 2 day address (1 - 7)
' Alias of Clock register addresses
' ========================
ContReg CON $0E ' CONTROL register address
StatusReg CON $0F ' STATUS register address
' Clock Variables
' ===========
sec VAR BYTE ' seconds
MINs VAR BYTE ' minutes
hr VAR BYTE ' hours
day VAR BYTE ' day
date VAR BYTE ' date
mon VAR BYTE ' month
yr VAR BYTE ' year
' ALARM1 VARIABLES
' ==============
A1sec VAR BYTE ' seconds
A1MINs VAR BYTE ' minutes
A1hr VAR BYTE ' hours
A1day VAR BYTE ' day
' ALARM2 VARIABLES
' ==============
A2MINs VAR BYTE ' minutes
A2hr VAR BYTE ' hours
A2day VAR BYTE ' day
GoSub SetTimeAndDate ' Setup current time & alarm settings
'SETUP FOR INTERRUPTS
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
;INT_Handler USB_Handler
INT_Handler INT2_INT, _Alarm, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE INT2_INT ; enable external (INT) interrupts
INTCON.7 = 1 ' Set Global Interrupt Enable bit
INTCON2 = %00000000 ' Set INT2 for falling edge (Bit4-low)
' on RTC's interrupt.
INTCON3 = %10010000 ' Set INT2 high priority (Bit7-high), enable INT2
' (Bit4-high)
RTC_INT_FLG VAR INTCON3.1 'Alias for RB2 INTA interrupt flag from RTC
'[ Begin Main Program Loop ]
Main:
GoTo Main ' Endless Loop waiting for interrupt
End ' Safety measure to insure program stops if reaches here
'[ Begin Interrupt Handler
Alarm:
'Put your interrupt service routine code here
' Process the RTC alarm
' Read the current time and ALARM settings from the DS1337
I2CRead SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
Pause 1000
' Clear the Alarm flags to be ready for next intterupt
' Clear STATUS register
I2CWrite SDA, SCL, RTCdevice, StatusReg,[$00]
Pause 1000
WRITE 255, sec
PAUSE 20
RTC_INT_FLG = 0 ' Clear PIC interrupt flag for next Alarm
PAUSE 1000
' Resume Main Program
@ INT_RETURN
End ' Safety measure to insure program stops if reaches here
'{ End of Interrupt Handler }
' [ START LIST OF SUBROUTINES
SetTimeAndDate: ' Subroutine to set current time, date and alarms
'==============
' Initialize clock variables to 0
yr=0:date =0:mon =0:day=0:hr=0:MINs=0:sec=0
A1sec=0:A1MINs=0:A1hr=0:A1Day=0
A2MINs=0:A2hr=0:A2day=0
' The BCD constants below set the RTC to: 11:00:00 on 12-20-2009
hr=$11
MINs=$00
sec=$00
day=$07
mon=$12
date=$20
yr=$09
' Per MAXIM TechSupport, proper sequencing requires setting INTCN = 1,
' & A2IE=A1IE=0 before setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000100]
Pause 20
'Define ALARM1 FOR 11:01:00 & to alarm when secs match (1/min).
' This requires A1M1=0 and A1M2=A1M3=A1M4=1
' (A1xxx + $80 or A1xxx + 128d sets bit 7 as A1Mx = 1)
A1hr = %10010001 '$11 + $80 = %10010001, for A1M3 = 1
'Bit6 must be 0 for 24 hour clock
A1MINs = %10000001 '$501 + $80 = %10000001, for A1M2 = 1
A1sec = $00 '$00 = %00000000, for A1M1 = 0
A1day = %10000111 '$07 + $80 = $10000111, for A1M4 = 1
'DY/_DT Bit6 = 0 for using Day of month alarm
' Per MAXIM TechSupport, reset control register for desired Alarm
' after setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
PAUSE 20
'Set the main Time
I2CWrite SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
Pause 20
'Set the Alarm1 Time
I2CWrite SDA, SCL, RTCdevice, Alm1sec,[A1sec,A1MINs,A1hr,A1day]
PAUSE 20
' Clear STATUS and set CONTROL registers
I2CWrite SDA, SCL, RTCdevice, StatusReg,[$00] ' Clear STATUS register
PAUSE 20
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
' Starts the oscillator,
' enables INTA interrupt from A1F.
' WORKS as intended!!
Pause 20
Return
' If the user program ends by getting to the last statement of the
' program at an END instruction, the MCU will SLEEP and await a wakeup.
END