【NUCLEO-C562RE】MNIST 数字识别
本文介绍了 NUCLEO-C562RE 开发板结合 TinyMatrix 机器学习库、MNIST 数据集以及 Arduino IDE 实现数字识别的板端部署,包括流程图、关键代码、网页面板设计、效果演示等。
项目介绍
开发板结合 TinyMatrix 库和 MNIST 数据集,实现手写数字识别,将结果串口打印的项目设计。
- 准备工作:硬件连接、TinyMatrix 库、示例工程;
- 工程测试:流程图、工程代码、效果演示、手写面板的网页设计;

TinyMatrix
TinyMaix 是针对小算力小内存的芯片设计的轻量级推理框架。
使用 TinyMatrix 可将 MNIST 部署在 2KB 内存的单片机上运行,并对多种架构的单片机提供了支持和优化,包括 RISC-V、ARM Cortex-M 等。
关键特性
- 核心代码少;
- 低内存消耗;
- 支持 INT8/FP32/FP16 模型,支持 tflite 模型转换;
- 支持多种芯片架构的指令优化: ARM SIMD/NEON/MVEI,RV32P, RV64V;
- 友好的用户接口,只需要 load/run 模型;
- 支持全静态的内存配置 (无需malloc);
- MaixHub 在线模型训练支持;
详见:sipeed/TinyMaix .
例程获取
下载 mnist_arduino 示例工程。
详见:TinyMaix/examples/mnist_arduino .
硬件连接
使用 TypeC-USB 数据线连接 NUCLEO-C562RE 开发板和主机 USB 接口;

环境搭建


添加 URL
- 打开 Arduino IDE ,菜单栏 File - Preference 首选项,设置;

https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
- 回到 Arduino IDE 主界面,自动更新下载 STM32 板卡数据文件
package_stm_index.json;
- 等待所有工具及 SDK 下载部署完成,展开侧边工具栏 Board Manager 标签,搜索并安装
STM32 MCU based board by STMicroeletronics 最新版;

详见:STM32duino .
流程图

代码
Arduino IDE 打开 tinymatrix.ino 工程文件,代码如下
#include "stdio.h"
#include "tinymaix.h"
#include "num_test.h" // 存放目标数字图片数组
#define TM_GET_US() ((uint32_t)(micros()))
#define TM_DBGT_INIT() uint32_t _start,_finish;uint32_t _time;_start=TM_GET_US();
#define TM_DBGT_START() _start=TM_GET_US();
#define TM_DBGT(x) {_finish=TM_GET_US();\
_time = (_finish-_start);\
Serial.print("===use ");Serial.print(_time);Serial.print("us\n");\
_start=TM_GET_US();}
#include <stdint.h>
#define MDL_BUF_LEN (960)
#define LBUF_LEN (360)
const uint8_t mdl_data[920] PROGMEM={\
// ... ...
};
// 28x28 = 784 bytes, 灰度 0~255
//const uint8_t mnist_pic0[28*28] PROGMEM = {};
tm_err_t layer_cb(tm_mdl_t* mdl, tml_head_t* lh)
{ //dump middle result
return TM_OK;
int h = lh->out_dims[1];
int w = lh->out_dims[2];
int ch= lh->out_dims[3];
mtype_t* output = TML_GET_OUTPUT(mdl, lh);
Serial.print("Layer ");Serial.print(mdl->layer_i);Serial.print(" callback ========\n");
for(int y=0; y<h; y++){
Serial.print("[");
for(int x=0; x<w; x++){
Serial.print("[");
for(int c=0; c<ch; c++){
Serial.print(output[(y*w+x)*ch+c]);Serial.print(",");
}
Serial.print("],");
}
Serial.print("],\n");
}
Serial.print("\n");
return TM_OK;
}
static void parse_output(tm_mat_t* outs)
{
tm_mat_t out = outs[0];
float* data = out.dataf;
float maxp = 0;
int maxi = -1;
for(int i=0; i<10; i++){
//TM_PRINTF("%d: %.3f\n", i, data[i]);
Serial.print(i);Serial.print(": ");Serial.print(int(data[i]*100));Serial.print("\n");
if(data[i] > maxp) {
maxi = i;
maxp = data[i];
}
}
Serial.print("### Predict output is: Number ");Serial.print(maxi);Serial.print(", prob=");Serial.print(int(maxp*100));
Serial.print("\n");
return;
}
#define IMG_L (28)
#define IMG_CH (1)
#define CLASS_N (10)
static uint8_t mdl_buf[MDL_BUF_LEN];
void setup() {
Serial.begin(115200);
//printf_begin();
TM_DBGT_INIT();
Serial.print("mnist demo\n");
tm_mdl_t mdl;
const uint8_t *mnist_pic = mnist_pic5;
for(int i=0; i<28*28; i++){
Serial.print(pgm_read_byte(&mnist_pic[i])>>4, HEX);
if(i%28==27)Serial.print("\n");
}
tm_mat_t in_uint8 = {3,IMG_L,IMG_L,IMG_CH, (mtype_t*)mnist_pic};
tm_mat_t in = {3,IMG_L,IMG_L,IMG_CH, NULL};
tm_mat_t outs[1];
tm_err_t res;
//tm_stat((tm_mdlbin_t*)mdl_data);
res = tm_load(&mdl, mdl_data, mdl_buf, layer_cb, &in);
if(res != TM_OK) {
TM_PRINTF("tm model load err %d\n", res);
return ;
}
res = tm_preprocess(&mdl, TMPP_UINT2INT, &in_uint8, &in);
TM_DBGT_START();
res = tm_run(&mdl, &in, outs);
TM_DBGT("tm_run");
if(res==TM_OK) parse_output(outs);
else TM_PRINTF("tm run error: %d\n", res);
tm_unload(&mdl);
return ;
}
void loop() {
// put your main code here, to run repeatedly:
}
保存代码。
编译上传
参数配置
- 菜单栏 Tool 选择目标开发板为 Nucleo-64;
- 进一步在 Nucleo-64 开发板选择 C562RE 设备;
- 调试方式选择 SWD;

编译上传


串口输出
工具栏右上角打开 Arduino IDE 自带的串口监视器,设置波特率 115200;
短按板载 RESET 键复位运行程序,串口打印 mnist demo 输出结果;

或使用串口调试助手

包括数组转换、耗时、0-9数字置信度、预测结果等信息。
网页面板设计
为了便于生成数组,设计网页手写面板,自动生成 28x28 数组,添加至 num_test.h 即可调用;

详见:mnist_num_generate.html .
效果
在网页手写面板书写不同的数字,生成数组粘贴至 num_test.h 文件;
修改主程序中的 *mnist_pic 指针定义,编译上传,串口打印推理结果;

尝试不同数字;

识别结果准确,置信度高;

总结
本文介绍了 NUCLEO-C562RE 开发板结合 TinyMatrix 机器学习库、MNIST 数据集以及 Arduino IDE 实现数字识别的板端部署,为相关产品在边缘 AI 领域的快速开发和应用设计提供了参考。