stm32oled实时显示时间
时间: 2023-10-12 13:06:02 浏览: 481
要实时显示时间,你需要使用一个时钟源来计时,并使用 OLED 屏幕来显示当前时间。以下是一个简单的示例代码,可以帮助你实现这个功能。
首先,你需要在 STM32 上选择一个时钟源。例如,你可以使用内置的 RTC(实时时钟)模块,该模块可以提供秒级别的时间精度。要启用 RTC,你需要在 STM32 上使能 LSE(低速外部晶振)或 LSI(低速内部时钟)。如果你使用的是 LSE,你需要将晶振连接到 RTC 外部引脚上。
接下来,你需要使用一个定时器来定期更新 OLED 屏幕上的时间。例如,你可以使用 TIM2 定时器,将其配置为每秒产生一个中断。在中断处理函数中,你可以读取 RTC 的当前时间,并将其显示在 OLED 屏幕上。
以下是一个示例代码,可以帮助你实现这个功能。请注意,该代码假定你已经正确配置了 RTC 和 OLED 屏幕,并正确连接了它们到 STM32 上。
```c
#include "stm32f1xx_hal.h"
#include "ssd1306.h"
#include <stdio.h>
RTC_HandleTypeDef hrtc;
TIM_HandleTypeDef htim2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
static void MX_TIM2_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim2) {
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
char buf[20];
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
sprintf(buf, "%02d:%02d:%02d", sTime.Hours, sTime.Minutes, sTime.Seconds);
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_WriteString(buf, Font_11x18, White);
ssd1306_UpdateScreen();
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_RTC_Init();
MX_TIM2_Init();
ssd1306_Init();
HAL_TIM_Base_Start_IT(&htim2);
while (1) {}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
static void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
RTC_HandleTypeDef hrtc = {0};
__HAL_RCC_RTC_ENABLE();
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
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;
if (HAL_RTC_Init(&hrtc) != HAL_OK) {
Error_Handler();
}
if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2) {
sTime.Hours = 0x12;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) {
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) {
Error_Handler();
}
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, 0x32F2);
}
}
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7999;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
Error_Handler();
}
}
void Error_Handler(void)
{
while (1) {}
}
```
这个示例代码使用 RTC 来计时,并使用 TIM2 定时器来定期更新 OLED 屏幕上的时间。在 `HAL_TIM_PeriodElapsedCallback()` 中,我们首先调用 `HAL_RTC_GetTime()` 和 `HAL_RTC_GetDate()` 来获取当前时间和日期。然后,我们使用 `sprintf()` 函数将时间格式化为字符串,并在 OLED 屏幕上显示出来。最后,我们调用 `ssd1306_UpdateScreen()` 函数来更新屏幕上的内容。
请注意,该代码假定你已经正确配置了 RTC 和 OLED 屏幕,并正确连接了它们到 STM32 上。如果你遇到任何问题,可以参考相应的文档或示例代码来帮助你解决问题。
阅读全文