Francis Schumacher
/
nRF51_rtc_example
This program is an example of an attempt at a Real Time Clock on the nRF51-DK.
main.cpp@1:c1f06d0a5e11, 2015-02-08 (annotated)
- Committer:
- fxschumacher
- Date:
- Sun Feb 08 01:45:35 2015 +0000
- Revision:
- 1:c1f06d0a5e11
- Parent:
- 0:8a9f15c4effd
Example program for using a Real Time Clock with the nRF51-DK.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fxschumacher | 0:8a9f15c4effd | 1 | /* |
fxschumacher | 0:8a9f15c4effd | 2 | This example code shows one way of creating a real time clock for the nRF51 without interfering with the mbed library functions |
fxschumacher | 0:8a9f15c4effd | 3 | |
fxschumacher | 0:8a9f15c4effd | 4 | Two methods are created to replace the similarly named C routines: rtc.time and rtc.set_time. |
fxschumacher | 0:8a9f15c4effd | 5 | If the rtc.time method isn't called frequently (< 512 seconds between calls), a ticker (from the mbed library) is required |
fxschumacher | 0:8a9f15c4effd | 6 | to keep the time updated. |
fxschumacher | 0:8a9f15c4effd | 7 | |
fxschumacher | 0:8a9f15c4effd | 8 | In this example, LED2 toggles and the time is printed when button1 is pushed. LED1 will toggle when the time is periodically updated. |
fxschumacher | 0:8a9f15c4effd | 9 | |
fxschumacher | 0:8a9f15c4effd | 10 | references: |
fxschumacher | 0:8a9f15c4effd | 11 | -- see NRF_RTC_Type in nrf51.h |
fxschumacher | 0:8a9f15c4effd | 12 | (e.g.: http://developer.mbed.org/users/mbed_official/code/mbed-src/file/12a9a5f8fea0/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/nrf51.h) |
fxschumacher | 0:8a9f15c4effd | 13 | -- see "nRF51 Series Reference Manual" chapter on Real Time Counter (chapter 19 in V3.0) |
fxschumacher | 0:8a9f15c4effd | 14 | Note: RTC2 does not exist, despite what the nrf51 reference manual (V3.0) claims. The other RTCs (0/1) are used by various other libraries, |
fxschumacher | 0:8a9f15c4effd | 15 | so you can read, but don't write! |
fxschumacher | 0:8a9f15c4effd | 16 | |
fxschumacher | 0:8a9f15c4effd | 17 | */ |
fxschumacher | 0:8a9f15c4effd | 18 | |
fxschumacher | 0:8a9f15c4effd | 19 | #include "mbed.h" |
fxschumacher | 0:8a9f15c4effd | 20 | #include "nrf51_rtc.h" |
fxschumacher | 0:8a9f15c4effd | 21 | |
fxschumacher | 0:8a9f15c4effd | 22 | // used for the example only, not required for rtc use |
fxschumacher | 0:8a9f15c4effd | 23 | DigitalOut rtc_update_led(LED1); // toggle when update_rtc is called |
fxschumacher | 0:8a9f15c4effd | 24 | DigitalOut button_push_led(LED2); // toggle when button1 is pushed |
fxschumacher | 0:8a9f15c4effd | 25 | DigitalIn button1(BUTTON1); // used to trigger the time report |
fxschumacher | 0:8a9f15c4effd | 26 | InterruptIn button1Press(BUTTON1); |
fxschumacher | 0:8a9f15c4effd | 27 | Serial pc(USBTX,USBRX); |
fxschumacher | 0:8a9f15c4effd | 28 | |
fxschumacher | 0:8a9f15c4effd | 29 | time_t example_time() { |
fxschumacher | 0:8a9f15c4effd | 30 | // set an intial time |
fxschumacher | 0:8a9f15c4effd | 31 | // ...not really necessary for this example, but it beats setting it to 0 or some non-obvious large integer (# of seconds since 1/1/1970) |
fxschumacher | 0:8a9f15c4effd | 32 | time_t rawtime=0; |
fxschumacher | 0:8a9f15c4effd | 33 | |
fxschumacher | 0:8a9f15c4effd | 34 | struct tm * init_timeinfo; |
fxschumacher | 0:8a9f15c4effd | 35 | |
fxschumacher | 0:8a9f15c4effd | 36 | // initialize time |
fxschumacher | 0:8a9f15c4effd | 37 | init_timeinfo = localtime(&rawtime); // note: must initialize the struct with this before trying to set components |
fxschumacher | 0:8a9f15c4effd | 38 | // ...else code goes into the weeds!! |
fxschumacher | 0:8a9f15c4effd | 39 | init_timeinfo->tm_sec = 0; |
fxschumacher | 0:8a9f15c4effd | 40 | init_timeinfo->tm_min = 10; |
fxschumacher | 0:8a9f15c4effd | 41 | init_timeinfo->tm_hour = 17; |
fxschumacher | 0:8a9f15c4effd | 42 | init_timeinfo->tm_mon = 1; |
fxschumacher | 0:8a9f15c4effd | 43 | init_timeinfo->tm_mday = 7; |
fxschumacher | 0:8a9f15c4effd | 44 | init_timeinfo->tm_year = 2015 - 1900; |
fxschumacher | 0:8a9f15c4effd | 45 | |
fxschumacher | 0:8a9f15c4effd | 46 | char date[24]; |
fxschumacher | 0:8a9f15c4effd | 47 | strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",init_timeinfo); |
fxschumacher | 0:8a9f15c4effd | 48 | pc.printf("Initial time set is %s.\r\n",date); |
fxschumacher | 0:8a9f15c4effd | 49 | |
fxschumacher | 0:8a9f15c4effd | 50 | // compute the proper value for time in time_t type |
fxschumacher | 0:8a9f15c4effd | 51 | rawtime = mktime(init_timeinfo); |
fxschumacher | 0:8a9f15c4effd | 52 | return rawtime; |
fxschumacher | 0:8a9f15c4effd | 53 | } |
fxschumacher | 0:8a9f15c4effd | 54 | void print_time() { |
fxschumacher | 0:8a9f15c4effd | 55 | // called when a button is pushed, this prints the current time to the USB-connected console |
fxschumacher | 0:8a9f15c4effd | 56 | button_push_led = !button_push_led; |
fxschumacher | 0:8a9f15c4effd | 57 | |
fxschumacher | 0:8a9f15c4effd | 58 | time_t rawtime=rtc.time(); |
fxschumacher | 0:8a9f15c4effd | 59 | |
fxschumacher | 0:8a9f15c4effd | 60 | // massage the time into a human-friendly format for printing |
fxschumacher | 0:8a9f15c4effd | 61 | struct tm * timeinfo; |
fxschumacher | 0:8a9f15c4effd | 62 | timeinfo = localtime(&rawtime); |
fxschumacher | 0:8a9f15c4effd | 63 | char date[24]; |
fxschumacher | 0:8a9f15c4effd | 64 | strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo); |
fxschumacher | 0:8a9f15c4effd | 65 | pc.printf("The current time is %s.\r\n",date); |
fxschumacher | 0:8a9f15c4effd | 66 | } |
fxschumacher | 0:8a9f15c4effd | 67 | |
fxschumacher | 0:8a9f15c4effd | 68 | // (probably) required for rtc use |
fxschumacher | 0:8a9f15c4effd | 69 | void update_rtc() { |
fxschumacher | 0:8a9f15c4effd | 70 | // for use as interrupt routine, to insure that RTC is updated periodically |
fxschumacher | 0:8a9f15c4effd | 71 | // ...if rtc is not read before the underlying counter rolls over (typically 512 seconds), the RTC value will be wrong |
fxschumacher | 0:8a9f15c4effd | 72 | // ...ideally this would be done as part of the nrf51_rtc method, but I couldn't get it to behave (see nrf51_rtc.cpp for details) |
fxschumacher | 0:8a9f15c4effd | 73 | rtc.time(); |
fxschumacher | 0:8a9f15c4effd | 74 | rtc_update_led = !rtc_update_led; |
fxschumacher | 0:8a9f15c4effd | 75 | } |
fxschumacher | 0:8a9f15c4effd | 76 | |
fxschumacher | 0:8a9f15c4effd | 77 | |
fxschumacher | 0:8a9f15c4effd | 78 | int main(void) |
fxschumacher | 0:8a9f15c4effd | 79 | { |
fxschumacher | 0:8a9f15c4effd | 80 | rtc_update_led=0; |
fxschumacher | 0:8a9f15c4effd | 81 | button_push_led=0; |
fxschumacher | 0:8a9f15c4effd | 82 | |
fxschumacher | 0:8a9f15c4effd | 83 | // user selectable, any time < 512 seconds is OK |
fxschumacher | 0:8a9f15c4effd | 84 | #define PERIODIC_UPDATE 1 |
fxschumacher | 0:8a9f15c4effd | 85 | Ticker rtc_ticker; |
fxschumacher | 0:8a9f15c4effd | 86 | rtc_ticker.attach(&update_rtc, PERIODIC_UPDATE); // update the time regularly |
fxschumacher | 0:8a9f15c4effd | 87 | |
fxschumacher | 0:8a9f15c4effd | 88 | time_t initial_time = example_time(); |
fxschumacher | 0:8a9f15c4effd | 89 | rtc.set_time(initial_time); |
fxschumacher | 0:8a9f15c4effd | 90 | |
fxschumacher | 0:8a9f15c4effd | 91 | button1Press.fall(&print_time); // when button1 is pressed, this calls rtc.time() and prints it |
fxschumacher | 0:8a9f15c4effd | 92 | |
fxschumacher | 0:8a9f15c4effd | 93 | while (true) { |
fxschumacher | 0:8a9f15c4effd | 94 | sleep(); |
fxschumacher | 0:8a9f15c4effd | 95 | } |
fxschumacher | 0:8a9f15c4effd | 96 | } |
fxschumacher | 0:8a9f15c4effd | 97 |