How do i convert bcd values to decimal, and decimal to bcd.
eg bcd :0010 0011 = 23
how would i convert that to 23 in decimal
How do i convert bcd values to decimal, and decimal to bcd.
eg bcd :0010 0011 = 23
how would i convert that to 23 in decimal
Shift right is one way.
This should in theory take the 4 Highbits and shift them right 4 times. Then multiply this result with 10 and add the 4 low bits putting the result in DEC_Out.Code:DEC_Out Var Byte BCD_In Var Byte DEC_Out=(BCD_In>>4*10)+(BCD_In & %00001111)
To do the DEC to BCD you can use the DIG command it is really good for this.
HI thanks that works great
i'm using a real time clock and the only issue i have now is that when seconds reaches 40 the hours increments to 40
the hour register is only 6 bits long bits 6 and 7 are not used, would i have to shift by less than 4 compared to the other registers
Real Time Clock, show us the code and we can advice. Or search the forum because most RTC has code examples or parts of examples that you can reuse in an easy way.
Many RTC has mixed registers so you have to do some woodoo activities to sort out the information you want from it![]()
Code:@ device pic16f870,WDT_OFF 'Watch Dog Timer Disabled @ device pic16f870,PROTECT_OFF 'Code Protect Off @ device pic16f870,XT_OSC 'Using External Oscillator @ device pic16f870,BOD_OFF 'Brown Out Timer Disabled @ device pic16f870,PWRT_OFF 'Power On Timer Disabled @ device pic16f870,LVP_OFF 'Low Voltage Programmed Disabled DEFINE OSC 4 ADCON0.0=0 ADCON1=7 ' ALL PINS SET TO DIGITAL TRISB = %00000000 TRISA = %00000000 TRISC.0=0 'rtc pins clk_pin var portc.5 data_pin var portc.6 number var word display VAR PORTB segment var PORTA seg_number var byte digit var byte delay var word 'register address's reg_seconds CON $02 reg_minutes con $03 reg_hours con $04 reg_days con $05 reg_weekdays con $06 reg_months_century con $07 reg_years con $08 reg_minute_alarm con $09 reg_hour_alarm con $0A reg_day_alarm con $0B reg_weekday_alarm con $0C rtc_write var byte rtc_read var byte rtc_write=$a2 rtc_read=$a3 'time variables bcdseconds var BYTE bcdminutes var BYTE bcdhours var BYTE bcddays var BYTE bcdyears var BYTE seconds var BYTE minutes var BYTE hours var BYTE days var BYTE years var BYTE '----------------------------------------------------- 'initial time variable values seconds=01 minutes=23 hours=22 'days=23 'years=7 ' ------------------------------------------------------- 'write intial variable's to the relevant rtc registers init: bcd_encode: bcdseconds=seconds dig 1 bcdseconds=bcdseconds<<4 bcdseconds=bcdseconds+seconds dig 0 bcdminutes=minutes dig 1 bcdminutes=bcdminutes<<4 bcdminutes=bcdminutes+minutes dig 0 bcdhours=hours dig 1 bcdhours=bcdhours<<3 bcdhours=bcdhours+hours dig 0 pause 10 I2CWrite data_pin,clk_pin,$A2,reg_seconds,[bcdseconds,bcdminutes,bcdhours] pause 100 clock_read: I2CRead data_pin,clk_pin,$A3,reg_seconds,[bcdseconds,bcdminutes,bcdhours] pause 10 bcd_decode: 'decodes bcd to decimal seconds=(bcdseconds>>4)*10+(bcdseconds & %00001111) minutes=(bcdminutes>>4)*10+(bcdminutes & %00001111) hours=(bcdhours>>3)*10+(bcdhours & %00000111) OUT: pause 20 serout2 portc.1,16780,[" ",#hours,":", #minutes,":",#seconds] PORTC.0=1 PAUSE 100 PORTC.0=0 goto clock_read
does anyone have any ideas?
when the seconds register is equal to 40, the "tens" of the hours register becomes 4 (e.g 09 then changed to 49 when seconds becomes 40) the hours "tens" then returns to its correct value once seconds is smaller than 40 again.
here is an example, i am debugging using hyperterminal:
hours:minutes:seconds
9(9):22(22):38(38)
9(9):22(22):39(39)
49(49):22(22):40(40)
the values in the brackets are the bcd values straight from the registers without being ran through any conversion routines, i then output them using the HEX modifier.
Last edited by -Dan-; - 23rd May 2009 at 03:30.
I am sorry I don't have that RTC here so I can test code for you yet.
There are some things in your code that are inconsistent with the datasheet so you should start with fixing this.
Please look at http://www.datasheetcatalog.org/data...s/PCF8563P.pdf Table 5. As you see the Seconds register is only 7 bits wide and not 8, the 8th bit is VL. So start by making sure that bit is not included in you conversion and setting of the RTC.
Are you sure you chip is healty? Have you tested this on more than one RTC?
Please forgive me for asking, but is this related to this previous 2007 posting?http://www.picbasic.co.uk/forum/arch...hp/t-7567.html
In that case I can only say you have had this problem for some time and then it is really time to solve this.
I will swing by the market some day and pick up a chip so I can help you better.
hey,
yer that is an old topic i kinda give up some time ago on the rtc.
But i tought i would pick it back up and finally get my head around it
when i posted that topic i didn't even no what bcd was... so as you can imagine i didn't get any were near as far as i have now.
i am watching the value of the seconds register and it is incrementing correctly from 0-59 and the minutes are incrementing when the seconds reaches 0
i'll look in to the voltage low bit in the seconds register and see if that is the cause of my problem, i'll let you know how i get on.
and yes ive tried another one of these rtc and get the same error
thanks for taking the time to help me
Last edited by -Dan-; - 23rd May 2009 at 12:53.
I've directly given the registers the bcd values and monitored the bcd value of the register as it changes but it still increase's the tens of the hours by 4 when seconds=40, i have not addressed the unused bits in the registers, so i cannot see it being that.
i am lost for ideas
Code:@ device pic16f870,WDT_OFF 'Watch Dog Timer Disabled @ device pic16f870,PROTECT_OFF 'Code Protect Off @ device pic16f870,XT_OSC 'Using External Oscillator @ device pic16f870,BOD_OFF 'Brown Out Timer Disabled @ device pic16f870,PWRT_OFF 'Power On Timer Disabled @ device pic16f870,LVP_OFF 'Low Voltage Programmed Disabled DEFINE OSC 4 ADCON0.0=0 ADCON1=7 ' ALL PINS SET TO DIGITAL TRISB = %00000000 TRISA = %00000000 TRISC.0=0 'rtc pins clk_pin var portc.5 data_pin var portc.6 number var word display VAR PORTB segment var PORTA seg_number var byte digit var byte delay var word 'register address's reg_seconds CON $02 reg_minutes con $03 reg_hours con $04 reg_days con $05 reg_weekdays con $06 reg_months_century con $07 reg_years con $08 reg_minute_alarm con $09 reg_hour_alarm con $0A reg_day_alarm con $0B reg_weekday_alarm con $0C rtc_write var byte rtc_read var byte rtc_write=$a2 rtc_read=$a3 'time variables bcdseconds var BYTE bcdminutes var BYTE bcdhours var BYTE bcddays var BYTE bcdyears var BYTE seconds var BYTE minutes var BYTE hours var BYTE days var BYTE years var BYTE '----------------------------------------------------- 'initial time variable values seconds=%0100011 minutes=%0100011 hours=%100011 'days=23 'years=7 ' ------------------------------------------------------- 'write intial variable's to the relevant rtc registers init: 'bcd_encode: 'bcdseconds=seconds dig 1 'bcdseconds=bcdseconds<<4 'bcdseconds=bcdseconds+seconds dig 0 'bcdminutes=minutes dig 1 'bcdminutes=bcdminutes <<4 'bcdminutes=bcdminutes+minutes dig 0 'bcdhours=hours dig 1 'bcdhours=bcdhours<<4 'bcdhours=bcdhours+hours dig 0 pause 10 I2CWrite data_pin,clk_pin,$A2,reg_seconds,[seconds,minutes,hours] pause 100 clock_read: I2CRead data_pin,clk_pin,$A2,reg_seconds,[bcdseconds,bcdminutes,bcdhours] pause 10 'bcd_decode: 'decodes bcd to decimal 'seconds=(bcdseconds>>4)*10+(bcdseconds & %00001111) 'minutes=(bcdminutes>>4)*10+(bcdminutes & %00001111) 'hours=(bcdhours>>4)*10+(bcdhours & %00001111) OUT: pause 20 serout2 portc.1,16780,["(",HEX bcdhours,")","(",HEX bcdminutes,")","(",HEX bcdseconds,")"] PORTC.0=1 PAUSE 100 PORTC.0=0 goto clock_read
OK this is a declaration of warI will go to the market tomorrow and get me a few of these RTC chips. Really, it has to be something simple because it almost always is but this has to be solved.
Please post a picture of your connections so I can connect in a similar way.
Bookmarks