news 2026/9/20 3:08:59

RIOT OS 中 AIP31068 I2C 字符型 LCD 驱动测试应用全解析:20 条 Shell 命令与进度条实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RIOT OS 中 AIP31068 I2C 字符型 LCD 驱动测试应用全解析:20 条 Shell 命令与进度条实现
  • 物联网
  • 嵌入式
  • 操作系统
  • 实时系统

【免费下载链接】RIOT

RIOT - The friendly OS for IoT

项目地址:https://gitcode.com/GitHub_Trending/riot/RIOT
点击查看免费下载

导读

AIP31068 是一款通过 I2C 接口控制、内部挂载 HD44780 兼容控制器的字符型 LCD 驱动芯片,常用于 16x2、20x4 等小尺寸显示屏。本文以 RIOT OS 官方测试应用 tests/drivers/aip31068/README.md 为骨架,完整讲解该测试程序提供的 20 条 Shell 命令的用法与参数,并深入 tests/drivers/aip31068/main.c 与 drivers/aip31068/aip31068.c 源码,剖析初始化序列、I2C 写协议、自定义字符与进度条(progress bar)的底层实现。读完本文,你将能够在任意支持periph_i2c的 RIOT 板卡上编译、烧录并逐条验证 AIP31068 的全部驱动能力。

测试应用概述:用 Shell 命令逐项验证 LCD 驱动接口

AIP31068 测试应用的核心目标是演示 AIP31068 驱动接口的用法,并通过 Shell 命令对一块真实的 AIP31068 LCD 设备进行逐项功能测试。其入口代码位于 tests/drivers/aip31068/main.c:

int main(void) { int rc = 0; if ((rc = aip31068_init(&aip31068_dev, &aip31068_params[0])) != 0) { printf("Initialization failed! rc = %d", rc); return 1; } aip31068_turn_on(&aip31068_dev); aip31068_set_custom_symbol(&aip31068_dev, CUSTOM_SYMBOL_1, custom_char_heart); char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); return 0; }

程序启动后先调用aip31068_init()完成初始化,随后点亮显示屏并把一颗"心形"图案写入自定义字符槽CUSTOM_SYMBOL_1,最后进入 Shell 交互循环等待用户输入命令。整个测试程序仅依赖三个模块,从 tests/drivers/aip31068/Makefile 可以看到:

include ../Makefile.drivers_common USEMODULE += aip31068 USEMODULE += xtimer USEMODULE += shell include $(RIOTBASE)/Makefile.include

而驱动本身在 drivers/aip31068/Makefile.dep 中声明了硬件依赖:

FEATURES_REQUIRED += periph_i2c USEMODULE += xtimer

即编译该测试应用需要板卡提供I2C 外设,且驱动内部使用xtimer实现初始化与命令执行的时序等待。

设备参数与默认配置

测试程序直接使用驱动提供的默认参数数组aip31068_params[]。默认配置定义在 drivers/aip31068/include/aip31068_params.h:

#ifndef AIP31068_PARAM_I2C_DEV /** I2C device is I2C_DEV(0) */ #define AIP31068_PARAM_I2C_DEV I2C_DEV(0) #endif #ifndef AIP31068_PARAM_I2C_ADDR /** I2C address of device is (0x7c >> 1) */ #define AIP31068_PARAM_I2C_ADDR (0x7c >> 1) #endif #ifndef AIP31068_PARAMS #define AIP31068_PARAMS \ { \ .i2c_dev = AIP31068_PARAM_I2C_DEV, \ .i2c_addr = AIP31068_PARAM_I2C_ADDR, \ .row_count = 2, \ .col_count = 16, \ .font_size = FONT_SIZE_5x8, \ .bit_mode = BITMODE_8_BIT, \ } #endif

关键参数说明:

参数默认值说明
i2c_devI2C_DEV(0)使用的 I2C 控制器编号
i2c_addr0x7c >> 1(即 0x3E)设备 7 位 I2C 地址,0x7C 是常见 LCD I2C 背板地址的 8 位写法
row_count2显示行数,驱动断言限制最大为 4 行
col_count16每行字符列数
font_sizeFONT_SIZE_5x8字符点阵规格,可选 5x8 或 5x10
bit_modeBITMODE_8_BIT接口位宽模式,可选 4 位或 8 位

参数结构体aip31068_params_t与枚举aip31068_font_size_taip31068_bit_mode_t的定义位于 drivers/include/aip31068.h。测试程序在 tests/drivers/aip31068/main.c 中按默认 2 行 16 列定义了常量:

#define ROW_COUNT 2 #define COL_COUNT 16 /* font is either 5x8 or 5x10, so always 5 columns per character */ #define PIXEL_COLUMNS_PER_CHAR 5

若你的 LCD 是 20x4 等规格,可通过在构建时覆盖AIP31068_PARAMS宏(或对应AIP31068_PARAM_*宏)来适配。

20 条 Shell 命令的完整用法

README 列出的全部 20 条命令都在 tests/drivers/aip31068/main.c 的命令表中注册。下面按功能分类逐一给出精确用法与对应驱动函数。

3.1 显示开关与清屏

命令用法驱动函数说明
turn_onturn_onaip31068_turn_on()打开 LCD 显示
turn_offturn_offaip31068_turn_off()关闭 LCD 显示
clearclearaip31068_clear()清空显示内容,光标回到 (0, 0)
homehomeaip31068_return_home()光标回到 (0, 0),并撤销此前所有滚动移位

这四条命令不带参数。从源码看,turn_on/turn_off通过置位/清零DISPLAY_CONTROL命令中的显示位(AIP31068_BIT_DISPLAY_CONTROL_DISPLAY)实现,而clearhome在执行后都会等待AIP31068_EXECUTION_TIME_MAX(清屏/归位是耗时最长的操作,见 drivers/aip31068/aip31068.c)。

3.2 光标与文本行为

命令用法驱动函数说明
autoscrollautoscroll <0 or 1>aip31068_set_auto_scroll_enabled()启用/禁用自动滚动
cursor_blinkingcursor_blinking <0 or 1>aip31068_set_cursor_blinking_enabled()启用/禁用光标闪烁
cursor_visiblecursor_visible <0 or 1>aip31068_set_cursor_visible()显示/隐藏光标
cursor_positioncursor_position <row> <column>aip31068_set_cursor_position()设置光标位置,row/column 均从 0 起算
text_insertiontext_insertion <mode (0-1)>aip31068_set_text_insertion_mode()设置文本插入方向:0 = LEFT_TO_RIGHT,1 = RIGHT_TO_LEFT
cursor_leftcursor_leftaip31068_move_cursor_left()光标左移一格
cursor_rightcursor_rightaip31068_move_cursor_right()光标右移一格
scroll_leftscroll_leftaip31068_scroll_display_left()显示内容整体左移一格
scroll_rightscroll_rightaip31068_scroll_display_right()显示内容整体右移一格

其中带参命令的参数校验逻辑都写在对应处理函数中,例如_cursor_position(tests/drivers/aip31068/main.c)要求恰好两个参数,否则打印用法提示;_text_insertion(tests/drivers/aip31068/main.c)会把数字参数映射为LEFT_TO_RIGHT/RIGHT_TO_LEFT枚举并拒绝 0-1 之外的值。

值得注意的实现细节:scroll_left/scroll_rightcursor_left/cursor_right共用同一条CURSOR_DISPLAY_SHIFT命令,区别仅在于控制位的组合——滚动方向由AIP31068_BIT_CURSOR_DISPLAY_SHIFT_SELECTION(选择移动光标还是滚动显示)与AIP31068_BIT_CURSOR_DISPLAY_SHIFT_DIRECTION(方向)两个位决定,见 drivers/aip31068/include/aip31068_regs.h。

3.3 字符输出与自定义符号

命令用法驱动函数说明
printprint <text>aip31068_print()在当前光标处打印字符串
create_custom_symbolcreate_custom_symbol <symbol (0-7)> <row 0 (0-31)> ... <row 7 (0-31)>aip31068_set_custom_symbol()创建自定义符号(8 行像素数据)
print_custom_symbolprint_custom_symbol <symbol (0-7)>aip31068_print_custom_symbol()打印自定义符号

自定义符号是 HD44780 系 LCD 的经典能力:控制器内置 CGRAM,可存放最多 8 个用户自定义字符。每个字符在 5x8 字体下由 8 行、每行 5 位(0-31)的位图定义。测试程序给出了心形示例(tests/drivers/aip31068/main.c):

static const uint8_t custom_char_heart[] = { 0, 0, 10, 31, 31, 14, 4, 0 };

即执行create_custom_symbol 0 0 0 10 31 31 14 4 0即可在槽位 0 写入一颗心,再用print_custom_symbol 0打印。处理函数_create_custom_symbol(tests/drivers/aip31068/main.c)会校验符号索引必须在 0-7 之间。

驱动侧aip31068_set_custom_symbol()的实现揭示了 CGRAM 的地址编码:自定义字符基地址为symbol << 3,并通过SET_CGRAM_ADDR命令定位,随后按字体逐行写入像素数据(5x8 字体写 8 行,5x10 字体写 10 行),见 drivers/aip31068/aip31068.c。aip31068_print_custom_symbol()则直接以符号索引作为数据字节输出。

3.4 进度条功能

命令用法说明
progressbarprogressbar <0 or 1>启用/禁用进度条功能
progressbar_rowprogressbar_row <row>设置进度条所在行(默认最后一行)
progressprogress <progress (0-100)>设置进度百分比并刷新显示

进度条是测试程序在驱动基础能力之上实现的"彩蛋"功能,它复用了 5 个自定义字符槽位(CUSTOM_SYMBOL_4CUSTOM_SYMBOL_8)来渲染不同填充宽度的竖条,见 tests/drivers/aip31068/main.c 的_init_progress_bar()。启用进度条时程序会自动:

  1. 关闭自动滚动并执行return_home撤销已发生的滚动(否则进度条显示会错位);
  2. 将文本插入模式设为LEFT_TO_RIGHT
  3. 向槽位 4-8 写入 5 种逐级变宽的条状图案(像素列宽分别为 1/5 至 5/5)。

绘制算法_set_progress()(tests/drivers/aip31068/main.c)把百分比换算为整行像素列数:

int bar_count = dev->params.col_count * PIXEL_COLUMNS_PER_CHAR; /* 16 列 x 5 像素 = 80 */ int progress_bar_count = bar_count * progress / 100; /* 目标像素列数 */ int full_bar_count = progress_bar_count / PIXEL_COLUMNS_PER_CHAR; /* 完整实心字符数 */ int remainder_bar_count = progress_bar_count % PIXEL_COLUMNS_PER_CHAR; /* 剩余半格 */

完整实心部分用CUSTOM_SYMBOL_8填充,余数部分按 1-4 像素分别用CUSTOM_SYMBOL_4~CUSTOM_SYMBOL_7,行尾剩余部分用空格补齐,从而在 2 行 16 列屏上呈现细腻的像素级进度条。

run_demo:一键演示全部功能

run_demo命令无需参数,会在屏幕上顺序演示 9 个场景,是验收驱动与硬件连接是否正常的最快途径(tests/drivers/aip31068/main.c):

  1. 自定义符号:打印 "Hello world! " 并输出心形符号;
  2. 滚动演示:先以LEFT_TO_RIGHT插入模式打印 "scroll right" 并右移 4 次;再以RIGHT_TO_LEFT模式、光标置于第 15 列打印反向文本并左移 5 次(演示双向插入与滚动);
  3. 开关显示:打印 "turning off..." 后turn_off1 秒,再clear+turn_on恢复;
  4. 自动滚动:第二行打印超长文本,光标移到第 16 列后启用autoscroll,逐字符打印 "This is a very long line"(每 250ms 一个字符)观察自动滚动,随后关闭;
  5. 归位return_home复位;
  6. 光标闪烁:在首行 16 个位置间移动光标,中途反复开关闪烁位;
  7. 显示与移动光标:打印 0-9,然后光标右移 50 格、左移 50 格;
  8. 50 字符长文本LEFT_TO_RIGHT交替打印 50 个 "A"/"B"(跨行环绕),再以RIGHT_TO_LEFT从第 15 列起反向交替打印 50 个 "X"/"Y";
  9. 进度条:启用进度条后,在第 10 列实时打印 "0 %" 到 "100 %",同时_set_progress逐百分比推进,最后关闭并清屏。

整个 demo 依赖xtimerxtimer_sleep/xtimer_msleep控制节奏。运行run_demo即可直观验证 LCD 的所有功能点。

底层原理:初始化序列与 I2C 写协议

5.1 初始化序列

aip31068_init()(drivers/aip31068/aip31068.c)严格按照 AIP31068 数据手册第 20 页(即其背后 HD44780 的初始化流程)执行:

  1. 根据bit_mode/row_count/font_size组装FUNCTION_SET命令的控制位;
  2. 先睡眠 50ms,连续三次发送FUNCTION_SET(间隔分别为 5ms 与 500us),保证兼容各种实现;
  3. 依次发送turn_offclearset_text_insertion_mode(LEFT_TO_RIGHT)完成收尾。

同时初始化断言params->row_count <= 4,因为aip31068_set_cursor_position()内部使用硬编码的行偏移表row_offsets[4] = {0x00, 0x40, 0x00+col, 0x40+col}计算 DDRAM 地址(drivers/aip31068/aip31068.c),超过 4 行无法寻址。

5.2 I2C 数据帧格式

AIP31068 通过 I2C 传输时,每个数据帧由"控制字节 + 数据字节"组成(drivers/aip31068/aip31068.c):

static inline int _write(aip31068_t *dev, uint8_t data_byte, bool is_cmd) { uint8_t control_byte = 0; if (!is_cmd) { SETBIT(control_byte, AIP31068_BIT_CONTROL_BYTE_RS); /* RS=1 表示数据 */ } uint8_t data[] = { control_byte, data_byte }; return _device_write(dev, data, sizeof(data)); }

控制字节的含义定义在 drivers/aip31068/include/aip31068_regs.h:

  • BIT7(CO):0 表示这是最后一个控制字节,1 表示其后还跟有控制字节;
  • BIT6(RS):0 表示后续数据字节被解释为命令,1 表示被解释为显示数据

最终通过i2c_acquire()/i2c_write_bytes()/i2c_release()发送到总线上(drivers/aip31068/aip31068.c)。每个命令或数据字节写入后,驱动都会xtimer_usleep(AIP31068_EXECUTION_TIME_DEFAULT)等待指令执行完成。

5.3 驱动 API 一览

驱动对外公开的全部 API 声明在 drivers/include/aip31068.h(共 421 行),包括本文涉及的核心函数:aip31068_initaip31068_turn_on/offaip31068_clearaip31068_return_homeaip31068_set_auto_scroll_enabledaip31068_set_cursor_blinking_enabledaip31068_set_cursor_visibleaip31068_set_cursor_positionaip31068_set_text_insertion_modeaip31068_move_cursor_left/rightaip31068_scroll_display_left/rightaip31068_set_custom_symbolaip31068_print_custom_symbolaip31068_printaip31068_print_char。它们与本文 Shell 命令一一对应,因此在验证完命令后,完全可以直接在业务代码中调用同样的 API 驱动 LCD。

编译、烧录与运行

在支持periph_i2c的任意板卡上(如native之外的各类开发板)按 RIOT 标准流程构建:

make BOARD=<你的板卡名> -C tests/drivers/aip31068 flash term

例如使用nucleo-f446re

make BOARD=nucleo-f446re -C tests/drivers/aip31068 flash term

连接 LCD 的 SDA/SCL 到板卡I2C_DEV(0)对应引脚(地址默认 0x3E),上电后终端即可交互。建议按以下顺序验证:

turn_on print Hello RIOT! cursor_position 1 0 print progress test progressbar 1 progress 50 run_demo

aip31068_init返回非 0(如-ENXIO),说明 I2C 总线上未发现设备,请检查接线、地址与I2C_DEV编号;若返回-EIO,通常是设备未正确应答,可优先排查供电与地址配置(详见 drivers/include/aip31068.h 中的返回值说明)。

小结

RIOT OS 的 tests/drivers/aip31068 测试应用以 20 条 Shell 命令完整覆盖了 AIP31068 驱动的显示控制、光标管理、滚动移位、自定义字符与进度条五大能力,其中run_demo一键即可完成全功能验收。配合 drivers/aip31068 驱动源码,开发者既能快速验证硬件,也能把测试程序中的用法直接迁移到自己的业务代码中,是学习 RIOT 字符型 LCD 驱动开发的最佳起点。

  • 物联网
  • 嵌入式
  • 操作系统
  • 实时系统

【免费下载链接】RIOT

RIOT - The friendly OS for IoT

项目地址:https://gitcode.com/GitHub_Trending/riot/RIOT
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 3:07:27

2026企业级AI编程助手横向评测:六款主流产品能力与选型指南

2026年这几个月&#xff0c;我带着团队里二十多个研发同学&#xff0c;把市面上主流的AI编程助手几乎都用了一个遍。确切说&#xff0c;是选了六款有代表性的产品&#xff0c;做了整整六周的企业级横向评测。这个选题不是临时起意&#xff0c;而是因为AI编程助手已经从一个”写…

作者头像 李华
网站建设 2026/9/20 3:04:02

RF-DETR:面向边缘NPU的实时Transformer目标检测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 3:03:04

Composer依赖解析全指南:从报错排查到平台兼容与Lock文件实践

如果你维护过任何一个用 PHP 写的 Web 项目&#xff0c;大概率对这段输出不陌生&#xff1a;在终端敲下composer update&#xff0c;光标停在Loading composer repositories with package information这一行久久不动&#xff0c;接着慢慢吐出Updating dependencies&#xff0c;…

作者头像 李华
网站建设 2026/9/20 3:03:01

高效利用GitHub热榜:项目筛选、拆解与落地经验

每天早上到工位&#xff0c;我先花十几分钟把 GitHub 热榜项目的日榜过一遍。2026-09-10 这期榜单&#xff0c;说实话信息量不小&#xff0c;AI 类项目开始往落地走&#xff0c;开发工具类也进入“卷细节”的阶段。这篇文章我会按自己的筛选习惯&#xff0c;把当天上榜的几个方…

作者头像 李华
网站建设 2026/9/20 3:01:16

Codex科研工作流实战:从选题到模拟审稿的保姆级教程

说实话&#xff0c;我在把 Codex 真正塞进自己的科研流程之前&#xff0c;一直觉得它就是个写代码的辅助工具&#xff0c;无非是自动补全、生成几个脚本。直到我完整跑了一遍“研究问题 → 文献综述 → 实验分析 → 论文写作 → 模拟审稿”这条链路&#xff0c;才发现 Codex 最…

作者头像 李华
网站建设 2026/9/20 3:00:54

基于Hadoop+Spark+Kafka+Hive的民宿推荐系统设计与实现

1. 毕业设计选题背后的技术选型逻辑——为什么是这套大数据组合拳每年做计算机毕业设计的学生&#xff0c;十个里面有八个会在选题阶段纠结一件事&#xff1a;既要保证工作量、让评委觉得有技术含量&#xff0c;又怕自己撑不起一个复杂度太高的系统。民宿推荐系统这个题目恰好卡…

作者头像 李华