单片机智能人脸识别实战:K210+STM32联动
想给单片机装上“眼睛”和“大脑”,实现低功耗、高响应、离线运行的人脸识别控制。本文手把手带你实战K210与STM32的联动。
·
摘要: 想给单片机装上“眼睛”和“大脑”,实现低功耗、高响应、离线运行的人脸识别控制。本文手把手带你实战K210与STM32的联动。非常荣幸本篇博客被九章云极"普惠算力"社区录用,感谢社区的支持!
一.项目架构与核心思想
1.1K210(视觉处理单元)
- 运行轻量化的人脸识别模型(如Mobilenet-SSD或自定义卷积神经网络),实时处理摄像头输入数据。
- 输出结构化识别结果:识别成功时发送人员ID及置信度,未识别时发送特定错误码。
- 通过UART串口以固定协议(如JSON或自定义二进制协议)向STM32传输数据,波特率需双方匹配(如115200bps)。
1.2STM32(控制执行单元)
- 配置UART接收中断服务程序,实时解析K210发送的指令数据包。
- 实现状态机逻辑:根据指令内容触发对应动作(如ID匹配成功点亮绿色LED,未识别触发蜂鸣器报警)。
- 直接操作GPIO驱动外设:LED采用推挽输出模式,蜂鸣器需PWM调制频率,必要时增加三极管驱动电路。
二、K210端的“灵魂”代码(MaixPy)
核心是模型转换和串口通信。这里坑最多:
2.1 模型转换:
训练完成的模型需转换为K210支持的.kmodel格式。使用官方工具nncase或在线转换平台完成转换,确保模型输入输出尺寸与硬件匹配。转换后模型需存放在SD卡指定路径。
2.2路径配置:
SD卡中模型存储路径必须与代码中load_kmodel()指定的路径完全一致。建议使用简洁路径如/sd/KPU/model_name.kmodel,避免因路径错误导致加载失败。
分享一个k210初学者的指南:k210配置与学习
2.3串口通信核心代码
import sensor, image, time, lcd
from maix import KPU
from modules import ybserial
import binascii
serial = ybserial()
def str_int(data_str):
bb = binascii.hexlify(data_str)
bb = str(bb)[2:-1]
hex_1 = int(bb[0])*16
hex_2 = int(bb[1],16)
return hex_1+hex_2
def send_data(x,y,w,h,msg):
start = 0x24
end = 0x23
data = []
# 小端模式处理坐标数据
if x!=0 or y!=0 or w!=0 or h!=0:
for val in [x, y, w, h]:
data.append(val & 0xFF)
data.append(0x2C)
data.append(val >> 8 & 0xFF)
data.append(0x2C)
# 消息处理
if msg:
for char in msg:
data.append(str_int(char))
data.append(0x2C)
crc = sum([len(data)+5, 0x06, 0xBB, len(data)] + data) % 256
send_buf = [start, len(data)+5, 0x06, 0xBB, len(data)] + data + [crc, end]
return send_buf
三、STM32端的“大脑”解析(标准库)
STM32端的关键在于稳定地接收和解析数据。我们使用的是STM32F103来进行控制,在里面我们采用了简单的帧结构 "ID:xxx\n"。
3.1硬件初始化部分
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 配置为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // 选择PB12引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB
GPIO_SetBits(GPIOB,GPIO_Pin_12); // 初始置高电平(关闭蜂鸣器)
3.2外设初始化部分
OLED_Init(); // OLED显示屏初始化
SystemInit(); // 系统时钟初始化
delay_init(); // 延时函数初始化
led_int(); // LED灯初始化
USART2_init(115200); // 串口2初始化,波特率115200
LED = 0; // 初始关闭LED
3.3主循环逻辑
while(1)
{
if (k210_msg.class_n != 0) // 检测是否收到K210发送的有效数据
{
if(k210_msg.class_n == 8) // 检查数据类别是否为8(特定指令)
{
// 格式化输出坐标信息到串口
sprintf(buff_com,"x=%d,y=%d,w=%d,h=%d\r\n",k210_msg.x,k210_msg.y,k210_msg.w,k210_msg.h);
USART2_Send_ArrayU8((uint8_t*)buff_com,strlen(buff_com));
3.4身份验证处理
if(k210_msg.id == 'Y' || k210_msg.id == 'y') // 验证成功分支
{
sprintf(buff_com,"Yes\r\n");
USART2_Send_ArrayU8(...);
LED=1; // 点亮LED
OLED_ShowString(2,1,"identity yes"); // OLED显示验证成功
}
else // 验证失败分支
{
sprintf(buff_com,"NO\r\n");
USART2_Send_ArrayU8(...);
// LED闪烁三次
for(i=0;i<3;i++) {
LED=1; delay_ms(100);
LED=0; delay_ms(100);
}
// 蜂鸣器报警(PB12控制)
GPIO_ResetBits(GPIOB, GPIO_Pin_12); // 蜂鸣器响
delay_ms(100);
GPIO_SetBits(GPIOB, GPIO_Pin_12); // 蜂鸣器停
delay_ms(100);
OLED_ShowString(2,1,"identity no "); // OLED显示验证失败
}
k210_msg.class_n = 0; // 清除接收标志位
}
}
}
四.STM32进行命令下发控制
在main函数里面,我们已经接受到了k210的数据,能够判断人脸id是不是正确的,要实现led显示人员身份正确或者错误可以直接在id判断那里修改即可,如果id正确则控制led显示"identify yes",如果错误则控制led显示"identify no",这样即可实现k210识别的数据来控制led的显示,让结果直接呈现在LED上面。
4.1定义LED显示模式
- 身份正确时:LED常亮(
LED=1),OLED显示"identity yes" - 身份错误时:LED闪烁3次(现有逻辑),OLED显示"identity no"
if(k210_msg.id == 'Y' || k210_msg.id == 'y')
{
sprintf(buff_com,"Yes\r\n");
USART2_Send_ArrayU8((uint8_t*)buff_com,strlen(buff_com));
LED=1; // 常亮模式
OLED_ShowString(2,1,"identity yes");
}
else
{
sprintf(buff_com,"NO\r\n");
USART2_Send_ArrayU8((uint8_t*)buff_com,strlen(buff_com));
// 闪烁逻辑保持不变
for(i=0;i<3;i++){
LED=1;
delay_ms(100);
LED=0;
delay_ms(100);
}
OLED_ShowString(2,1,"identity no");
}
4.2硬件连接验证
- 确保LED引脚(如
GPIO_Pin_12)已正确连接到物理LED模块 - 检查OLED的I2C/SPI接口连接是否正常
- 蜂鸣器控制引脚(PB12)应独立于LED控制
4.3调试建议
- 使用逻辑分析仪或示波器观察LED引脚的电平变化
- 在串口调试助手查看
buff_com发送的调试信息 - 若LED不亮,检查:
- GPIO初始化配置(输出模式、时钟使能)
- 硬件限流电阻是否合适
- LED正负极连接方向
4.4扩展功能(可选)
- 添加声音提示:在身份错误时触发蜂鸣器(现有代码已实现)
- 增加RGB LED支持:用不同颜色表示不同状态
- 设置延时复位:身份验证后延迟5秒清除OLED显示
至此完成了从k210端进行识别,并且和STM32通信,同时根据k210的识别数据控制指示灯的开关和LED屏的显示。
更多推荐


所有评论(0)