前言

本篇记录鸿蒙班物联网课程的二维码模拟识别实验,基于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;
        }
    }
}

任务逻辑拆解:

  1. 定义字符缓冲区,存放模拟二维码解码得到的字符串;
  2. while(1)构成任务循环;
  3. 调用QR_CODE_Display(),把缓冲区字符串输出到LCD屏幕;
  4. keytask()扫描4路物理按键IO电平;
  5. LOS_TaskDelay(10)延时,主动释放CPU,降低CPU占用率。

3.3 配套初始化与任务创建

  1. task_view_init():执行Screen_Init_Display()屏幕初始化,全屏清屏,绘制标题栏,打印实验标题,同时初始化按键硬件。
  2. creat_view_task():填充任务初始化结构体,配置任务名、入口函数、任务优先级、栈大小,调用LOS_TaskCreate()完成任务创建。

关键参数说明

  • PRINTF_XPRINTF_Y:控制屏幕文字输出坐标;
  • ColorTab[]:颜色数组,保存红绿蓝黄等显示色彩;
  • g_ViewTskHandle:任务句柄,供操作系统管理该显示任务。

整体软件流程图

main硬件&外设初始化 → LiteOS内核初始化 → 创建view_task任务 → LOS_Start启动操作系统  ↓ view_task循环:二维码内容显示 → 按键扫描 → 任务延时

四、实验现象

程序编译下载烧录至NBV2.1主板,上电运行:

  1. 串口调试助手输出
     二维码识别实验     
----------------------------------
开始本实验:

创建二维码显示任务
盛东亮

串口打印说明main执行正常,显示任务创建成功。

  1. LCD液晶屏现象 屏幕底色白色,上下绘制蓝色标题栏,屏幕居中打印标题二维码识别实验; 调用QR_CODE_Display,缓冲区字符串输出到屏幕,模拟展示二维码识别解析后的文本。
  2. 按键与系统状态 4个物理按键可以被周期扫描检测;任务每10Tick刷新一次界面,系统运行稳定,不会死机。

调试遇到的异常现象

  1. 任务栈空间设置过小 → 栈溢出,系统直接死机;
  2. 任务创建失败 → 串口不会打印任务创建提示;
  3. LCD驱动配置错误 → 屏幕花屏、完全无显示。

五、实验总结与踩坑记录

  1. 初始化顺序不能颠倒:硬件外设、模块初始化必须放在操作系统内核初始化之前,外设准备完成之后,再启动LiteOS内核调度。
  2. LiteOS任务两个重点:任务栈空间要给足,栈太小直接系统崩溃;任务循环内必须使用延时/阻塞函数让出CPU,否则任务独占CPU,整个系统卡死。
  3. LCD屏幕绘制,XY坐标、字体颜色、前景背景色参数要正确,参数错误会出现文字乱码、看不到输出。
  4. 简单按键检测,可以直接放在显示任务循环周期扫描;复杂业务建议拆分为独立按键任务。
  5. 本实验属于模拟演示,只做识别结果展示;真正产品还需要摄像头采集、图像预处理、二维码解码算法。
  6. 串口printf是嵌入式调试利器:打印关键节点信息,快速判断任务是否创建、函数是否正常执行。

六、拓展优化思路

  1. 真实扫码硬件升级:外接摄像头模块,采集真实二维码图像,调用解码库,将真实解析字符串替换固定缓冲区,实现真正硬件扫码识别。
  2. 按键交互升级:4个按键分配功能,按键1切换显示页面;按键2清空屏幕;按键3刷新识别;按键4切换字体颜色。
  3. 物联网上云:二维码解析得到字符串后,通过NB‑IoT模组BC35G,将识别内容上报云平台,实现端云数据传输。
  4. 增加状态提示:增加识别失败逻辑,未识别二维码屏幕提示“未检测到二维码”;识别成功展示解析文本。
  5. 多任务解耦重构:把按键、二维码解码、显示拆分为独立任务;解码任务完成解析后通过消息队列把识别结果发送给显示任务,模块解耦,程序架构更规范。

写在最后

这个实验覆盖LiteOS多任务开发、LCD GUI、按键扫描、嵌入式调试几个非常高频的知识点。很多新手遇到系统死机,大多来自任务栈配置不足,或者任务循环没有做延时。如果正在做鸿蒙物联网课程实验,希望本篇博客对你有所帮助。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐