平台:FPB RA6E2开发板
Zephyr 版本:v4.3.99 (main 分支)
【目标】体验OLED功能
【项目结构】
~/zephyrproject/app/ra6e2/ra6e2_ssd1306_i2c/ ├── boards/ │ └── fpb_ra6e2.overlay ← 启用 SCI9 I²C + SSD13064 ├── src/5 │ └── main.c ← 简单显示 "Hello"6 ├── prj.conf ← 启用 I2C / Display / SSD13067 └── CMakeLists.txt ← 标准 CMake
【操作步骤】
️1、创建项目目录
lugl@lugl:~/zephyrproject/app$ mkdir -p ~/zephyrproject/app/ra6e2/ra6e2_ssd1306_i2c lugl@lugl:~/zephyrproject/app$ cd ra6e2/ra6e2_ssd1306_i2c/
2、创建 boards/fpb_ra6e2.overlay
&sci0 {
status = "okay";
uart {
status = "disabled";
};
i2c: i2c {
compatible = "renesas,ra-i2c-sci";
status = "okay";
clock-frequency = <400000>;
ssd1306: ssd1306@3c {
compatible = "solomon,ssd1306fb";
reg = <0x3c>;
width = <128>;
height = <64>;
segment-offset = <0>; // 列偏移(通常为 0)
page-offset = <0>; // ←←← 行(页)偏移(通常为 0)
display-offset = <0>;
multiplex-ratio = <63>;
prechargep = <2>;
status = "okay";
};
};
};3、创建 prj.conf
# 启用基础功能 CONFIG_GPIO=y CONFIG_I2C=y # 启用 Renesas RA 的 SCI-I2C 驱动(关键!) CONFIG_I2C_RENESAS_RA_SCI=y # 可选:启用 DTC(DMA),提升性能(默认已开) CONFIG_I2C_RENESAS_RA_SCI_DTC=y CONFIG_DISPLAY=y # 禁用串口(因为 sci0 的 UART 被禁用) CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n
4、创建 src/main.c
/* main.c */
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include "oled.h"
#include "gui.h"
#define SSD1306_NODE DT_NODELABEL(ssd1306)
void main(void)
{
// 获取 I2C 总线设备
const struct device *i2c_dev = DEVICE_DT_GET(DT_BUS(SSD1306_NODE));
if (!device_is_ready(i2c_dev)) {
return;
}
// 注入 I2C 设备到 OLED 驱动
oled_i2c_dev = i2c_dev;
// 初始化 OLED
OLED_Init();
OLED_Clear(0);
// 显示字符串(假设 gui.c 中有 GUI_ShowString)
GUI_ShowString(0, 0, "Hello RA6E2", 16, 1); // x, y, str, size, mode
GUI_ShowString(0, 16, "Zephyr RTOS", 16, 1); // x, y, str, size, mode
OLED_Display();
while (1) {
k_sleep(K_SECONDS(1));
}
}5、移植ssd1306的驱动包到工程中:

配置写数据命令:
void OLED_WR_Byte(unsigned char dat, unsigned char cmd)
{
if (!oled_i2c_dev) return;
uint8_t buf[2];
buf[0] = cmd ? 0x40 : 0x00; // 0x00 = command, 0x40 = data
buf[1] = dat;
i2c_write(oled_i2c_dev, buf, 2, OLED_I2C_ADDR);
// k_msleep(5); 延时
}5、创建 CMakeLists.txt
cmake_minimum_required(VERSION 3.20.0)
# set(DTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ssd1306_i2c_demo)
target_sources(app PRIVATE src/main.c src/oled.c src/gui.c)【实验效果】
【问题探讨】
RA6E2的zephyr的SSD1306配置有问题,一直报:
device.h:96:41: error: '__device_dts_ord_DT_N_S_soc_S_sci0_40118000_S_i2c_S_ssd1306_3c_BUS_ORD' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_sci0_40118000_S_i2c_S_ssd1306_3c_ORD'? 96 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
还有就是使用示波器抓数据不对:

但是我发送的数据为:
OLED_WR_Byte(0xAE, 0); // 关闭显示 OLED_WR_Byte(0x20, 0); // 设置内存寻址模式 OLED_WR_Byte(0x00, 0); // 水平寻址模式 OLED_WR_Byte(0xB0, 0); // 设置页地址 OLED_WR_Byte(0xC8, 0); // 设置扫描方向 OLED_WR_Byte(0x00, 0); // 设置列地址低 4 位 OLED_WR_Byte(0x10, 0); // 设置列地址高 4 位 OLED_WR_Byte(0x40, 0); // 设置显示起始行 OLED_WR_Byte(0x81, 0); // 设置对比度 OLED_WR_Byte(0xFF, 0); // 最大对比度 OLED_WR_Byte(0xA1, 0); // 设置段重映射 OLED_WR_Byte(0xA6, 0); // 设置正常显示 OLED_WR_Byte(0xA8, 0); // 设置多路复用率 OLED_WR_Byte(0x3F, 0); // 1/64 多路复用 OLED_WR_Byte(0xA4, 0); // 恢复整体显示 OLED_WR_Byte(0xD3, 0); // 设置显示偏移 OLED_WR_Byte(0x00, 0); // 无偏移 OLED_WR_Byte(0xD5, 0); // 设置时钟分频比/振荡器频率 OLED_WR_Byte(0xF0, 0); // 设置分频比 OLED_WR_Byte(0xD9, 0); // 设置预充电周期 OLED_WR_Byte(0x22, 0); // 设置预充电周期 OLED_WR_Byte(0xDA, 0); // 设置 COM 引脚硬件配置 OLED_WR_Byte(0x12, 0); // 设置 COM 引脚硬件配置 OLED_WR_Byte(0xDB, 0); // 设置 VCOMH 取消选择级别 OLED_WR_Byte(0x20, 0); // 设置 VCOMH 取消选择级别 OLED_WR_Byte(0x8D, 0); // 设置电荷泵 OLED_WR_Byte(0x14, 0); // 启用电荷泵 OLED_WR_Byte(0xAF, 0); // 开启显示
抓取的只有0xAE是对的,后面的都解析不对。
【总结】
通过两天的调试,终于是把OLED点亮了。期待官方能完善zephyr驱动。
【附工程源码】
我要赚赏金
