0

I am reading seconds from a real time counter as BCD data, the 7th bit isn't used for this.

PCF seconds bit registers

Using similar samples online I was able to convert the uint8_t BCD data to human readable (0 - 59) seconds.

#define PCF8563_BCD_LOWER_MASK 0x0f
#define PCF8563_BCD_UPPER_MASK_SEC 0x70
#define PCF8563_BCD_UPPER_SHIFT 4

uint8_t raw_seconds = get_raw_seconds();
int seconds = (raw_seconds & PCF8563_BCD_LOWER_MASK) + (((raw_seconds & PCF8563_BCD_UPPER_MASK_SEC) >> PCF8563_BCD_UPPER_SHIFT) * 10);

I'd like to do the same for minutes, hours, etc, (they're all also in BCD format). I feel like I know what to do; shift/remove the 7th bit (for minutes) and convert BCD to Decimal - but I can't figure how to do this in code.

Converting from BCD to decimal isn't exactly the problem (there's a function for that), the shifting/removing of unused bits is throwing me off.

exile97
  • 317
  • 3
  • 10
  • 1
    You want to remove (or rather, ignore) bit 7 and keep bits 6-0. Consider which bit mask can accomplish that. You don't need to shift anything. – mkrieger1 May 10 '22 at 01:37
  • @mkrieger1 that's exactly what I needed, thank you. To clarify the code In my question was put together from other samples and I couldn't figure out how it worked. Bit masking is what I was looking for - I was looking into the wrong things. – exile97 May 10 '22 at 01:38

1 Answers1

0

Thanks to @mkrieger1 's comment I looked into bit masking and the solution was very simple.

For hours and minutes, the bit mask 0x7f/01111111 is used to only keep the first 7 bits, while if you want only 6 you simply use 0x3f/00111111, etc. The code remains the same, but the masks change.

exile97
  • 317
  • 3
  • 10