New object added.... NXP PCF8583 Real Time Clock
photomankc
Posts: 943
Just putting the word out that it's there. I ended up ordering this because was about all that was left when I searched Mouser for an I2C Interface, DIP Package, 3.3V, with at least a 1Hz square wave output to add to my last order. So I ended up having to write my own driver for it since it packs a few of the counters together in several registers differently than the DS clocks.
I have tested the basic getting and setting functions and the cog-counter tracking of the square wave which all seems to be working but I have not tested much with the alarm registers.
I started out initially with Kye's code from the DS1307 but for some reason his I2C routines and Basic_I2C_Driver would not get along when used together in a project which I required to continue to use my EEPROM data access functions. So I ended up ripping out a portion of Basic_I2C and transplanting it into the RTC driver and it now works along with Basic_I2C in the same project but about 30% slower. Kye's code was fast so eventually I'd like to figure out why they would not work together.
The PCF8583 doesn't have a 99 year counter for the year, for whatever reason they only included a 4 year counter (0=leap-year). My use would be ok with this but I went ahead and used the leftover RAM to setup a way around the limitation. Calling SetYear will take the year and compute where it is in the leap-year cycle and store that in the RTC counter. It also stores the full year in RAM. Calling GetYear returns the year stored in RAM only. Calling CorrectYear on some schedule (more frequent than one year) will increment the year stored in RAM with the counter. This lets me use the year more easily. SetYearRaw\GetYearRaw deal only with the RTC counter if that's desired.
Anyway, just letting folks know it's out there as another RTC option. I'm using it in my Thermostat project so if I run into any bugs I'll fix those in the obex post.
Any and all feedback welcome.
obex.parallax.com/objects/530/
I have tested the basic getting and setting functions and the cog-counter tracking of the square wave which all seems to be working but I have not tested much with the alarm registers.
I started out initially with Kye's code from the DS1307 but for some reason his I2C routines and Basic_I2C_Driver would not get along when used together in a project which I required to continue to use my EEPROM data access functions. So I ended up ripping out a portion of Basic_I2C and transplanting it into the RTC driver and it now works along with Basic_I2C in the same project but about 30% slower. Kye's code was fast so eventually I'd like to figure out why they would not work together.
The PCF8583 doesn't have a 99 year counter for the year, for whatever reason they only included a 4 year counter (0=leap-year). My use would be ok with this but I went ahead and used the leftover RAM to setup a way around the limitation. Calling SetYear will take the year and compute where it is in the leap-year cycle and store that in the RTC counter. It also stores the full year in RAM. Calling GetYear returns the year stored in RAM only. Calling CorrectYear on some schedule (more frequent than one year) will increment the year stored in RAM with the counter. This lets me use the year more easily. SetYearRaw\GetYearRaw deal only with the RTC counter if that's desired.
Anyway, just letting folks know it's out there as another RTC option. I'm using it in my Thermostat project so if I run into any bugs I'll fix those in the obex post.
Any and all feedback welcome.
obex.parallax.com/objects/530/
Comments
They won't ever work togeter.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (photomankc) : 10/26/2009 7:25:29 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Thanks... couple of questions though.
I don't understand your addressing clearly.· You take %1010 and shift left 4 to make %10100000 so it appears the I2C address is fixed at A0?· Why not just let me specify the whole address?· If I want to do that·can I just pull out your << 4 on each EEPROM_Address entry?··Looking it appears the | 1 would handle the write/read bit.· I'd really like to have the option to specify which device to read from when I do the read rather than hard-code that but I'd be a little lost on adding that in.
I also don't get the EEPROM_Address >> 15 part?· So if I want to access·location 35698 thats %1000101101110010 and if I shift that right 15 doesn't that just leave me at 1?· You got a lot going on in one line of code and it's hard for me to follow it maybe I'm missing something going on there later on.·
So, read the preface for the basic I2C driver to see what I'm doing and the functions in it. Basically the %1010 is your base eeprom adress. Then you can have 19th bit addressing where the top three bits select the device from everything with $A0 ... $A1 ... $A2 ... $A3. And then the last 16 bits selects the data.
So the eeprom address 15 part gets the top 3 bits. Its 15 and not 16 because the last bit needs to be 1 or 0 for read or write. That's also why I'm using $E as a mask.
...
Hey if this code works good please tell me because I really haven't tested it much. I believe its functional but I haven't really broken it in.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
EEPROM_Address %1010 becomes: %10100000
EEPROMAddress %001_1000000000000001 becomes: %00000011
AND EEPROMAddress with: %00001110
results in: %00000010
So OR EEPROM_Address with the Final result made from EEPROMAddress and you get:
%10100010 == $A2
So you made it possible to select the device by adding the final three bits as a prefix to the normal memory address and thus the shift 15 to the right, so you could plop them into the proper position to be OR'd with the constant high nibble of the device address.
I'm still a total newb to all this bit-twiddling stuff so I have to really take my time to understand it. Neat though.
Post Edited (photomankc) : 10/29/2009 2:19:23 PM GMT