|
【STM32U599J-DK】智能手表之一RTC时间与STTS22H数据采集与显示
[复制链接]
【实验目的】
实时采集显示日期与时间、温度。
【实验硬件】
STM32U599J-DK开发板及板载的stts22h温度计
【开发环境】
TouchGFX4.22
Stm32CubeIDE1.14.1
【模型图】
【实现步骤】
- 温度获取,配置i2c3为stts22h的接口。
- 配置rtc实时时间:
开启rtc的时钟,与开启日历。
- 开启LSE时钟:
- 在RTC_init中添加自定义代码,主要是实现重启不再写入默认的时间。
/**
* @brief RTC Initialization Function
* @param None
* @retval None
*/
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
RTC_DateTypeDef datebuff; //日期结构体参�???
/* USER CODE END RTC_Init 0 */
RTC_PrivilegeStateTypeDef privilegeState = {0};
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
/* USER CODE BEGIN RTC_Init 1 */
__HAL_RCC_PWR_CLK_ENABLE();
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
hrtc.Init.BinMode = RTC_BINARY_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
privilegeState.rtcPrivilegeFull = RTC_PRIVILEGE_FULL_NO;
privilegeState.backupRegisterPrivZone = RTC_PRIVILEGE_BKUP_ZONE_NONE;
privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0;
privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0;
if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)
{
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x7;
sTime.Minutes = 0x15;
sTime.Seconds = 0x10;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_FRIDAY;
sDate.Month = RTC_MONTH_DECEMBER;
sDate.Date = 0x7;
sDate.Year = 0x23;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
datebuff = sDate; //把日期数据拷贝到自己定义的data�??
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x5051);//向指定的后备区域寄存器写入数�??
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (uint16_t)datebuff.Year);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (uint16_t)datebuff.Month);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, (uint16_t)datebuff.Date);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, (uint16_t)datebuff.WeekDay);
}
else
{
datebuff.Year = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
datebuff.Month = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);
datebuff.Date = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);
datebuff.WeekDay = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5);
sDate = datebuff;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE END RTC_Init 2 */
}
- 添加stts22h的驱动库stts22h_reg.c/h:
- 在stm32CubeMax中添加一个信号量,用于与model进行通信:
- 在freertos的任务中,我们添加定时获取温度时间的代码,主要是读取温度值、日期、时间,并发送信号量,使得model能接收到信号量并进行显示。
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN defaultTask */
static int16_t data_raw_temperature;
static uint8_t whoamI;
stmdev_ctx_t dev_ctx;
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &SENSOR_BUS;
/* Check device ID */
stts22h_dev_id_get(&dev_ctx, &whoamI);
if (whoamI != STTS22H_ID)
while (1)
{
osDelay(10);
}
/* Infinite loop */
stts22h_temp_data_rate_set(&dev_ctx, STTS22H_1Hz);
for(;;)
{
uint8_t flag;
stts22h_temp_flag_data_ready_get(&dev_ctx, &flag);
if (flag) {
/* Read temperature data */
memset(&data_raw_temperature, 0, sizeof(int16_t));
stts22h_temperature_raw_get(&dev_ctx, &data_raw_temperature);
temperature_degC = stts22h_from_lsb_to_celsius(
data_raw_temperature);
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
osSemaphoreRelease(myBinarySemtempHandle);
osDelay(1000);
}
}
/* USER CODE END defaultTask */
}
- 在modelListener.hpp中添加虚拟函数,在model.cpp中实现:
virtual void NotifyTempValudChanged(float value, RTC_TimeTypeDef GetTime, RTC_DateTypeDef GetData) {}
void Model::tick()
{
if(osSemaphoreGetCount(myBinarySemtempHandle)>0)
{
modelListener->NotifyTempValudChanged(temperature_degC,
GetTime, GetData);
}
}
- 在screen1Presenter.hpp构建虚拟函数NotifyTempValudChanged,u并在scree1Presenter.cpp实现:
virtual void NotifyTempValudChanged(float value, RTC_TimeTypeDef GetTime, RTC_DateTypeDef GetData);
void Screen1Presenter::NotifyTempValudChanged(float value,
RTC_TimeTypeDef GetTime, RTC_DateTypeDef GetData)
{
view.setTempValud(value, GetTime, GetData);
}
- 在screen1View.hpp中构建虚拟函数setTempValud,并在screen1View.cpp中实现:
virtual void setTempValud(float value, RTC_TimeTypeDef GetTime, RTC_DateTypeDef GetData);
void Screen1View::setTempValud(float value,
RTC_TimeTypeDef GetTime, RTC_DateTypeDef GetData)
{
Unicode::snprintfFloat(textAreaTempBuffer, TEXTAREATEMP_SIZE, "%2.2f", value);
Unicode::snprintf(textAreaDataBuffer, TEXTAREADATA_SIZE, "%04d-%02d-%02d",
2000 + GetData.Year, GetData.Month, GetData.Date);
Unicode::snprintf(textAreaTimeBuffer, TEXTAREATIME_SIZE,"%02d:%02d:%02d",
GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
textAreaData.invalidate();
textAreaTime.invalidate();
textAreaTemp.invalidate();
}
- 在touchGFX Designer中创建显示界面:
【程序效果】
【总结】
Stm32U599J-DK开发板板载了温度计,stm32u599J标配了RTC外设,可以实现日期时间的精准输出与配置。
在这次工程中,我们主要实现了MPV的设计模式,实现后台与界面的分离开发。
|
|