use DS1307 RTC

This commit is contained in:
King Kévin 2017-02-08 14:06:06 +01:00
parent 4c9f28f69f
commit 5e14d886ac
1 changed files with 56 additions and 7 deletions

63
main.c
View File

@ -43,6 +43,7 @@
#include "usart.h" // USART utilities
#include "usb_cdcacm.h" // USB CDC ACM utilities
#include "led_tm1637.h" // TM1637 7-segment controller utilities
#include "rtc_ds1307.h" // DS1307 RTC utilities
#define WATCHDOG_PERIOD 10000 /**< watchdog period in ms */
@ -102,6 +103,7 @@ static void process_command(char* str)
printf("available commands:\n");
printf("led [on|off|toggle]\n");
printf("time [HH:MM:SS]\n");
printf("date [YYYY-MM-DD]\n");
} else if (0==strcmp(word,"led")) {
word = strtok(NULL,delimiter);
if (!word) {
@ -118,6 +120,41 @@ static void process_command(char* str)
} else {
goto error;
}
} else if (0==strcmp(word,"time")) {
word = strtok(NULL,delimiter);
if (!word) {
printf("current time: %02u:%02u:%02u\n", rtc_ds1307_read_hours(), rtc_ds1307_read_minutes(), rtc_ds1307_read_seconds()); // get and print time from external RTC
} else if (strlen(word)!=8 || word[0]<'0' || word[0]>'2' || word[1]<'0' || word[1]>'9' || word[3]<'0' || word[3]>'5' || word[4]<'0' || word[4]>'9' || word[6]<'0' || word[6]>'5' || word[7]<'0' || word[7]>'9') { // time format is incorrect
goto error;
} else {
if (!rtc_ds1307_write_hours((word[0]-'0')*10+(word[1]-'0')*1)) {
printf("setting hours failed\n");
} else if (!rtc_ds1307_write_minutes((word[3]-'0')*10+(word[4]-'0')*1)) {
printf("setting minutes failed\n");
} else if (!rtc_ds1307_write_seconds((word[6]-'0')*10+(word[7]-'0')*1)) {
printf("setting seconds failed\n");
} else {
rtc_ds1307_oscillator_enable(); // be sure the oscillation is enabled
printf("time set\n");
}
}
} else if (0==strcmp(word,"date")) {
word = strtok(NULL,delimiter);
if (!word) {
printf("current date: 20%02u-%02u-%02u\n", rtc_ds1307_read_year(), rtc_ds1307_read_month(), rtc_ds1307_read_date());
} else if (strlen(word)!=10 || word[0]!='2' || word[1]!='0' || word[2]<'0' || word[2]>'9' || word[3]<'0' || word[3]>'9' || word[5]<'0' || word[5]>'1' || word[6]<'0' || word[6]>'9' || word[8]<'0' || word[8]>'3' || word[9]<'0' || word[9]>'9') {
goto error;
} else {
if (!rtc_ds1307_write_year((word[2]-'0')*10+(word[3]-'0')*1)) {
printf("setting year failed\n");
} else if (!rtc_ds1307_write_month((word[5]-'0')*10+(word[6]-'0')*1)) {
printf("setting month failed\n");
} else if (!rtc_ds1307_write_date((word[8]-'0')*10+(word[9]-'0')*1)) {
printf("setting day failed\n");
} else {
printf("date set\n");
}
}
} else {
goto error;
}
@ -174,16 +211,28 @@ void main(void)
}
#endif
// setup RTC
// setup internal RTC
printf("setup internal RTC: ");
rtc_auto_awake(RCC_LSE, 32768-1); // ensure internal RTC is on, uses the 32.678 kHz LSE, and the prescale is set to our tick speed, else update backup registers accordingly (power off the micro-controller for the change to take effect)
rtc_interrupt_enable(RTC_SEC); // enable RTC interrupt on "seconds"
nvic_enable_irq(NVIC_RTC_IRQ); // allow the RTC to interrupt
printf("OK\n");
// display uptime
uint32_t ticks_time = rtc_get_counter_val(); // get time from internal RTC (since first start/power up)
printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime
// setup external RTC
printf("setup external RTC: ");
rtc_ds1307_setup(); // setup external RTC module
printf("OK\n");
// verify is external RTC is running
if (rtc_ds1307_oscillator_disabled()) {
printf("/!\\ RTC oscillator is disabled: the battery may be empty\n");
}
// display date
uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
printf("current date: 20%02u-%02u-%02u %02u:%02u:%02u\n", rtc_ds1307_time[6], rtc_ds1307_time[5], rtc_ds1307_time[4], rtc_ds1307_time[2], rtc_ds1307_time[1], rtc_ds1307_time[0]);
// setup TM1637
printf("setup 7-segment display: ");
led_tm1637_setup();
@ -210,9 +259,6 @@ void main(void)
button_flag = false; // reset button flag
char c = '\0'; // to store received character
bool char_flag = false; // a new character has been received
if (!led_tm1637_on()) { // switch on display
fprintf(stderr,"could not switch on TM1637\n");
}
while (true) { // infinite loop
iwdg_reset(); // kick the dog
while (usart_received) { // data received over UART
@ -255,15 +301,18 @@ void main(void)
}
while (rtc_internal_tick_flag) { // the internal RTC ticked
rtc_internal_tick_flag = false; // reset flag
led_toggle(); // toggle LED (good to indicate if main function is stuck)
//led_toggle(); // toggle LED (good to indicate if main function is stuck)
ticks_time = rtc_get_counter_val(); // copy time from internal RTC for processing
action = true; // action has been performed
if ((ticks_time%(60))==0) { // one minute passed
printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime
}
if (!led_tm1637_time((ticks_time%(60*60))/60, ticks_time%60)) {
if (!led_tm1637_time(rtc_ds1307_read_minutes(), rtc_ds1307_read_seconds())) {
fprintf(stderr,"could not set time on TM1637\n");
}
if (!led_tm1637_on()) { // switch on display
fprintf(stderr,"could not switch on TM1637\n");
}
}
if (action) { // go to sleep if nothing had to be done, else recheck for activity
action = false;