You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:40:28