HW8 - ndm736/ME433_2020 GitHub Wiki
Many microcontrollers have a peripheral for keeping track of time on a more human time scale, like a watch. This peripheral is called the Real Time Clock and Calendar, or RTCC. The RTCC takes an input from a 32.768kHz clock, and keeps track of the time with 0.5 second sensitivity, including the year, month, day, and day of week. The accuracy is dependent on the clock source, and can be calibrated to become accurate to within a few seconds per month (or year? depends on the clock source). Many brands also support a battery voltage input to the microcontroller that powers only the RTCC peripheral, so that even if the microcontroller is unplugged, the time is not lost and keeps ticking.
Some versions of the PIC32MX contain the clock source internally, but the PIC32MX170F256B does not. To get 32.768kHz, we need to use an external crystal resonator attached to the secondary oscillator input pins. Unfortunately those pins are B4 and A4, the pins that we have been using for a user LED and user button, so we'll have to move those. I moved my LED to B5 and button to B7.
The crystal I've included in the kit does not include what are called the load capacitors, and was not a good choice for a breadboard application (sorry about that!) The datasheet for the crystal calls for 12pF caps from SOSCI and SOSCO to GND, and you only have 10pF, so use 2 in parallel for 20pF on each pin.
To use the RTCC, you must enable the Secondary Oscillator in the #pragma area of your code (FSOSCEN). Then you can use the RTCC example code to initialize the peripheral. Note that the initialization is a little different than other peripherals, because we need to change how a clock works while the PIC is running. To do this, the value of the SYSKEY register is set a few times, which unlocks the CPU and allows for changes to the clock system.
I have made a function that initializes the RTCC and sets the date and time. Every time you reset the PIC it will return to this hard coded time, so another good function to write would be one that reads from some buttons and lets you change the time on the fly (I'll leave that to you). The date and time are stored using binary coded decimal encoding. Each character of "time" is stored individually, which is a little weird (so 09:15:00am is a 0, a 9, a 1, a 5, a 0, and a 0). Take a look at the RTCDATE and RTCTIME registers in the RTCC chapter of the reference manual to see how many bits each character is given. This format makes it hard to get the time in and out of the registers, but easier to set the time in one big hex number. For RTCTIME, the 32bit unsigned int uses 2 hex characters for each section of time (the format is 0xHrMnSe00) and RTCDATE (0xYrMnDyWk, where Wk is 0 for Sunday, 1 for Monday, ..., and 6 for Saturday). For example, RTCTIME = 0x13254500 sets the time to 1pm, 25 minutes and 45 seconds (note that this is all 24Hr time, also called military time). RTCDATE = 20052602 sets the date to Tuesday, May 26, 2020.
The function rtcc_setup() takes two hex numbers to initialize the time. Your job is to read the time and display it on your display. In rtcc.h I created a structure to store the BCD time, and a function to return it. You should finish this function, or make your own. I also made an array of character arrays that store the name of the day of the week.
xc.h has provided a structure for pulling the BCD characters out of the RTCTIME and RTCDATE SFR. For example, the minutes are in RTCTIMEbits.MIN10 and RTCTIMEbits.MIN01. Use these fields to complete the function and write the time to the display.
Update the display at 2Hz, writing a number to the screen with each update that increments by one so you can tell that the code is working. Upload your code to a folder named HW8 in your repo and make a short video demonstrating your clock display. Breadboard problems: On a printed circuit board this probably works with no problems, but on a breadboard there is a lot of stray capacitance and noise, and I didn't give you close enough values for the load capacitors, so the secondary oscillator doesn't always start, and sometimes randomly stops ticking. I found that touching the crystal added enough shock to the system to wake up the oscillator and keep it going long enough to complete the assignment. Don't worry if it isn't too stable, this isn't the right way to prototype this circuit in the long run, just try to get it to work long enough for the demo.