基于STM32 BlueBill内置RTC的时钟开发:OLED显示乱码问题
问题描述
我是STM32开发新手,正在开发一款基于STM32 BlueBill内置RTC的时钟,目标是在OLED显示屏上显示时间。但运行代码后,屏幕出现随机无法识别的符号。
运行代码
while(1){ /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); uint8_t *a = sTime.Hours; char* buffer2; int i; buffer2 = malloc(9); if (!buffer2) break; buffer2[8] = 0; for (i = 0; i <= 7; i++) buffer2[7 - i] = (((*a) >> i) & (0x01)) + '0'; puts(buffer2); // sprintf(date,"Date: %02d.%02d.%02d\t",sDate.Date,sDate.Month,sDate.Year); // sprintf(time,"Time: %02d.%02d.%02d\r\n",sTime.Hours,sTime.Minutes,sTime.Seconds); SSD1306_GotoXY (0,0); SSD1306_Puts (buffer2, &Font_11x18, 1); SSD1306_GotoXY (0, 30); SSD1306_Puts ("CLOCK", &Font_11x18, 1); SSD1306_UpdateScreen(); HAL_Delay (1000); }
RTC配置

问题分析与解决
核心问题1:指针错误导致非法内存访问
代码中uint8_t *a = sTime.Hours;是错误的——sTime.Hours是uint8_t类型的数值,不是指针。直接将数值赋值给指针,相当于把小时数当作内存地址去解引用,会读取随机的非法内存数据,最终导致屏幕显示乱码。
正确写法是直接使用数值,无需指针:
uint8_t hour = sTime.Hours;
核心问题2:格式转换逻辑错误
当前循环将小时数转换为8位二进制字符串(例如10点会转为00001010),但OLED字库仅支持ASCII格式的十进制数字字符,这种二进制字符串没有对应字形,自然显示乱码。
如果要显示常规的十进制时间(如10:30:25),直接使用注释里的sprintf格式化即可,无需手动转二进制。
修正后的完整代码示例
while(1){ /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); // 栈上定义缓冲区,避免循环malloc导致内存碎片 char time_buf[20]; // 格式化时间为HH:MM:SS的十进制格式 sprintf(time_buf, "%02d:%02d:%02d", sTime.Hours, sTime.Minutes, sTime.Seconds); SSD1306_GotoXY(0, 0); SSD1306_Puts(time_buf, &Font_11x18, 1); SSD1306_GotoXY(0, 30); SSD1306_Puts("CLOCK", &Font_11x18, 1); SSD1306_UpdateScreen(); HAL_Delay(1000); }
额外注意事项
- 不要在循环内重复调用
malloc,容易产生内存碎片,栈上固定大小的缓冲区更安全高效。 - 确认RTC初始化正确:从配置截图看已开启RTC,需确保时钟源(LSE/LSI)选择合理,且初始化时已设置好初始时间。
内容的提问来源于stack exchange,提问作者moaz
相关产品推荐
相关产品推荐

