This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP432P401R
Tool/software: Code Composer Studio
I have done one firmware where the user choose by hardware configuration adjust date and time. The problem is ... after the user adjust date and time I would like use the rtc to control the watch and show the current date and time in a lcd. Soo if i need use bcd code, how can I convert the user configuration in bcd code, and after show in a lcd screen converted on decimal.
Armando,
It's certainly possible to set up an RTC wakeup from a low-power mode to update an output like an LCD. TI Resource Explorer provides links to the SimpleLink MSP432 SDK that has example code for running a clock/calendar using the RTC for just that purpose. This example can be found here: rtc_c_calendar_alarm_interrupt.. This example also shows how the clock/calendar information is stored. From there it would be straightforward to convert whatever user configuration information you have to/from this format.
The data structure used by the driverlib APIs for the RTC are shown in the example as:
//![Simple RTC Config]
/* Time is Saturday, November 12th 1955 10:03:00 PM */
const RTC_C_Calendar currentTime =
{
0x00,
0x03,
0x22,
0x06,
0x12,
0x11,
0x1955
};
//![Simple RTC Config]
The APIs for accessing the RTCs are listed below:
newTime = MAP_RTC_C_getCalendarTime();
/* Initializing RTC with current time as described in time in
* definitions section */
MAP_RTC_C_initCalendar(¤tTime, RTC_C_FORMAT_BCD);
/* Setup Calendar Alarm for 10:04pm (for the flux capacitor) */
MAP_RTC_C_setCalendarAlarm(0x04, 0x22, RTC_C_ALARMCONDITION_OFF,
RTC_C_ALARMCONDITION_OFF);
Hope that helps.
Regards,
Bob L
Hello,
I leave my code with hope someone help me. tanks in advance.
#include "msp.h" #include "osc.h" #include "adc.h" #include "osc.h" #include "buttons.h" #include "lcd.h" #include "lcd_symbols.h" #include "clock.h" #include "timer.h" #include "tasks.h" #include <stdbool.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #ifndef _CLOCK_C #define _CLOCK_C volatile uint16_t option; volatile uint16_t botao; unsigned int tempo = 0; char dayConf[2]; char monthConf[2]; char yearConf[2]; char hourConf[2]; char minuteConf[2]; char secondConf[2]; /*HH:MM:SS*/ VAL_LCD LCDHOURS = {0,1,1}; VAL_LCD LCDMINUTS = {0,0,0}; VAL_LCD LCDSECONDS = {0,0,0}; /*yy-mm-dd*/ VAL_LCD LCDYEARS = {1,4,14}; VAL_LCD LCDMONTH = {1,1,1}; VAL_LCD LCDDAYS = {1,1,1}; int Blink_pos[5]={1,4,7,10,13}; /*STATE VARIABLES*/ typedef enum { RTC_ADJ_DAY= 0, RTC_ADJ_MONTH, RTC_ADJ_YEAR, RTC_ADJ_HOURS, RTC_ADJ_MINUTES, RTC_ADJ_SECONDS, RTC_SAVE, RTC_CONVERTION } RTC_ADJSTATES; /*RTC STATE ADJUST*/ typedef struct { RTC_ADJSTATES state; int day; int month; int year; int hour; int minutes; int seconds; int save; int cancel; } RTC_CTRL; /*RTC CONTROL STATE*/ /*VARIABLES*/ volatile RTC_CTRL rtc; /*GLOBAL RTC VARIABLE*/ /*CLOCK CONFIGURATION TO 12 MHz*/ void clockConf(void){ P2->OUT &= ~( BIT1 ); P2->DIR |= BIT1 ; CS->KEY = 0x695A; /*UNLOCK CS MODULE DOR ACESS*/ CS->CTL0 = 0; /*RESET TUNING PARAMETERS*/ CS->CTL0 |= CS_CTL0_DCORSEL_2; /*SET DCO TO 6 MHz (NOMINAL FREQUENCY BETWEEN 4 AND 8 MHz)*/ CS->CTL1 |= CS_CTL1_SELA_3 | CS_CTL1_SELS_3 | CS_CTL1_SELM_3; /*SELECT ACLK = REFO + SMCKL*/ /*RTC CONFIGURATION*/ RTC_C->CTL0 = RTC_C_KEY; /*UNLOCK RTC KEY PROTECTED REGISTERS*/ RTC_C->PS1CTL = RTC_C_PS1CTL_RT1IP__64 | /*SET DIVIDER T0 64*/ RTC_C_PS1CTL_RT1PSIE; RTC_C->CTL13 = RTC_C_CTL13_HOLD | /*HOLD THE RTC*/ RTC_C_CTL13_MODE | /*SER RTC TO CALENDAR MODE*/ RTC_C_CTL13_BCD; RTC_C->CTL13 = RTC_C->CTL13 & ~(RTC_C_CTL13_HOLD); RTC_C->CTL0 = RTC_C->CTL0 & ~(RTC_C_CTL0_KEY_MASK); /*LOCK RTC KEY PROTECT REGISTERS*/ __enable_irq(); NVIC->ISER[0] = 1 << ((RTC_C_IRQn) & 31); SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; userDefineTime(); } /*RTC STATE MACHINE CONTROL*/ bool RTC_Task(void){ if (ADC_GetButton() == _BTN_SETUP) { if (++rtc.state > RTC_SAVE) { } } if(rtc.state != RTC_SAVE){ rtc_ShowClock(); } switch(rtc.state){ /*DATE*/ case RTC_ADJ_DAY: rtc_setDays(); character_Blink(RTC_ADJ_DAY); updateLcdTimeValues(); break; case RTC_ADJ_MONTH: rtc_setMonths(); character_Blink(RTC_ADJ_MONTH); updateLcdTimeValues(); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number day_result; day_result = dec2bcd(rtc.day); sprintf(dayConf, "0x%x\n",*((int *)day_result.value)); LCD_SetText(dayConf, 0, 0); break; case RTC_ADJ_YEAR: rtc_setYears(); character_Blink(RTC_ADJ_YEAR); updateLcdTimeValues(); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number month_result; month_result = dec2bcd(rtc.month); sprintf(monthConf, "0x%x\n",*((int *)month_result.value)); LCD_SetText(monthConf, 0, 0); break; /*TIME*/ case RTC_ADJ_HOURS: rtc_setHours(); character_Blink(RTC_ADJ_HOURS); updateLcdTimeValues(); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number year_result; year_result = dec2bcd(rtc.year); sprintf(yearConf, "0x%x\n",*((int *)year_result.value)); LCD_SetText(yearConf, 0, 0); break; case RTC_ADJ_MINUTES: rtc_setMinutes(); character_Blink(RTC_ADJ_MINUTES); updateLcdTimeValues(); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number hour_result; hour_result = dec2bcd(rtc.hour); sprintf(hourConf, "0x%x\n",*((int *)hour_result.value)); LCD_SetText(hourConf, 0, 0); break; case RTC_ADJ_SECONDS: /*PASS VARIABLE TO */ rtc.state = RTC_SAVE; /*CLEAR LCD*/ LCD_Clear(); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number minute_result; minute_result = dec2bcd(rtc.minutes); sprintf(minuteConf, "0x%x\n",*((int *)minute_result.value)); LCD_SetText(minuteConf, 0, 0); /*PASS LAST PARAMETER CONFIGURATION*/ BCD_Number second_result; second_result = dec2bcd(0); sprintf(secondConf, "0x%x0\n",*((int *)second_result.value)); LCD_SetText(secondConf, 6, 0); break; case RTC_SAVE: /*SAVE DEFINITIONS?*/ if(RTC_AskToSave() == true & option == 2){ /*CLEAR LCD CHARACTERS*/ LCD_Clear(); /*VERIFY IF DATA IS STORED IN SDCARD OR BLUETOOTH*/ if(DEV_AquisitionStore() == true & option == 2){ /*DATA AQUISITION TO SDCARD*/ rtc.state = RTC_CONVERTION; }else if(DEV_AquisitionStore() == true & option == 3){ /*DATA AQUISITION TO BLUETOOTH*/ rtc.state = RTC_CONVERTION; } }else if(RTC_AskToSave()==true & option == 3){ rtc.state = RTC_ADJ_DAY; LCD_Clear(); } break; case RTC_CONVERTION: /*CLOCK CONVERTION*/ /*TMP006 AQUISITION*/ /*ADS1292R AQUISITION*/ /*BATTERY READER*/ break; } return false; } /*RTC SAVE USER CONFIGURATION*/ bool RTC_AskToSave(void){ option = ADC_GetButton(); // 1234567890123456 LCD_SetText(" SAVE CONFIG? ", 0, 0); LCD_SetText(" YES NO ", 0, 1); switch(option){ case _BTN_UP: /*ASK FOR WITCH DEVICE SAVING*/ if(option == 2){ return true; } LCD_Clear(); break; case _BTN_DWN: /*START CONFIGURATION*/ if(option == 3){ return true; } LCD_Clear(); break; } return false; } bool DEV_AquisitionStore(void){ option = ADC_GetButton(); // 01234567890123456 LCD_SetText(" DEVICE TO STORE ", 0, 0); LCD_SetText(" SDC BLE ", 0, 1); switch(option){ case _BTN_UP: /*ASK FOR WITCH DEVICE SAVING*/ if(option == 2){ return true; } break; case _BTN_DWN: /*START CONFIGURATION*/ if(option == 3){ return true; } break; } return false; } void rtc_ShowClock(void){ static bool blink = false; static uint16_t counter = 0; updateLcdTimeValues(); // 01234567890123456 //LCD_SetText("dd-mm-yy HH:MM", 1, 0); LCD_SetIntWithZero(LCDDAYS.valor, 1, 1); LCD_SetText("-", 3, 1); LCD_SetIntWithZero(LCDMONTH.valor, 4, 1); LCD_SetText("-", 6, 1); LCD_SetIntWithZero(LCDYEARS.valor,7, 1); // 01234567890123456 LCD_SetIntWithZero(LCDHOURS.valor, 10, 1); LCD_SetIntWithZero(LCDMINUTS.valor, 13, 1); if(++counter > 5){ if (blink == true) { LCD_SetText(":", 12, 1); } else { LCD_SetText(" ", 12, 1); } blink ^= true; counter = 0; } } void character_Blink(int state){ static bool set = false; static uint16_t count = 0; /*LCD_SetInt(Blink_pos[state], 0, 0);*/ if(++count > 2){ if(set == true){ }else{ LCD_SetText(" ", Blink_pos[state],1); } set ^= true; count = 0; } } void CLK_GetTempo(int comando){ tempo^=1; } /*RTC USER SET MINUTES*/ void rtc_setMinutes(void){ /* INCREMENTO */ if(ADC_GetButton() == _BTN_UP){ if(rtc.minutes < MAX_MM){ rtc.minutes++; }else{ rtc.minutes = MIN_MM; } } /* DECREMENTO */ if(ADC_GetButton()== _BTN_DWN){ if(rtc.minutes > MAX_MM){ rtc.minutes--; }else{ rtc.minutes = MAX_MM; } } } /*RTC USER SET HOURS*/ void rtc_setHours(void){ /* INCREMENTO */ if(ADC_GetButton() == _BTN_UP){ if(rtc.hour < MAX_HH){ rtc.hour++; }else{ rtc.hour = MIN_HH; } } /* DECREMENTO */ if(ADC_GetButton()== _BTN_DWN){ if(rtc.hour > MIN_HH){ rtc.hour--; }else{ rtc.hour = MAX_HH; } } } /*RTC USER SET YEARS*/ void rtc_setYears(void){ /* INCREMENTO */ if(ADC_GetButton() == _BTN_UP){ if(rtc.year < MAX_YY){ rtc.year++; }else{ rtc.year = MIN_YY; } } /* DECREMENTO */ if(ADC_GetButton() == _BTN_DWN){ if(rtc.year > MIN_YY){ rtc.year--; }else{ rtc.year = MAX_YY; } } } /*RTC USER SET MONTHS*/ void rtc_setMonths(void){ /* INCREMENTO */ if(ADC_GetButton() == _BTN_UP){ if(rtc.month < MAX_MN){ rtc.month++; }else{ rtc.month = MIN_MN; } } /* DECREMENTO */ if(ADC_GetButton() == _BTN_DWN){ if(rtc.month > MIN_MN){ rtc.month--; }else{ rtc.month = MAX_MN; } } } /*RTC USER SET DAYS*/ void rtc_setDays(void){ /* INCREMENTO */ if(ADC_GetButton() == _BTN_UP){ if(rtc.day < MAX_DA){ rtc.day++; }else{ rtc.day = MIN_DA; } } /* DECREMENTO */ if(ADC_GetButton() == _BTN_DWN){ if(rtc.day > MIN_DA){ rtc.day--; }else{ rtc.day = MAX_DA; } } } /*PICK USER KEY BUTTON DATA/TIME DEFENITION*/ void userDefineTime(void){ RTCYEAR = yearConf; RTCMON = monthConf; RTCDAY = dayConf; RTCHOUR = hourConf; RTCMIN = minuteConf; RTCSEC = secondConf; } /**/ void updateLcdTimeValues(void){ LCDYEARS.valor = rtc.year; /*YEAR = 0xYYYY*/ LCDMONTH.valor = rtc.month; /*MOUNTH = 0xMM*/ LCDDAYS.valor = rtc.day; /*DAY = 0xDD*/ LCDHOURS.valor = rtc.hour; /*HOUR = 0xhh*/ LCDMINUTS.valor = rtc.minutes; /*MIN = 0xmm*/ LCDSECONDS.valor = rtc.seconds; /*SEC = 0xss*/ } BCD_Number dec2bcd(int bin_number){ BCD_Number bcd_number; unsigned int i; for(i = 0;i<sizeof(bcd_number.value);i++){ bcd_number.value[i] = bin_number %10; bin_number = bin_number/10; bcd_number.value[i] |=bin_number%10 <<4; bin_number= bin_number/10; } return bcd_number; } // RTC interrupt service routine void RTC_C_IRQHandler(void){ if (RTC_C->PS1CTL & RTC_C_PS1CTL_RT1PSIFG){ P2OUT ^= BIT1; // // Clear the pre-scalar timer interrupt flag RTC_C->PS1CTL &= ~(RTC_C_PS1CTL_RT1PSIFG); } } #endif // _CLOCK_C
Armando,
If you are asking how to pull the calendar data from the RTC, this is handled by the RTC_C_getCalendarTime() API. This API returns a RTC_C_Calendar object, which has the definition shown below:
typedef struct _RTC_C_Calendar
{
uint_fast8_t seconds;
uint_fast8_t minutes;
uint_fast8_t hours;
uint_fast8_t dayOfWeek;
uint_fast8_t dayOfmonth;
uint_fast8_t month;
uint_fast16_t year;
} RTC_C_Calendar;
RTC_C_Calendar currTime;
currTime = RTC_C_getCalendarTime();
Each Parameter is then accessed as:
currTime->seconds
currTime->minutes
currTime->hours
and so on.
Regards,
Bob L
Bob L thanks for your help, I solve my problem, if you want i share my solution, I have to convert decimal to BCD, to use the MSP432 RTC, and to get the real time in the LCD, I have to convert BCD to decimal, through rtc registers .
Armando,
Thanks for responding, and good to hear that you found a solution. I didn't understand that it was the BCD-to-Decimal conversion that was the issue. You can skip the conversion by using the RTCBCD bit in the RTCCTL1 register to have the RTC always use decimal. You would then not need to do a conversion when reading the values and sending them to the LCD. The BCD / Decimal modes can be selected using the RTC_C_initCalendar() function. The rtc_c_calendar_alarm_interrupt.c example code shows how this can be done:
/* Initializing RTC with current time as described in time in definitions section */
MAP_RTC_C_initCalendar(¤tTime, RTC_C_FORMAT_BCD); // or Use RTC_C_FORMAT_BINARY for decimal represenation
Just as reference for others reading this post, the RTC registers which convert BCD-to-Decimal and Decimal-to-BCD are: RTCBCD2BIN and RTCBIN2BCD. Writing to these registers and then reading back from that same register will automatically perform the stated conversion. There are equivalent driverlib calls that perform the same function:
uint16_t RTC_C_convertBCDToBinary(uint16_t valueToConvert); and
uint16_t RTC_C_convertBinaryToBCD(uint16_t valueToConvert);
Further details on the RTC registers are available in the RTC section of the MSP432 Technical Reference manual. and the Driverlib User's Guide.
Regards,
Bob L.
**Attention** This is a public forum