Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Using ThePCF8563 RTC with MMBasic
Author | Message | ||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Hi All, I have built my own pcb with a PIC32 and an RTC using the PCF8563 RTC Chip. I am able to read the RTC ok through the I2C bus but seem unable to write to it. Has anybody out there got any sample code that they have used to access the PCF8563 on the I2C bus? I have MMBasic 3.2A loaded. Thanks Dave |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi Dave Here is all you need http://www.thebackshed.com/forum/forum_posts.asp?TID=3790&KW =jman Regards John |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks for that john, but this is for the DS1307 RTC, without sifting through reams of Data sheets, I'm not sure if they are the same..... Dave |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi Scroll to the second page of that thread I used a PCF8563 Code is posted in the same thread John |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
First set the time and date on the maximite. Then run this.... 600 ' Get time from time$ and date$ 610 tempdec = VAL(LEFT$(TIME$, 2)) 615 GOSUB 1100 617 hours = hex 620 tempdec = VAL(MID$(TIME$, 4, 2)) 625 GOSUB 1100 627 minutes = hex 630 tempdec = VAL(RIGHT$(TIME$, 2)) 635 GOSUB 1100 637 seconds = hex 640 tempdec = VAL(LEFT$(DATE$, 2)) 645 GOSUB 1100 647 day = hex 650 tempdec = VAL(MID$(DATE$, 4, 2)) 655 GOSUB 1100 657 month = hex 660 tempdec = (VAL(RIGHT$(DATE$, 4)) - 2000) 665 GOSUB 1100 667 year = hex 670 ' rtcctrl = &h10 680 rtcwday= &h1 690 ' Write Time to RTC 700 i2caddr = &h51 ' PCF8563 I2C address 710 I2CEN 100,100 ' Enable I2C 725 I2CSEND i2caddr, 0, 10, 0, 0, 0, seconds, minutes, hours, day, rtcwday, month, year 730 I2CDIS 770 ? "0=ok 1=nack 2=timeout ";MM.I2C 780 END 1100 ' Convert to Hex 1110 hex = FIX(tempdec / 10) * 16 1120 hex = hex OR ((tempdec / 10) - (FIX(tempdec / 10))) * 10 1140 RETURN This will set the 8563 to the Maximite time/date. This is all part of the forum that Jman pointed to. Have fun centrex Cliff |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3801 |
Would be wiser for 1120 to be 1120 hex = hex OR (tempdec - FIX(tempdec / 10) * 10) It's because it's unwise to assume that tempdec / 10 * 10 (which is what the original ends up using) results in the number desired! Saves a division, too, so will be faster and smaller. OTOH it's a bit odd to be converting a string to decimal and then hex when it could be done directly to hex... John |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks John, Brilliant service, will try it out tomorrow when I have a bit more time. Dave |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks to Centrex too......... |
||||
BobD Guru Joined: 07/12/2011 Location: AustraliaPosts: 935 |
I see the code posted by Centrex in a lot of places. It's like a signature. Someone wrote it way back for RTCs in C and then someone converted it to BASIC. I guess it works for all BASICS. The Maximite Basic can do it easier because it has integer divide (\) and remainder divide (MOD). As an example, the code above at 650 to 657 can be simplified down to: ' get month number
x = VAL(MID$(DATE$, 4, 2)) month = x\10*16 + x mod 10 similarly when reading the RTC and extracting the Packed BCD (a number in each Nibble or 4 bits of a byte) and converting it to an integer and then to a string, you can do: ' get seconds - range 00 - 59, 7 bits, mask 0x7F
Seconds$=str$((RTCdata(0) and &H70)\16*10 + (RTCdata(0) and &H0F)) Integer divide again simplifies the conversion. The above was for reading a DS3231 RTC. The data for seconds may end up in a different byte of the array RTCdata() when you read another RTC. The MASK is used both to separate the Nibbles and to exclude bits in the RTC register that are unused or used for another function in the particular register. |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
a faster way of converting a Packed BCD to a string: (This is actually the reason why RTC chips return values in BCD, when displaying on hardware you don't need to calculate much just put it on an output port, like to a 2 digit 7-segment display via bcd to 7-segment decoders.) ' RTCdata(0) contains 23 (decimal) 17 (hex) 0001 0111 (BCD nibbles) -> 17 seconds Seconds$ = hex$(RTCdata(0)) ' Seconds$ will be "17" This does not need any extra math. i have modified the hex$ function to accept a minimumlength parameter. That makes it easy to have a leading zero. I use it like this: Seconds$ = hex$(RTCdata(0), 2) ' if seconds is lower than 10 the result will have one leading zero There are many ways to get the same end result. I often use different ways and profile them for speed. I don't have a Maximite yet maybe someone can test which one is the fastest. From decimal to BCD is also pretty easy: ' when date$ has 17 as the seconds part hex = val("&H" + LEFT$(DATE$, 2)) ' hex will be 23 (decimal) or 17 (hex) and in nibbles 0001 0111 Microblocks. Build with logic. |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks to all of your help, I have managed to get it working, Phew!! So the code I am using is fine which is derived from the code suggested, however, I have come across a hardware problem thet I don't quite understand, if I connect the two pull up resistors for the I2C bus to the RTC chip's VDD then it works great, if I connect them to +3.3v, before the diode, then it doesn't work. The PCF8563 data sheet says that they should be connected to +3.3V for obvious reasons, it could drain the RTC battery if connected to the chip VDD. Unfortunately, I don't have a storage scope to look at the signals, only a real time one. I also notice that the Olimex MOD-RTC board has the pull ups connected to the Chip VDD, maybe they had the same problem that I have had?........... any comments? Once again, thanks for all your help......Dave |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
It would appear from the data sheet that the 8563 draws about 550na when the device is not being accessed so it is probably not a problem. When you do access the device power would come from the calling computer. regards cliff Cliff |
||||
BobD Guru Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Regarding the pullup resistors. If you are running at 400KHz then try running it at 100KHz instead. What size are the pullup resistors? There is a discussion here about sizing pullups and setting the speed of the bus. It's open to interpretation but the way I read it is size resistors on the low side and same for the speed, if you run into problems. |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks for the link about pull up resistors. I am running at 100kHz and using 10k resistors as recommended in the MMBasic manual, and it is all working great now, but the main question was about where to connect the top end of the pull ups. If I connect to VCC (3.3V) then I can't read the RTC, if I connect to chip VCC the it works fine, but it begs the question, will that drain the RTC battery prematurely? The OLIMEX Duinomite rtc ext board has them connected to the chip (therefore the RTC battery) but in the RTC data sheet it clearly says to connect them to VCC before the diode (which doesn't work for me) Whether it does drain or not depends on the MM pins 12 & 13 and whether the PIC minds having these held up when it has no power connected........ Dave |
||||
BobD Guru Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Dave if you want battery operation (who doesn't?) you have to have those resistors away from the chip. I would try 4.7K resistors and even go as low as 2.2K to try and get it working. I have a DS3231 RTC permanently connected with 4.7K resistors. Even with 2.2K resistors they only carry 1.5mA and the PIC can handle up to 25mA on a pin. |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Thanks for that Bob, I will try some lower value resistors and see if it works. I guessed that it should work with the pull ups on the other side, but don't understand why it doesn't. Will have a play around and let you know. Won't be for a couple of days as I have to do some work sometime!! Dave |
||||
davefaw Newbie Joined: 06/05/2012 Location: United KingdomPosts: 8 |
Great working fine now with the pull-ups on the correct side of the diode. Found that the 100n decoupler at that point was cracked........... replaced it and it all works fine with the 10k pull ups. Thanks everybody for your help. Dave |
||||
Print this page |