# OLED_shell **Repository Path**: Hans_Rudle/oled_shell ## Basic Information - **Project Name**: OLED_shell - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-15 - **Last Updated**: 2026-06-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OLED_shell 基于 STM32F103C8T6 的 OLED 终端输出项目,将 `printf` 重定向到 SSD1306 OLED 显示屏,支持 `\r\n` 换行和满屏自动滚屏。 ## 硬件 | 项目 | 详情 | |------|------| | MCU | STM32F103C8T6 (LQFP48) | | 显示屏 | 0.96" OLED SSD1306 (I2C) | | I2C | I2C1 — PB6 (SCL), PB7 (SDA) | | 时钟 | HSE 8MHz → PLL ×9 → SYSCLK 72MHz | | 调试 | SWD (PA13/PA14) | ### 接线 ``` SSD1306 STM32F103C8T6 -------- -------------- GND --> GND VCC --> 3.3V SCL --> PB6 SDA --> PB7 ``` ## 软件架构 ``` OLED_shell/ ├── Core/ │ ├── BSP/ │ │ ├── OLED.c/h # SSD1306 驱动(I2C 操作、显存管理、字符/图像显示) │ │ ├── OLED_Data.c/h # ASCII 字模数据(6×8 / 8×16) │ │ ├── OLED_printf.c/h # printf 重定向层(__io_putchar 实现) │ ├── Inc/ # HAL 外设头文件 │ ├── Src/ │ │ ├── main.c # 主程序 │ │ ├── syscalls.c # Newlib 系统调用(_write → __io_putchar) │ │ ├── sysmem.c # 堆内存管理 │ │ └── ... ├── Drivers/ # CMSIS + STM32F1xx HAL ├── CMakeLists.txt # CMake 构建配置 ├── OLED_shell.ioc # STM32CubeMX 工程文件 └── startup_stm32f103xb.s # 启动文件 ``` ### printf 重定向原理 ``` printf("hello\r\n") │ ▼ Newlib _write() ← syscalls.c(ST 自动生成) │ ▼ __io_putchar(int ch) ← OLED_printf.c(自定义实现) │ ├── '\r' → 光标回行首 ├── '\n' → 换行 + 满屏滚屏 ├── 控制字符 → 忽略 └── 可打印字符 → OLED_ShowChar() → SSD1306 ``` 光标状态 `(cursor_x, cursor_y)` 在模块内维护: - 6×8 字体:每行 21 字符,共 8 行 - 行末自动换行,底部满屏自动上滚(`memcpy` 搬移 Page1~7 → Page0~6) ## 在 CLion 中构建(当前平台) ### 前提 - [STM32CubeCLT](https://www.st.com/en/development-tools/stm32cubeclt.html) 已安装(提供 arm-none-eabi-gcc 工具链) - CLion 已安装(项目使用 CMake + GCC 编译) ### 构建步骤 1. 用 CLion 打开本工程根目录(包含 `CMakeLists.txt`) 2. CLion 会自动检测 CMakePresets.json 并加载工具链 3. 点击 **Build** → **Build Project**(或 `Ctrl+F9`) 4. 产物:`build/OLED_shell.elf`、`build/OLED_shell.bin`、`build/OLED_shell.hex` ## 切换到 Keil (MDK-ARM) 平台 ### 方法一:CubeMX 一键转换(推荐) 1. 用 STM32CubeMX 打开 `OLED_shell.ioc` 2. **Project Manager** → **Toolchain / IDE**,将 `CMake` 改为 `MDK-ARM` 3. 勾选 **Keep User Code**(保留 `/* USER CODE BEGIN */` 之间的自定义代码) 4. 点击 **GENERATE CODE**,Keil 工程会生成到 `MDK-ARM/` 目录 5. ⚠️ 非 CubeMX 文件(`OLED_printf.c/h`、`OLED_Data.c/h`)不会自动加入工程,需在 Keil 中手动添加 `Core/BSP/*.c` 6. 用 Keil 打开 `MDK-ARM/OLED_shell.uvprojx` > 如果想同时保留 CLion 和 Keil 两套工程,先复制 `OLED_shell.ioc` 为 `OLED_shell_keil.ioc`,在副本上操作,原 `.ioc` 不动。 ### 方法二:手动创建 Keil 工程 适用场景:不想依赖 CubeMX,或者 CubeMX 版本差异导致生成失败。 1. 在 Keil 中新建工程,选择器件 `STM32F103C8` 2. 添加源文件:`Core/Src/*.c`、`Core/BSP/*.c`,以及用到的 HAL 驱动文件 3. 启动文件使用 ARM 版本: ``` Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s ``` 4. 添加头文件路径: ``` Core/Inc Core/BSP Drivers/STM32F1xx_HAL_Driver/Inc Drivers/CMSIS/Device/ST/STM32F1xx/Include Drivers/CMSIS/Include ``` 5. 添加宏:`USE_HAL_DRIVER,STM32F103xB` 6. 选择调试器(ST-Link / J-Link),编译下载 --- ## 使用示例 ```c #include "OLED.h" #include "OLED_printf.h" #include int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); OLED_Init(); OLED_Clear(); // 直接使用 printf,输出到 OLED printf("OLED Terminal\r\n"); printf("================\r\n"); printf("Temp: %d.%d C\r\n", 25, 6); printf("Humi: %d %%\r\n", 60); int count = 0; while (1) { printf("Tick: %d\r\n", ++count); HAL_Delay(1000); } } ``` 输出效果: - `\r` → 光标回到本行开头 - `\n` → 光标移动到下一行,满 8 行后自动上滚 ## 注意事项 - printf 的输出遵循行缓冲模式,**务必以 `\r\n` 结尾**,否则内容可能停留在缓冲区不显示 - OLED I2C 地址为 `0x78`(SA0 接地),如果模块 SA0 接高电平需改为 `0x7A` - 切换 CubeMX 工具链时,`syscalls.c` 和 `sysmem.c` 由 CubeMX 自动生成,不同平台可能有细微差异