In dit artikel bespreek ik hoe je een DS3232 real time clock kan gebruiken met picbasic.
Aansluiten:
Ik heb hier een PIC16F628A gebruikt. De SDA van de DS3232 heb ik met portA.0 van de pic verbonden en de SCL met portA.1. Bij I?C communicatie moet je ook 2 pull-up weerstandjes voorzien.
De reset lijn heb ik hier ook doorverbonden maar die wordt niet gebruikt in de code dus mag weggelaten worden.
De pindeclaratie wordt dan:
Symbol DS_SDA = PORTA.0 Symbol DS_SLC = PORTA.1
Het uitlezen:
Het uitlezen van de DS3232 gebeurd met het I2CIN commando.
In de helpfunctie van picbasic staat hierover de volgende beschrijving:
Syntax I2CIN Dpin , Cpin , Control , { Address }, [ Variable {, Variable?} ] Operators: [i]Dpin[/i] - a Port.Pin constant that specifies the I/O pin that will be connected to the I2C device's data line (SDA). This pin's I/O direction will be changed to input and will remain in that state after the instruction is completed. [i]Cpin[/i] - a Port.Pin constant that specifies the I/O pin that will be connected to the I2C device's clock line (SCL). This pin's I/O direction will be changed to output. [i]Variable[/i] - a user defined variable of type bit, byte, byte array, word, word array, dword, or float. [i]Control[/i] - a constant value or a byte sized variable expression. [i]Address[/i] - an optional constant value or a variable expression.
Dpin wordt hier nu vervangen door DS_SDA en Cpin door DS_SLC.
De control byte is bij de DS3232 1101000 gevolgd door een 0 voor te lezen of een 1 voor te schrijven naar de DS3232.
{ Address } geeft hier aan in welk register we willen wegschrijven. Hiervoor staat in de datasheet een handige tabel:
Voor het overzicht te behouden kunnen we de adressen omzetten naar woordjes met symbol. Zo krijg je deze lijst:
Symbol Reg_Seconden = $00 Symbol Reg_Minuten = $01 Symbol Reg_Uren = $02 Symbol Reg_Dag = $03 Symbol Reg_Datum = $04 Symbol Reg_Maand = $05 Symbol Reg_Jaar = $06 Symbol Reg_Temp = $11
Nu kan je gewoon Reg_Seconden schrijven in plaats van $00. Als we nu het control adres ook zo maken wordt dat ook meteen overzichtelijker.
Symbol Lezen = %11010000 Symbol Schrijven = %11010001
De code om de seconden uit te lezen wordt dan dit:
I2CIN DS_SDA, DS_SLC, Lezen, Reg_Seconden, [Seconden]
Nu is er nog het probleem dat de getallen in bcd staan in de DS3232. Om die naar byte?s om te zetten heb ik 2 subroutines geschreven.
Eerst moet je alles gaan uitlezen. Dan omzetten naar byte waarde. Die 2 subroutine?s roep ik aan met deze code:
GoSub Inlezen GoSub Omzetten
De subroutine “Inlezen” bestaat uit de volgende code:
Inlezen: I2CIN DS_SDA, DS_SLC, Lezen, Reg_Seconden, [Seconden] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Minuten, [Minuten] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Uren, [Uren] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Datum, [Datum] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Maand, [Maand] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Jaar, [Jaar] I2CIN DS_SDA, DS_SLC, Lezen, Reg_Temp, [Temperatuur] Return
De subroutine “Omzetten” bestaat uit de volgende code:
Omzetten: 'Seconden BCD_In = Seconden : GoSub BCD_To_Byte: Seconden = Byte_Uit 'Minuten BCD_In = Minuten : GoSub BCD_To_Byte: Minuten = Byte_Uit 'Uren Uren.7 = 0 Uren.6 = 0 BCD_In = Uren : GoSub BCD_To_Byte: Uren = Byte_Uit 'Datum BCD_In = Datum : GoSub BCD_To_Byte: Datum = Byte_Uit 'Maand BCD_In = Maand : GoSub BCD_To_Byte: Maand = Byte_Uit 'Jaar BCD_In = Jaar : GoSub BCD_To_Byte: Jaar = Byte_Uit 'Temperatuur Temperatuur.7 = 0 Return BCD_To_Byte: 'Hoogste 4 bits omzetten (Tientallen) Byte_Uit = 0 Byte_Uit.0 = BCD_In.4 Byte_Uit.1 = BCD_In.5 Byte_Uit.2 = BCD_In.6 Byte_Uit.3 = BCD_In.7 Byte_Uit = Byte_Uit * 10 'Laagste 4 bits omzetten (Eenheden) BCD_In.4 = 0 BCD_In.5 = 0 BCD_In.6 = 0 BCD_In.7 = 0 Byte_Uit = BCD_In + Byte_Uit Return
Declaraties voor dit werkend te krijgen:
'RTC Symbol DS_SDA = PORTA.0 Symbol DS_SLC = PORTA.1 Symbol DS_Reset = PORTA.2 Dim Seconden As Byte Dim Minuten As Byte Dim Uren As Byte Dim Dag As Byte Dim Datum As Byte Dim Maand As Byte Dim Jaar As Byte Dim Temperatuur As Byte Symbol Reg_Seconden = $00 Symbol Reg_Minuten = $01 Symbol Reg_Uren = $02 Symbol Reg_Dag = $03 Symbol Reg_Datum = $04 Symbol Reg_Maand = $05 Symbol Reg_Jaar = $06 Symbol Reg_Temp = $11 Symbol Lezen = %11010000 Symbol Schrijven = %11010001 '************************************************************ 'Subroutine Dim BCD_In As Byte Dim Byte_Uit As Byte
Het wegschrijven:
Dit gebeurd hetzelfde als het inlezen alleen wordt hier het I2COUT commando gebruikt en schrijven inplaats van lezen in het control adres.
Zo krijg je bijvoorbeeld deze code:
I2COUT DS_SDA, DS_SLC, Schrijven ,Reg_Minuten, [Minuten]
LET OP: De data moet hier weer bcd worden weggeschreven.