开发板模拟二维码识别显示实验
前言
本篇记录鸿蒙班物联网课程的二维码模拟识别实验,基于NBV2.1开发板 + STM32主控 + LiteOS‑A轻量级实时操作系统。 实验没有接入摄像头硬件,调用封装好的显示API,模拟二维码解码完成之后,把解析出的文本输出到TFT‑LCD屏幕,同时练习LiteOS多任务开发、LCD液晶屏GUI绘制、按键周期扫描、串口调试等嵌入式核心技能,适合鸿蒙物联网入门同学参考学习。
一、实验硬件环境
- 开发主板:NBV2.1(STM32L431VC)
- 外设:240×320 TFT彩色LCD屏幕、4路物理按键
- 调试:Type‑C数据线、串口调试助手
- OS:华为鸿蒙LiteOS‑A内核
硬件拓扑简述 主控芯片驱动LCD屏幕外设与按键GPIO;LiteOS操作系统创建独立显示任务,任务循环内完成屏幕刷新、按键扫描,调用QR_CODE_Display()接口输出解析后的二维码文本。
二、基础原理
2.1 LiteOS多任务原理
LiteOS属于抢占式实时操作系统,不同业务拆分为独立任务,每个任务拥有独立栈空间、任务优先级。
- 任务中调用
LOS_TaskDelay()进行延时,主动让出CPU,实现多任务并发调度。 - 程序执行顺序:硬件外设初始化 →
LOS_KernelInit()内核初始化 → 创建用户任务 →LOS_Start()启动操作系统;系统启动后,main函数while(1)不再运行,CPU交由操作系统调度。⚠️踩坑提醒:任务栈空间配置过小,会发生栈溢出,直接导致系统死机崩溃。
2.2 LCD屏幕显示原理
TFT屏幕X坐标范围0~240,Y坐标范围0~320。 程序完成屏幕初始化、清屏,通过GUI接口设置字体、前景色、背景色,指定XY坐标完成标题、文本绘制。本实验绘制上下蓝色标题栏,中间区域用来展示二维码解析文本。
2.3 按键扫描原理
在任务循环中周期性读取4个按键GPIO电平,做按键扫描检测。本实验将按键处理函数keytask()放在显示任务循环内周期性调用,完成按键状态采集。
2.4 二维码模拟显示原理
真实完整二维码流程:摄像头图像采集 → 二维码标记定位 → 图像二值化校正 → RS纠错解码,输出字符串。 本实验为课程模拟实验,跳过图像采集和解码硬件部分;直接向字符缓冲区填入测试字符串,调用QR_CODE_Display()接口,将字符串输出到LCD屏幕,模拟“二维码解码完成展示识别结果”。
三、软件代码逻辑解析
3.1 main函数整体流程
main函数只负责硬件、模块、操作系统初始化,业务全部交给创建出来的view_task显示任务执行。
int main(void)
{
UINT32 uwRet = LOS_OK;
/*初始化*/
HAL_Init(); //硬件HAL库初始化
sysclkinit(); //系统时钟初始化
task_view_init(); //显示任务模块初始化
task_control_init(); //控制任务模块初始化
printf("\r\n 二维码识别实验 \r\n");
printf("----------------------------------\r\n");
printf("开始本实验:\r\n\r\n");
uwRet = LOS_KernelInit(); //LiteOS操作系统内核初始化
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
uwRet = creat_view_task(); //创建显示任务
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
LOS_Start(); //启动操作系统调度
while (1)
{
}
}
执行顺序: HAL硬件初始化 → 系统时钟 → LCD、按键模块初始化 → 串口打印实验提示 → LOS_KernelInit()内核初始化 → creat_view_task()创建显示任务 → LOS_Start()启动OS。
LOS_Start()执行之后main函数死循环永远不会执行,任务由操作系统调度。
3.2 view_task 显示任务核心代码
VOID view_task(VOID)
{
UINT32 uwRet = LOS_OK;
char strbuffer[sizeof(QR_STR_HEAD) + 20] = {"盛东亮"};
while(1)
{
QR_CODE_Display((uint8_t *)strbuffer); //模拟输出二维码解析内容
keytask(); //按键扫描处理
uwRet = LOS_TaskDelay(10); //延时10个tick,让出CPU
if(uwRet != LOS_OK)
{
return;
}
}
}
任务逻辑拆解:
- 定义字符缓冲区,存放模拟二维码解码得到的字符串;
while(1)构成任务循环;- 调用
QR_CODE_Display(),把缓冲区字符串输出到LCD屏幕; keytask()扫描4路物理按键IO电平;LOS_TaskDelay(10)延时,主动释放CPU,降低CPU占用率。
3.3 配套初始化与任务创建
task_view_init():执行Screen_Init_Display()屏幕初始化,全屏清屏,绘制标题栏,打印实验标题,同时初始化按键硬件。creat_view_task():填充任务初始化结构体,配置任务名、入口函数、任务优先级、栈大小,调用LOS_TaskCreate()完成任务创建。
关键参数说明
PRINTF_X、PRINTF_Y:控制屏幕文字输出坐标;ColorTab[]:颜色数组,保存红绿蓝黄等显示色彩;g_ViewTskHandle:任务句柄,供操作系统管理该显示任务。
整体软件流程图
main硬件&外设初始化 → LiteOS内核初始化 → 创建view_task任务 → LOS_Start启动操作系统 ↓ view_task循环:二维码内容显示 → 按键扫描 → 任务延时
四、实验现象
程序编译下载烧录至NBV2.1主板,上电运行:
- 串口调试助手输出
二维码识别实验
----------------------------------
开始本实验:
创建二维码显示任务
盛东亮
串口打印说明main执行正常,显示任务创建成功。
- LCD液晶屏现象 屏幕底色白色,上下绘制蓝色标题栏,屏幕居中打印标题
二维码识别实验; 调用QR_CODE_Display,缓冲区字符串输出到屏幕,模拟展示二维码识别解析后的文本。 - 按键与系统状态 4个物理按键可以被周期扫描检测;任务每10Tick刷新一次界面,系统运行稳定,不会死机。
调试遇到的异常现象
- 任务栈空间设置过小 → 栈溢出,系统直接死机;
- 任务创建失败 → 串口不会打印任务创建提示;
- LCD驱动配置错误 → 屏幕花屏、完全无显示。
五、实验总结与踩坑记录
- 初始化顺序不能颠倒:硬件外设、模块初始化必须放在操作系统内核初始化之前,外设准备完成之后,再启动LiteOS内核调度。
- LiteOS任务两个重点:任务栈空间要给足,栈太小直接系统崩溃;任务循环内必须使用延时/阻塞函数让出CPU,否则任务独占CPU,整个系统卡死。
- LCD屏幕绘制,XY坐标、字体颜色、前景背景色参数要正确,参数错误会出现文字乱码、看不到输出。
- 简单按键检测,可以直接放在显示任务循环周期扫描;复杂业务建议拆分为独立按键任务。
- 本实验属于模拟演示,只做识别结果展示;真正产品还需要摄像头采集、图像预处理、二维码解码算法。
- 串口printf是嵌入式调试利器:打印关键节点信息,快速判断任务是否创建、函数是否正常执行。
六、拓展优化思路
- 真实扫码硬件升级:外接摄像头模块,采集真实二维码图像,调用解码库,将真实解析字符串替换固定缓冲区,实现真正硬件扫码识别。
- 按键交互升级:4个按键分配功能,按键1切换显示页面;按键2清空屏幕;按键3刷新识别;按键4切换字体颜色。
- 物联网上云:二维码解析得到字符串后,通过NB‑IoT模组BC35G,将识别内容上报云平台,实现端云数据传输。
- 增加状态提示:增加识别失败逻辑,未识别二维码屏幕提示“未检测到二维码”;识别成功展示解析文本。
- 多任务解耦重构:把按键、二维码解码、显示拆分为独立任务;解码任务完成解析后通过消息队列把识别结果发送给显示任务,模块解耦,程序架构更规范。
写在最后
这个实验覆盖LiteOS多任务开发、LCD GUI、按键扫描、嵌入式调试几个非常高频的知识点。很多新手遇到系统死机,大多来自任务栈配置不足,或者任务循环没有做延时。如果正在做鸿蒙物联网课程实验,希望本篇博客对你有所帮助。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)