|
|
|
|
|
AN #196 - DotMatrix display |
|
BASCOM guru Ben Zijlstra wrote support for the neat matrix board based on some code he found on the net. Paulvk (check out his forums blog projects) added a lot of functionality such as IR control as you can read in his blog. So a good moment to create an AN out if it.
This is for the 4 digit HT1632 driven 32 x 8 matrix display JY-MCU-3208. A RX8025 real time clock and resistors have been soldered to the board also a MCP9700 analog temperature sensor has been used in place of an I2C one as the RTC is on different pins and we can only have one I2C port in Bascom with this board/AVR. A TSOP31236 infra-red receiver is used but any suitable one that runs off 5 volts will do. The 3 buttons on the board are not used as space in flash was needed and they are redundant with an IR remote. It is necessary to load and run the infra-red timing and decode programs to determine the characteristics and codes for the remote used Demo version of Bascom can be used for this but the full is required for this code.
'---------------------------------------------------------------------------------------
'This is for the 4 digit HT1632 driven 32 x 8 matrix display JY-MCU-3208
' Note as the code takes almost all the flash some parts need
' to be commented out to use the debug prints
' A RX8025 real time clock and resistors have been soldered to the board
' also a MCP9700 analog temprature sensor has been used in place of an I2C
' one as the RTC is on diffrent pins and we can only have one I2C port in Bascom
' with this board/AVR
' A TSOP31236 infra-red reciver is used but any suitable one that runs off 5 volts will do
' The 3 buttons on the board are not used as space in flash was needed
' and they are redundant with an IR remote
' It is nessary to load and run the infra-red timing and decode programs
' to determin the characteristics and codes for the remote used Demo version of
' Bascom can be used for this but the full is required for this code'
'--------------------------------------------------------------------------
' I have left some replaced code in but commented out so that it can be seen
' how Sub programs can be used to reduce code & flash use
'
'
'
'--------------------------------------------------------------------------------------------------------------
'
'I used an old VCR remote control hence PLAY & EJECT just replace the codes received for the buttons
'in your remote at the constants and re-type the instructions with your button choices
'Note I wrote these instructions for myself as there are too many to remember!
'
'
'CLOCK OPERATING INSTRUCTIONS
'
'
'Constant Button Function
'
'Pause PAUSE This displays the temprature
'
'Irclock CLOCK This puts theclock into time set mode
'
'Play PLAY This causes the date to be displayed
'
'Eject EJECT This turns the display off
'
'Poweron POWER ON This turns the display on
'
'Square SQUARE This sets the display to max brightness
'
'Arrowright ARROWRIGHT This changes the brightnes in steps from low to high in a loop
'
'Rew REWIND This stors the current brightness as the DUSK SETTING
'
'Ff FAST FORWARD This stors the current brightness as the DAYLIGHT SETTING
'
'Sstop STOP This stors the current brightness as the DARK SETTING
'
'Rec RECORD This turns the alarm on
'
'Tvvcr TVVCR This turns the alarm off & stops the display flashing
'
'TIME SET MODE-------------------AFTER PRESSING CLOCK
'
'Longp LONGPLAY This selects - Set the time
'
'Av AV This selects - Set the date
'
'Skip SKIP This selects - Set the alarm time and days
'
'How to set Time & Date
'----------------------------
'
'Press CLOCK this puts us into setting mode at any time pressing CLEAR will abort the mode
'
'Press LONGPLAY to set the time
'Enter hours and minutes via the number buttons then press OK to store them
'
'Press AV to set the date
'Enter month then day then two digits for the year the 20 is entered automatically (so it works for only 98 years)
'now press REC Record Day will be displayed then enter the day of the week starting at 0 for sunday
'when the correct day is shown press OK to store the date
'
'Press SKIP to set the alarm time and days
'Enter hours and minutes
'then press ARROW UP to move through the days of the week SUN MON TUE will display on the clock
'then press 1 or 0 1 will set that day for an alarm 0 with turn that day off any other number is a 1
'press OK to store the alarm setting
'
'---------------------------------------------------------------------------------------------------------------------
$regfile = "m8adef.dat"
$crystal = 8000000 'using internal RC
$hwstack = 128
$swstack = 256
$framesize = 256
$baud = 19200
'--fuse settings
'$PROG &HFF,&HC4,&HC7,&H00' generated. Take care that the chip supports all fuse bytes.
$lib "ds1307clock.lib" 'both chips are similar
Declare Sub Clrd 'clears display
Declare Sub Get_character
Declare Sub Show_text 'writes text data to display chip
Declare Sub Commandout 'sends commands to the HT1632 display driver
Declare Sub Rotate_chr 'rotates the eeprom data 90 deg
Declare Sub Get_chr 'caculates the position in eeprom of the character
Declare Sub Roll_over 'calls Roll_digit 8 times to roll the character in
Declare Sub Display_chr
Declare Sub Showtime 'gets the time from the RX8025 to be displayed
Declare Sub Roll_digit 'rolls the digit into the display on byte at a time
Declare Sub Bright_up 'changes the brightness of display
Declare Sub Add_kar
'--this sub for debug prints of RX8025 registers
'Declare Sub I2c_print
Declare Sub Set_tick
Declare Sub I2c_write 'writes to the RX8025
Declare Sub Dig1_2 'displays characters 1 & 2
Declare Sub Dig3_4 'displays characters 3 & 4
Declare Sub St_time 'looks up eeprom for character patern
Declare Sub I2c_read 'reads from RX8025
Declare Sub Add_chr 'add characters to be displayed
Declare Sub Handle_infrared 'decodes infra-red input
'address of rx8025
Const Rx8025w = &H64 ' Addresses of rx8025 clock
Const Rx8025r = &H65
Const 24hr = &HE0 'select 24 hour mode
Const 24hron = &H20
Const Alarmon = &HE3
Const Alarmoff = &H23
'--these are the control codes for the display chip
Const Senddata = &B0010100000000000
Const Sysen = &B100000000010
Const Ledon = &B100000000110
Const Ledoff = &B100000000100
Const Blinkon = &B100000010010
Const Mastermode = &B100000101110
Const Rc = &B100000110110
Const Commonsoption = &B100001000000 'N-MOS open drain output
Const Pwmduty = &B100101111100
Const Pwm 1_16duty = &B100101000000
Const Pwm 2_16duty = &B100101000100
Const Blinkoff = &B100000010000
'--remote control constants need to test with chosen remote to get codes
'--using the infra-red debugging programs with a serial port on a pc
'--
Const Remoteid = 183
Const Arrowup = 24740
Const Arrowdown = 41572
Const Arrowright = 58404
Const Arrowleft = 8420
Const Square = 17828
Const Eject = 49188
Const Poweron = 50468
Const Ok = 25508
Const Klear = 2020
Const Numone = 33124
Const Numtwo = 16804
Const Numthree = 484
Const Numfour = 49956
Const Numfive = 33636
Const Numsix = 17316
Const Numseven = 996
Const Numeight = 50980
Const Numnine = 34660
Const Numzero = 49444
Const Irclock = 4068
Const Tvvcr = 34148
Const Skip = 46948
Const Av = 21924
Const Longp = 53796
Const Rec = 33380
Const Rew = 16548
Const Ff = 228
Const Sstop = 32868
Const Play = 49700
Const Pause = 740
Cs1 Alias Portb.3 'chip select for display driver
Clk Alias Portb.4 'chip clock for display driver
Dat Alias Portb.5 'chip data line for display driver
'--configure these as outputs
Config Dat = Output
Config Clk = Output
Config Cs1 = Output
'--Pins connected to push buttons
'redundant with infra-red remote
'Push1 Alias Pind.5
'Push2 Alias Pind.6
'Push3 Alias Pind.7
Ina Alias Pinb.0
Almin Alias Pinc.3
Buzz Alias Portc.0
Llevel Alias Pinc.4
'Config Push1 = Input
'Config Push2 = Input
'Config Push3 = Input
Config Almin = Input 'inerrupt B output from RX8025
Config Buzz = Output 'output for use as buzzer or to switch something on
Config Llevel = Input 'connected to light sensor
Config Ina = Input
'Set Portd.5
'Set Portd.6 'Switch on the pullup for the buttons
'Set Portd.7
'Config Debounce = 1
Dim Chrrom(336) As Eram Byte 'the character fonts in eeprom
Dim Txt(51) As Eram String * 1 'days of week & text in eeprom
Dim Ereg As Eram Byte
Dim Eereg As Byte
'---here we stor the alarm settings in eeprom in case of battery fail
Dim Bright As Eram Word 'stor brightness for night
Dim Dusk As Eram Word 'stor brightness for in the middle
Dim Daybright As Eram Word 'stor brightness for day light
Dim Alarmmins As Eram Byte 'this is the alarm settings for minutes
Dim Alarmhours As Eram Byte 'this is the alarm settings for hours
Dim Alarmdays As Eram Byte 'this is the alarm settings for days
Dim Alarmcodes(31) As Eram Word
Dim Seeprm As Byte 'start pointer in eeprom
Dim Steps As Byte 'number of eeprom bytes to get
Dim Days As Byte
Dim Daybit As Byte
Dim Daybyte As Byte
Dim Setday As Bit
Dim Dayweek As Byte
Dim Almison As Bit
Dim Mabcd As Byte
Dim B As Byte
Config Scl = Portb.1 ' we need to provide the SCL pin name
Config Sda = Portb.2 ' we need to provide the SDA pin name
Dim Weekday As Byte
Dim G As String * 32
'--infra red
Dim Length As Word
Dim Recvdata As Long
'--
'--Overlay is a good function here it enables me to
'--break the Recvdata Long (4 bytes) into two Datain words (2 bytes each)
'--and importantly uses no RAM
Dim Datain(2) As Word At Recvdata Overlay
Dim Bx As Byte
Dim Px As Bit
Dim Dotim As Byte
Dim Dodat As Bit
Dim Klk As Bit
Dim Timedate As Bit
Dim Digit As Byte
Dim Timeset As String * 8
Dim Dateset As String * 8
Dim Lmins As Byte
Dim Lhour As Byte
Dim I2caddress As Byte
Dim I2cdata As Byte
Dim X As Byte
Dim Y As Byte
Dim D As Byte
Dim E As Word
Dim F As Word
'Dim Fnt(8) As Byte
Dim Kar As String * 1
Dim Lt As String * 8 'changed from local to make use of a sub
Dim Shiftdat As Word
'Dim Shiftdodat As Word
Dim Pulswidth As Word
Dim Z As Byte
Dim W As Word
Dim K As Word
Dim B1 As Byte
Dim B2 As Byte
Dim Cd As Byte
Dim Col As Bit
Dim Ana As Double
'-- Ana is 8 bytes long
'--the dim below uses the Overlay function
'--this breakes Ana up into 8 one byte variables
'--and importantly uses no RAM
Dim Aa(8) As Byte At Ana Overlay
Dim Bb(8) As Byte 'a place to stor the 8 bytes of the character
'font from eeprom
'--digits 1 to four with space for two digits the before and after
'--so we can roll them in
'--this holds each 8x8 digit in one variable
Dim Dig1 As Double
Dim Dig2 As Double
Dim Dig3 As Double
Dim Dig4 As Double
Dim Dignew As Double
Dim Digtemp As Double
'--with the overlay we break up each double into 8 bytes which gives us each row 1 t 8
'--and importantly uses no RAM
Dim D1(8) As Byte At Dig1 Overlay
Dim D2(8) As Byte At Dig2 Overlay
Dim D3(8) As Byte At Dig3 Overlay
Dim D4(8) As Byte At Dig4 Overlay
Dim Ddnew(8) As Byte At Dignew Overlay
Dim Ddtemp(8) As Byte At Digtemp Overlay
Dim Lv As Byte
Dim Dignum As Byte 'this is the number of the digit
Dim Light As Word 'value from the ADC connected to the light sensor
'used in deguging
'Dim N As Byte
'Dim M As Byte
'Dim O As Byte
'Dim P As Byte
'
'Set up the ADC part of the chip let the compliler handle Prescaler = Auto set the Reference = Avcc this uses the voltage
'fed to the micro, the board has a 1nF capacitor from AREF to ground already so no need to add it
'
Config Adc = Single , Prescaler = Auto , Reference = Avcc
'---Here we are not using the timer but its interrupt function to trigger code
'---this is a very usefull thing as with some chips if you use the other functions like
'---two RS232 serial ports INT0 & INT1 are no longer avaliable
'
'===for 1 second tick
Config Timer1 = Timer , Capture_edge = Rising , Noise_cancel = 0
On Capture1 Sectic 'go to Sectic on interrupt
'------this is for the infra-red
On Int1 Int_one 'go to Int_one on interrupt
Dim Tim As String * 8 '8 characters for time and date
Config Date = Dmy , Separator = Minus ' EG 22-10-12
Dim Tick As Byte 'we use this to count up to 60
Config Clock = User 'we do our own clock (User) not using the megaAVR timer and 32KHz crystal
'---
'--- NOTE You must enable the individual interrupts for them to work
'--- Enable Interrupts does not do this
'---
Enable Capture1 'the one second pulse from RTC
Enable Int1 'infra-red detector
Enable Interrupts
Reset Buzz 'turn buzzer off
'---read control register E I2cdata will hold the contents
I2caddress = &HE4
Call I2c_read
'debug prints
'Print "I2c>" ; Bin(i2cdata)
Eereg = Ereg
'Print "EEP>" ; Bin(eereg)
If I2cdata = Eereg Then 'if it does not match the stored value
'this may be because the alarm is on
nop
Else 'or the RTC chip has just been powered up
I2caddress = &HE0
I2cdata = Eereg
'Print "eeprom" ; Hex(i2cdata)
Call I2c_write
End If
'Print "eeprom" ; Hex(i2cdata)
'--debug prints
'----------------------------
'--this shows how to read the control registers of the RX8025
'I2cstart ' Generate start code
'I2cwbyte Rx8025w ' send write address
'I2cwbyte &H80 ' start address in rx8025 with read bit set
' we can read from this address
'--read back the two control registers
'I2crbyte N , Ack
'I2crbyte M , Ack
'I2crbyte O , Ack
'I2crbyte P , Nack
'I2cstop
'Print "Reg MINS>" ; Bin(n)
'Print "Reg HOURS>" ; Bin(m)
'Print "Reg DAYS>" ; Bin(o)
'Print "Reg E>" ; Bin(p)
Daybit = 1
D = 12
Set Cs1
Shiftdat = Sysen
Call Commandout
'--turn the display on
Shiftdat = Ledon
Call Commandout
'--as we only have one display driver we set it as a master
Shiftdat = Mastermode
Call Commandout
Shiftdat = Rc
Call Commandout
'--set the type of led common anode or cathode
Shiftdat = Commonsoption
Call Commandout
'--set the display to maximum brightness
Pulswidth = 2368
Shiftdat = Pwmduty
Call Commandout
'here we get the alarm time from eeprom to write to the RTC
'at default these will be all 0 but if we set alarm values and
'the back up battery is flat we will have not to reset the alarm data
'also as I intend to have a clock with a retrofited mega328 which will
'get its time from the internet via NTP so it does not even need back up
Lmins = Alarmmins
Lhour = Alarmhours
Daybyte = Alarmdays
'if the value is greater than 0
If Lhour > 0 Then 'write alarm time to real time clock
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send address
I2cwbyte &H80 ' starting address in rx8025
I2cwbyte Lmins
I2cwbyte Lhour
I2cwbyte Daybyte
I2cstop
End If
Dignum = 1
Call Clrd 'clear Display
Dotim = 0
Dodat = 0
Klk = 0
Tick = 60
Timedate = 1 'show date
'Call Showtime
'--here we go around in a circle a do--loop
'--waiting to be sent to an interrup which comes
'--once every second from the RTC clock or from the
'--infra-red reciver
Do
If Klk = 0 Then 'if Klk 1 we are setting the time & date
'so leave display alone
If Tick >= 59 Then
Light = Getadc(4) 'get the value for thelight sensor
'--debug print
'Print "Light" ; Light 'this is so you can determin what is the dark, dusk, daylight value
'comment out date$ print to use
Select Case Light
Case Is > 700 'it must be dark
Pulswidth = Bright 'set it to what we stored in eeprom
Case Is > 550 'it must be almost dark
Pulswidth = Dusk 'set it to what we stored in eeprom
Case Else
Pulswidth = Daybright 'set it to what we stored in eeprom
End Select
Shiftdat = Pulswidth
Call Commandout
Call Showtime
Call Set_tick
'---So why send date and time to serial port?
'---well I intend to build slave clocks that
'---will recive this via a wireless link
'---thus every clock in my house will have
'---exactly the same time I only need set
'---the master clock, along comes daylight saving
'---the master will know this and update itself then
'---transmit time and date which all the slaves
'---will get and update their times
Print Date$ ; "<<<>>>" ; Time$
End If
End If
If Almin = 0 And Almison = 0 Then 'we have an alarm
Almison = 1 'stop the if-then running
Shiftdat = Blinkon 'flash display
Call Commandout
Set Buzz 'turn on buzzer
End If
Loop 'go back to the DO
End
'--read a byte from the RTC
Sub I2c_read
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send write address
I2cwbyte I2caddress ' control register two address in rx8025
I2crbyte I2cdata , Nack ' read in byte
I2cstop
End Sub
'--write a byte to the RTC
Sub I2c_write
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send write address
I2cwbyte I2caddress ' control register two address in rx8025
I2cwbyte I2cdata
I2cstop
End Sub
'call three subs in turn
Sub Display_chr
Call Get_chr
Call Rotate_chr
Call Roll_over
End Sub
'-display digit 1 & 2
Sub Dig1_2
Dignum = 1
Kar = Left(lt , 1)
Call Display_chr
Dignum = 2
Kar = Mid(lt , 2 , 1)
Call Display_chr
End Sub
'-display digit 3 & 4
Sub Dig3_4
Dignum = 3
Kar = Mid(lt , 4 , 1)
Call Display_chr
Dignum = 4
Kar = Mid(lt , 5 , 1)
Call Display_chr
End Sub
'--this will display the time or date depending
'--on the setting of the Timedate variable
Sub Showtime
'--these local variables a temporary we release the RAM used by them
'--when we exit the sub and they are only avaliable in this sub
'--this makes best use of what can be a scarce resource
Local Lm As String * 2
Local Ln As String * 2
Local Lo As String * 4
Select Case Timedate
Case 0
Lt = Time$
Case 1
Lt = Date$
Tick = 0
Lm = Left(lt , 2) 'month
Ln = Mid(lt , 4 , 2) 'day
Lo = Right(lt , 2) 'year
Lt = Ln + "-" + Lm + "-" + Lo 'day month year
Print Lt
Seeprm = 26 'eeprom start point
Steps = 4 'number of bytes from eeprom
Call St_time 'now get the bytes from eeprom
'these will put a character on the display
Wait 2
End Select
'--debug print
'Print "LT>>" ; Lt
Call Dig1_2
Call Dig3_4
If Timedate = 1 Then
Wait 5
Seeprm = 34
Steps = 2
Call St_time
Dignum = 3
Kar = Mid(lt , 7 , 1)
Call Display_chr
Dignum = 4
Kar = Mid(lt , 8 , 1)
Call Display_chr
Wait 5
Timedate = 0
Tick = 60
Exit Sub
Call Set_tick
End If
End Sub
Sub Set_tick
Local Lk As String * 2
Lt = Time$
Lk = Right(lt , 2)
Tick = Val(lk) - 2
End Sub
'--this gets the data from the infra-red
Int_one:
Pulsein Length , Pind , 3 , 1
'--the values in the case statements can be found with the infra-red debug programs
Select Case Length
Case Is < 60
Recvdata.bx = 0
Incr Bx
'Waitms 1 'adjust this for timing if needed
'Print "0" 'debug
Case Is < 250
Recvdata.bx = 1
Incr Bx
'Print "1" 'debug
Case Is > 500 'we are at the end
'this needs to be varied depending on
Call Handle_infrared 'the remote used some do not have this
Case Is > 400 'we are at the start
'some do not have this
Bx = 0
End Select
Return
'--this gets characters from the eeprom which have been placed in a particular
'--place and order there to make them simple to read this saves code space
Sub St_time
Local Lb As Byte
For Lb = 1 To Steps 'now we get the text from eeprom to save some flash
'the eeprom is now a character ROM
Kar = Txt(seeprm) 'this saved 400 bytes of flash
Dignum = Lb
Call Display_chr
Incr Seeprm
Next Lb
End Sub
'--this reduced the code by over 100 bytes
'--any task done a number of times can in most cases
'--be done in a sub saving flash
Sub Add_kar
Timeset = Timeset + Kar
Call Display_chr
Incr Dignum
End Sub
Sub Add_chr
Local Lkar As String * 1
Local Lbit As Byte
Select Case Dotim
Case 1 'set time
Select Case Dignum
Case 1 To 2
Call Add_kar
Case 3
Timeset = Timeset + ":"
Call Add_kar
Case 4
Timeset = Timeset + Kar + ":" + "00"
Call Display_chr
Dignum = 1
End Select
Case 0 'set date
Select Case Dignum
Case 1 To 2
Call Add_kar
Case 3
Timeset = Timeset + "-"
Call Add_kar
Case 4
Kar = Kar + "-"
Call Add_kar
Case 5
Lkar = Kar 'save character
Seeprm = 34
Steps = 2
Call St_time
Kar = Lkar 'replace character
'debug print
'Print "tset-mel>>" ; Kar
Dignum = 3
Call Add_kar
Dignum = 6
Case 6
Dignum = 4
Call Add_kar
Digit = 1
Case 7
Dignum = 4
Dayweek = Val(kar)
Call Display_chr
End Select
Case 2
Select Case Dignum 'set alarm
Case 1 To 4 'hour and minutes
Call Add_kar
Case 5 'set days for the alarm
Dignum = 4
Call Display_chr
'--------here we are setting the bit for the day to 1 or 0
Lbit = Val(kar)
'debug
'Print "Lbit" ; Lbit
If Lbit > 1 Then 'so if you press a number higher than 1 we asume it to be 1
Lbit = 1
End If
Daybyte.daybit = Lbit
'DEBUG PRINT
'Print "tset>>" ; Timeset
'Print "YES" ; Bin(daybyte)
Incr Daybit
End Select
End Select
End Sub
'--here we use the decoded infra-red data as commands
Sub Handle_infrared 'infra-red command
'--again we use temporary ram variables
Local Temp As Word
Local Deg As Single
Local Tval As String * 3
Local Alm As String * 2
Local Lday As Byte
Shift Recvdata , Left , 6 'line up the device ID and data to be in each variable
Shift Datain(1) , Right , 7 'move the device ID to the front of the variable
'debug
'Print Datain(1) 'these are to see the codes from remote
'Print Datain(2)
If Datain(1) = Remoteid Then 'Remoteid is an idetification code sent by
'the infra-red remote to identify itself
'it sends this before the data of the button
'so that when you turn your TV off your CD player
'knows its not its remote control and does not react
Datain(1) = 0
If Klk = 1 Then 'we are in set clock mode
Select Case Datain(2)
Case Longp 'set time
Dotim = 1
Dodat = 0
Timeset = ""
Seeprm = 22
Steps = 4 'number of bytes from eeprom
Call St_time
Dignum = 1
Case Av 'set date
'when we get to the year the 20 is automatically
'inserted before you put in the two year digits
'so yes its only good for 98 years
Dotim = 0
Timeset = ""
Seeprm = 26
Steps = 4 'number of bytes from eeprom
Call St_time
Dignum = 1
Case Skip 'set alarm
Dotim = 2
Timeset = ""
Seeprm = 45
Steps = 4
Days = 1
Daybit = 0 'number of bytes from eeprom
Call St_time
Dignum = 1
'Case 0
Case Numone 'number 1
Kar = "1"
Call Add_chr
Case Numtwo 'number 2
Kar = "2"
Call Add_chr
Case Numthree 'number 3
Kar = "3"
Call Add_chr
Case Numfour 'number 4
Kar = "4"
Call Add_chr
Case Numfive 'number 5
Kar = "5"
Call Add_chr
Case Numsix 'number 6
Kar = "6"
Call Add_chr
Case Numseven 'number 7
Kar = "7"
Call Add_chr
Case Numeight 'number 8
Kar = "8"
Call Add_chr
Case Numnine 'number 9
Kar = "9"
Call Add_chr
Case Numzero 'number 0
Kar = "0"
Call Add_chr
Case Arrowup 'move through days for alarm
'eg SUN , MON ,TUE
Seeprm = Days
Steps = 3
Dotim = 2
Call St_time
Days = Days + 3 'move to the position of the next day in eeprom
Dignum = 5
'Wait 1
Case Rec 'set day of week
'here we start at 0 for sunday
'and go up to 6 for saturday
'as this is how the RX8025 RTC works
Seeprm = 49
Steps = 3
Call St_time
Dignum = 7
Case Ok
Select Case Dotim
Case 0 'date
Date$ = Timeset 'set the date in the RTC
Tick = 0
Klk = 0
Case 1 'time
Time$ = Timeset 'set the time in the RTC
Tick = 0
Klk = 0
Case 2 'alarm set
Alm = Left(timeset , 2)
Lhour = Val(alm)
Lhour = Makebcd(lhour)
Alm = Mid(timeset , 3 , 2)
Lmins = Val(alm)
Lmins = Makebcd(lmins)
Alarmmins = Lmins 'write the values to eeprom
'to use to set if power fails
Alarmhours = Lhour 'Note not yet implimented
'due to flash space
Alarmdays = Daybyte
I2caddress = &HE0 'first turn alarm off
I2cdata = Alarmoff 'reccomended in spec documents
Call I2c_write
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send address
I2cwbyte &H80 ' starting address in rx8025
I2cwbyte Lmins 'write minutes to RX8025
I2cwbyte Lhour 'write hours to RX8025
I2cwbyte Daybyte 'write day settings to RX8025
I2cstop
Tick = 58
Klk = 0
End Select
Call Showtime
Case Klear 'abort the present operation
Klk = 0
Dignum = 1
Call Showtime
End Select
Recvdata = 0
Else
Select Case Datain(2)
Case Pause 'get temprature
'using an MCP9700
Seeprm = 30
Steps = 4 'number of bytes from eeprom
'to display the word TEMP
Call St_time
Dignum = 1
Wait 2
Temp = Getadc(2)
Deg = Temp * .00497 'refrence volts 4.97
'this needs to be adjusted to suit
'the value your analog reference is!
'measured at the AREF pin
Deg = Deg - .5 '0/C at 500 mili volts
Deg = Deg / .01 '10 mili volts per Deg/C
Print "Deg C/>" ; Deg
Tval = Fusing(deg , "##.#") 'only print 3 digits two before one after the decimal point
Lt = Tval + ":" 'the ":" character has been replaced by a deg C one in the eeprom
Call Dig1_2
Call Dig3_4
Case Irclock 'we will set clock
Klk = 1 'hold all events that change the display
Case Play 'show date
Timedate = 1
Call Showtime
'--not really needed alarm turns on blink
' Case Klear
' Shiftdat = Blinkon
'Call Commandout
'--need this to turn blink off after alarm turns it on
'--or we can include it in alarm off as I have done
'--it depends if you want the alarm to go off again
' Case Ok
' Shiftdat = Blinkoff
' Call Commandout
Case Eject
Shiftdat = Ledoff 'turn off the display
Call Commandout
Case Poweron
Shiftdat = Ledon 'turn on the display
Call Commandout
Case Square
Shiftdat = Pwmduty 'maximum brightness
Call Commandout
Case Arrowright
Call Bright_up
'---------debug prints to get value of alarm registers in RX8025
'Case Ff
'I2caddress = &H34
'Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
'I2caddress = &H70
'I2cdata = 0
'Call I2c_write
'Print ">>>>" ; Bin(i2cdata)
' I2caddress = &H84
' Call I2c_read
' Print ">>>>" ; Bin(i2cdata)
'
'I2caddress = &H94
'Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
'I2caddress = &HA4
'Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
' I2caddress = &HE4
' Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
'I2caddress = &HF4
'Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
'Call I2c_print
'Case Rew
'I2caddress = &H94
'Call I2c_print
'-------------------------------------------------
Case Rew
Dusk = Pulswidth 'stor current brightness for dusk setting
Case Ff
Daybright = Pulswidth 'stor current brightness for daylight setting
Case Sstop
Bright = Pulswidth 'stor current brightness for darkness setting
Case Rec 'turn alarm on
Almison = 0
I2caddress = &HE0
I2cdata = Alarmon
Call I2c_write
Case Tvvcr 'turn alarm off
Reset Buzz 'turn buzzer off
I2caddress = &HE0
I2cdata = Alarmoff
Call I2c_write
I2caddress = &HF0 'reset the bits to 0 in this register
I2cdata = 0 'as is reccomended in the data sheet
Call I2c_write
Shiftdat = Blinkoff 'stop display flashing
Call Commandout
End Select
Recvdata = 0
End If
End If
End Sub
'--for debug prints
'Sub I2c_print
'Call I2c_read
'Print ">>>>" ; Bin(i2cdata)
'End Sub
Sub Bright_up 'increase brightness then loop back to
'lowest value then up again
If Pulswidth > 2428 Then
Pulswidth = 2368
End If
Shiftdat = Pulswidth
Call Commandout
Pulswidth = Pulswidth + 4
End Sub
'--This ISR gets called once every second using the 1Hz from the RTC chip
Sectic:
'--this If > Then flashes the leds in the center for a clock display
'--once every second
If Klk = 0 Then
Tick = Tick + 1
If Col = 0 Then
'D2(1).7 = 0
D2(2).7 = 1 '*
D2(3).7 = 1 '*
D2(4).7 = 0 '
D2(5).7 = 1 '*
D2(6).7 = 1 '*
D2(7).7 = 0 '
'D2(8).7 = 0
' Ana = Dig2
'
' W = 16
' Cd = 1
'
' Call Show_text
Col = 1
Else
'D2(1).7 = 0
D2(2).7 = 0 '
D2(3).7 = 1 '*
D2(4).7 = 1 '*
D2(5).7 = 0 '
D2(6).7 = 1 '*
D2(7).7 = 1 '*
'D2(8).7 = 0
' Ana = Dig2
'
' W = 16
' Cd = 1
'
' Call Show_text
Col = 0
End If
D2(8).7 = 0
Ana = Dig2
W = 16
Cd = 1
Call Show_text
End If
Return
'--this sends the text to the display chip
Sub Show_text
'--use local variables as we have only 1K of ram
Local Ldat As Word
Local Lz As Byte
'W = 0 'address "0"
Ldat = &B0000001010000000 'write data command with space for address
Ldat = Ldat + W 'add address "W" to command (Shiftdodat)
Shift Ldat , Left , 6 'move the first bit to the front of the word
Reset Cs1 'select HT1632
Waitus 100 'wait for it to stabilise
Shiftout Dat , Clk , Ldat , 1 , 10 'clock out command and address
For Lz = 1 To Cd 'Cd alows us to clock out more than one character
Shiftout Dat , Clk , Ana , 3 , 64 'clock out data 64 bits= one character
'or 8 for one line,
Next Lz
Set Cs1
End Sub
'--This gets a character from the font data
'--that is now in eeprom
Sub Get_chr
'--use local variables as we have only 1K of ram
Local Le As Word
Local Lf As Word
Local Lz As Byte
Le = Asc(kar) 'get the ASCII value of the character
Le = Le - 48
'If Le = 0 Then
'Le = 1
'End If
Shift Le , Left , 3 'move up 8 bytes as there is 8 per character
'Le = Le * 8
'Le = Le + 1
'Restore Shrunk8x8 moved into eeprom
For Lz = 1 To 8 'get 8 the bytes from eeprom
Lf = Le + Lz
Bb(lz) = Chrrom(lf)
Next Lz
End Sub
'--This rotates the character 90deg to the left each time it is called
Sub Rotate_chr
'--use local variables as we have only 1K of ram
Local Lj As Byte
Local Lx As Byte
Local Ln As Byte
Local Lp As Byte
For Lj = 1 To 8
Ln = Lj - 1
For Lx = 1 To 8
Lp = Lx - 1
Aa(lj).lp = Bb(lx).ln
Next Lx
Next Lj
End Sub
'-this loads the data into the double word
'-Dignew is the new character Dig1 is character one, Dig2 is character two
'-Dig3 is character three, Dig4 is character four
Sub Roll_over
'--use local variables as we have only 1K of ram
'Local Lv As Byte
'--changed Lv to global to use Sub Roll_digit
'--removing 3 repeates of similar code saving 166 bytes of flash!
Cd = 1 ' only one characyer at a time
Dignew = Ana ' move character into temp buffer
For Lv = 8 To 1 Step -1 'move character in one byte at a time
Select Case Dignum
Case 1
Digtemp = Dig1
Call Roll_digit
Dig1 = Digtemp
Ana = Dig1
W = 0 'start of digit 1
Case 2
Digtemp = Dig2
Call Roll_digit
Dig2 = Digtemp
Ana = Dig2
W = 16 'start of digit 2
Case 3
Digtemp = Dig3
Call Roll_digit
Dig3 = Digtemp
Ana = Dig3
W = 32 'start of digit 3
Case 4
Digtemp = Dig4
Call Roll_digit
Dig4 = Digtemp
Ana = Dig4
W = 48 'start of digit 4
End Select
'-----Roll_digit sub replaced all this
'
' Select Case Dignum 'select character to change
'
' Case 1
'
' D1(8) = D1(7)
' D1(7) = D1(6)
' D1(6) = D1(5)
' D1(5) = D1(4)
' D1(4) = D1(3)
' D1(3) = D1(2)
' D1(2) = D1(1)
' D1(1) = Ddnew(lv)
'
' Ana = Dig1
'
' W = 0 'start of digit 1
'
' Case 2
'
'
' D2(8) = D2(7)
' D2(7) = D2(6)
' D2(6) = D2(5)
' D2(5) = D2(4)
' D2(4) = D2(3)
' D2(3) = D2(2)
' D2(2) = D2(1)
' D2(1) = Ddnew(lv)
'
' Ana = Dig2
'
' W = 16 'start of digit 2
'
' Case 3
'
'
' D3(8) = D3(7)
' D3(7) = D3(6)
' D3(6) = D3(5)
' D3(5) = D3(4)
' D3(4) = D3(3)
' D3(3) = D3(2)
' D3(2) = D3(1)
' D3(1) = Ddnew(lv)
'
' Ana = Dig3
'
' W = 32 'start of digit 3
'
'
' Case 4
'
'
' D4(8) = D4(7)
' D4(7) = D4(6)
' D4(6) = D4(5)
' D4(5) = D4(4)
' D4(4) = D4(3)
' D4(3) = D4(2)
' D4(2) = D4(1)
' D4(1) = Ddnew(lv)
'
' Ana = Dig4
'
' W = 48 'start of digit 4
'
'
' End Select
Call Show_text
Waitms 50 'adjust for speed of roll over
Next Lv
End Sub
'--replaced the multiple code in the sub above
Sub Roll_digit
Ddtemp(8) = Ddtemp(7)
Ddtemp(7) = Ddtemp(6)
Ddtemp(6) = Ddtemp(5)
Ddtemp(5) = Ddtemp(4)
Ddtemp(4) = Ddtemp(3)
Ddtemp(3) = Ddtemp(2)
Ddtemp(2) = Ddtemp(1)
Ddtemp(1) = Ddnew(lv)
End Sub
'---My clear display, all bits at once
'--this writes all of the leds at a time
'__this writes "0" to all leds clearing display
Sub Clrd
Dig1 = 0 'clear the digit variables
Dig2 = 0
Dig3 = 0
Dig4 = 0
Ana = 0 'set the value to "0"
Cd = 4 'send 64 bits 4 times & write to all bytes
Call Show_text
End Sub
'--this sends the command bytes to the display
Sub Commandout
Reset Cs1
Waitus 100
Shift Shiftdat , Left , 4
Shiftout Dat , Clk , Shiftdat , 1 , 12
Set Cs1
End Sub
'called from ds1307clock.lib so a DS1307 could be used as they both are similar but
'the RX8025 has its own internal crystal which has been calibrated at the factory
'so it has a higher accuracy
Getdatetime:
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send address
I2cwbyte &H04 ' start address in rx8025
I2crbyte _sec , Ack
I2crbyte _min , Ack ' MINUTES
I2crbyte _hour , Ack ' Hours
I2crbyte Weekday , Ack ' Day of Week
I2crbyte _day , Ack ' Day of Month
I2crbyte _month , Ack ' Month of Year
I2crbyte _year , Nack ' Year
I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
_day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return
Setdate:
_day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send address
I2cwbyte &H30 ' starting address in rx8025
I2cwbyte Dayweek
I2cwbyte _day ' Send Date
I2cwbyte _month ' MINUTES
I2cwbyte _year ' Hours
I2cstop
Return
Settime:
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
I2cstart ' Generate start code
I2cwbyte Rx8025w ' send address
I2cwbyte 0 ' starting address in rx8025
I2cwbyte _sec ' Send Data to SECONDS
I2cwbyte _min ' MINUTES
I2cwbyte _hour ' Hours
I2cstop
Return
'Moved into eeprom
'$include "shrunk8x8.font"
'--------------------------------------
'--Here we stor text in eeprom to save on flash space
$eeprom 'start of eeprom data
Data 0 , 62 , 81 , 73 , 69 , 62 , 0 , 0 ' 0
Data 0 , 0 , 66 , 127 , 64 , 0 , 0 , 0 ' 1
Data 0 , 98 , 81 , 73 , 73 , 70 , 0 , 0 ' 2
Data 0 , 34 , 73 , 73 , 73 , 54 , 0 , 0 ' 3
Data 0 , 24 , 20 , 18 , 127 , 16 , 0 , 0 ' 4
Data 0 , 47 , 73 , 73 , 73 , 49 , 0 , 0 ' 5
Data 0 , 60 , 74 , 73 , 73 , 48 , 0 , 0 ' 6
Data 0 , 1 , 113 , 9 , 5 , 3 , 0 , 0 ' 7
Data 0 , 54 , 73 , 73 , 73 , 54 , 0 , 0 ' 8
Data 0 , 6 , 73 , 73 , 41 , 30 , 0 , 0 ' 9
Data 7 , 5 , 7 , 0 , 60 , 66 , 66 , 66 ' : DEG C
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' ;
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' <
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' =
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' >
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' ?
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ' @
Data 0 , 126 , 17 , 17 , 17 , 126 , 0 , 0 ' A
Data 0 , 127 , 73 , 73 , 73 , 54 , 0 , 0 ' B
Data 0 , 62 , 65 , 65 , 65 , 34 , 0 , 0 ' C
Data 0 , 127 , 65 , 65 , 65 , 62 , 0 , 0 ' D
Data 0 , 127 , 73 , 73 , 73 , 65 , 0 , 0 ' E
Data 0 , 127 , 9 , 9 , 9 , 1 , 0 , 0 ' F
Data 0 , 62 , 65 , 73 , 73 , 122 , 0 , 0 ' G
Data 0 , 127 , 8 , 8 , 8 , 127 , 0 , 0 ' H
Data 0 , 0 , 65 , 127 , 65 , 0 , 0 , 0 ' I
Data 0 , 48 , 64 , 64 , 64 , 63 , 0 , 0 ' J
Data 0 , 127 , 8 , 20 , 34 , 65 , 0 , 0 ' K
Data 0 , 127 , 64 , 64 , 64 , 64 , 0 , 0 ' L
Data 0 , 127 , 2 , 4 , 2 , 127 , 0 , 0 ' M
Data 0 , 127 , 2 , 4 , 8 , 127 , 0 , 0 ' N
Data 0 , 62 , 65 , 65 , 65 , 62 , 0 , 0 ' O
Data 0 , 127 , 9 , 9 , 9 , 6 , 0 , 0 ' P
Data 0 , 62 , 65 , 81 , 33 , 94 , 0 , 0 ' Q
Data 0 , 127 , 9 , 9 , 25 , 102 , 0 , 0 ' R
Data 0 , 38 , 73 , 73 , 73 , 50 , 0 , 0 ' S
Data 0 , 1 , 1 , 127 , 1 , 1 , 0 , 0 ' T
Data 0 , 63 , 64 , 64 , 64 , 63 , 0 , 0 ' U
Data 0 , 31 , 32 , 64 , 32 , 31 , 0 , 0 ' V
Data 0 , 63 , 64 , 60 , 64 , 63 , 0 , 0 ' W
Data 0 , 99 , 20 , 8 , 20 , 99 , 0 , 0 ' X
Data 0 , 7 , 8 , 112 , 8 , 7 , 0 , 0 ' Y
'data 0 , 113 , 73 , 69 , 67 , 0 , 0 , 0 ' Z
'Data 7 , 5 , 7 , 0 , 60 , 66 , 66 , 66 ' !
'-------------prompts
Data "S" , "U" , "N" , "M" , "O" , "N" , "T" , "U" , "E" , "W" , "E" , "D"
Data "T" , "H" , "R" , "F" , "R" , "I" , "S" , "A" , "T"
Data "T" , "I" , "M" , "E" , "D" , "A" , "T" , "E" , "T" , "E" , "M" , "P"
Data "2"
Data "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9",
Data "A" , "L" , "A" , "M" , "D" , "A" , "Y" ', "M" , "A" , "L" , "A" , "M"
'Data "A" , "L" , "A" , "M"
Data &H23 'this is the register E control byte
'&H23 is the default with alarm off
'&HA3 is alarm on this is the
'eram variable Ereg
Data 2428 , 2428 , 2428 'default values for brightness
Data 0 , 0 , 0 , 0 , 0 , 0 'default alarm values
$data 'end of eeprom data
|
|
|
|
|
|
|