南北阁Nanbeige 4.1-3B硬件入门基于STM32F103C8T6最小系统板的交互演示你是不是也想过让手边那块小小的、看起来平平无奇的STM32开发板能听懂人话甚至能跟你简单聊上几句过去这听起来像是科幻情节但今天借助像南北阁Nanbeige 4.1-3B这样的大语言模型我们完全可以在资源极其有限的微控制器上实现一个智能交互的雏形。这篇文章我就带你一起动手用一块最常见的STM32F103C8T6最小系统板搭建一个能理解你指令并做出回应的“智能硬件”。我们不会去深究复杂的模型训练而是聚焦于一个更实际的工程问题如何把云端大模型的“大脑”与本地硬件的“手脚”巧妙地连接起来。整个过程就像教一个反应很快但知识有限的小朋友如何根据“总部”云端模型的指示去完成具体的动作。1. 项目思路让大模型为小硬件“翻译”在开始接线和写代码之前我们先得把整个项目的逻辑想明白。核心矛盾在于强大的云端模型输出的是丰富的自然语言而资源拮据的STM32只能处理简单的预定义指令。1.1 核心挑战与解决思路想象一下你问模型“打开客厅的灯再把温度调到25度。” 模型可能会回复一段很完整的文字“好的已为您打开客厅的灯光并将空调温度设置为25摄氏度祝您生活愉快。”这段回复对人类很友好但对STM32来说就是一堆无法直接理解的乱码。我们的STM32可能只认识几个简单的命令比如LED_ON、SET_TEMP_25。所以整个项目的核心思路就是“翻译”云端大脑Nanbeige模型负责理解复杂的用户意图并将其“翻译”成一套标准的、结构化的指令描述。本地协调员一个运行在树莓派、电脑或手机上的中间程序我们称之为“指令解析器”接收结构化描述并将其映射为STM32能懂的具体指令码。设备执行者STM32接收指令码执行对应的操作比如控制GPIO引脚高低电平。这样做的好处是STM32的负担极轻它只需要实现一个简单的指令集和通信协议。所有的智能理解和逻辑判断都交给了云端模型和中间的解析器。1.2 你需要准备的东西硬件部分很简单STM32F103C8T6最小系统板一块也就是常说的“蓝色药丸” Blue Pill。USB转TTL串口模块一个如CH340、CP2102等用于给STM32下载程序和通信。LED灯和电阻若干用于做执行动作的演示。杜邦线若干。一台电脑用于编写、调试代码并运行中间的指令解析器可以用Python快速实现。软件环境STM32开发环境Keil MDK、STM32CubeIDE 或 PlatformIO (VSCode插件) 任选其一。本文示例代码将基于HAL库兼容性较好。Python环境用于编写指令解析器需要安装requests、serial等库。南北阁Nanbeige API访问权限你需要一个能调用该模型API的密钥Key。通常可以从提供该模型的平台获取。2. 硬件连接与STM32基础工程我们先让STM32端准备好实现最基本的通信和指令执行框架。2.1 硬件连接示意图将USB转TTL模块与STM32最小系统板连接起来3.3V-3.3V(给模块供电注意不是5V)GND-GNDTXD-PA10(STM32的USART1_RX)RXD-PA9(STM32的USART1_TX)同时连接一个LED到PC13引脚很多最小系统板自带LED就在这里负极通过一个220Ω电阻接地。这样我们就有一个可以控制的设备了。2.2 创建STM32工程并配置串口如果你使用STM32CubeIDE新建工程选择型号STM32F103C8Tx。在图形化配置界面中启用USART1模式为Asynchronous。配置一个GPIO引脚如PC13为Output这就是我们的LED。生成代码。关键是在生成的main.c中我们需要编写串口接收和指令解析的逻辑。2.3 STM32端核心代码指令解析与执行STM32的程序非常简单就是一个死循环不断检查串口有没有收到新数据收到后解析并执行。// 定义简单的指令集 typedef enum { CMD_LED_ON 0x01, CMD_LED_OFF 0x02, CMD_BEEP 0x03, // 假设连接了蜂鸣器 CMD_GET_TEMP 0x04, // 假设有温度传感器 CMD_UNKNOWN 0xFF } DeviceCommand_t; // 串口接收缓冲区 uint8_t rx_buffer[64]; uint8_t rx_index 0; // 主循环中的处理部分 while (1) { // 1. 检查并接收串口数据这里使用中断接收方式更好为简化用轮询示例 if (HAL_UART_Receive(huart1, rx_buffer[rx_index], 1, 50) HAL_OK) { // 判断是否收到一条完整指令的结束符比如换行符 \n if (rx_buffer[rx_index] \n || rx_index sizeof(rx_buffer)-1) { rx_buffer[rx_index] \0; // 字符串终结符 // 2. 解析指令 DeviceCommand_t cmd parse_command(rx_buffer); // 3. 执行指令 execute_command(cmd); // 4. 清空缓冲区 rx_index 0; memset(rx_buffer, 0, sizeof(rx_buffer)); } else { rx_index; } } HAL_Delay(10); } // 解析函数示例我们约定上位机发送的是字符串指令如 LED_ON DeviceCommand_t parse_command(uint8_t* cmd_str) { if (strcmp((char*)cmd_str, LED_ON) 0) return CMD_LED_ON; if (strcmp((char*)cmd_str, LED_OFF) 0) return CMD_LED_OFF; if (strcmp((char*)cmd_str, BEEP) 0) return CMD_BEEP; return CMD_UNKNOWN; } // 执行函数 void execute_command(DeviceCommand_t cmd) { switch(cmd) { case CMD_LED_ON: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 点亮LED send_response(LED is ON); break; case CMD_LED_OFF: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 熄灭LED send_response(LED is OFF); break; case CMD_BEEP: // 控制蜂鸣器响一声的代码 send_response(Beep done); break; case CMD_UNKNOWN: send_response(Unknown command); break; } } // 通过串口发送响应 void send_response(char* msg) { HAL_UART_Transmit(huart1, (uint8_t*)msg, strlen(msg), 1000); HAL_UART_Transmit(huart1, (uint8_t*)\n, 1, 1000); // 添加结束符 }这段代码为STM32定义了一个极其简单的“世界观”它只认识LED_ON、LED_OFF等几个字符串命令。我们的任务就是让云端模型和Python解析器用STM32能懂的“语言”跟它说话。3. 搭建“翻译官”Python指令解析器现在我们来创建连接云端模型和STM32的桥梁——一个Python脚本。这个脚本要做三件事接收用户的自然语言输入。调用南北阁Nanbeige API请求模型将其转换为结构化指令。将结构化指令翻译成STM32的指令字符串并通过串口发送。3.1 与云端模型对话设计提示词Prompt这是最关键的一步。我们需要精心设计一个提示词引导模型输出我们想要的格式。# 这是一个设计给Nanbeige模型的系统提示词System Prompt system_prompt 你是一个智能家居控制指令转换器。用户会输入自然语言描述的需求你需要将其转换为JSON格式的指令序列。 可用的设备指令有 - LED_ON: 打开LED灯 - LED_OFF: 关闭LED灯 - BEEP: 蜂鸣器响一声 - GET_TEMP: 读取温度模拟 请严格按照以下JSON格式输出且只输出JSON { commands: [ {device: led, action: on}, {device: buzzer, action: beep} ] } 如果用户指令无法映射到已知设备则返回空数组。 示例 用户“开灯然后响一下” 你{commands: [{device: led, action: on}, {device: buzzer, action: beep}]} 这个提示词明确了模型的角色、可用指令、输出格式和示例。通过这种方式我们“约束”了模型的输出使其变得规整、可预测。3.2 Python解析器完整示例import requests import json import serial import time # 配置参数 API_KEY 你的_Nanbeige_API_Key API_URL https://api.nanbeige.cn/v1/chat/completions # 示例地址请替换为真实地址 SERIAL_PORT COM3 # Windows端口Linux/Mac通常是 /dev/ttyUSB0 或 /dev/ttyACM0 BAUDRATE 115200 # 初始化串口 ser serial.Serial(SERIAL_PORT, BAUDRATE, timeout1) time.sleep(2) # 等待串口稳定 def call_nanbeige_model(user_input): 调用南北阁模型API获取结构化指令 headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } # 构建请求数据包含我们设计好的系统提示词和用户问题 data { model: nanbeige-4.1-3b, # 指定模型名称 messages: [ {role: system, content: system_prompt}, {role: user, content: user_input} ], temperature: 0.1, # 低随机性确保输出稳定 max_tokens: 150 } try: response requests.post(API_URL, headersheaders, jsondata, timeout10) response.raise_for_status() result response.json() # 提取模型返回的文本内容 model_reply result[choices][0][message][content].strip() print(f模型原始回复: {model_reply}) return model_reply except Exception as e: print(f调用API失败: {e}) return None def parse_model_output(model_output): 解析模型返回的JSON转换为STM32指令字符串 try: # 尝试从回复中提取JSON部分有时模型会附带说明文字 start model_output.find({) end model_output.rfind(}) 1 if start -1 or end 0: return [] json_str model_output[start:end] cmd_list json.loads(json_str).get(commands, []) # 映射表将JSON动作映射为STM32认识的字符串指令 action_map { (led, on): LED_ON, (led, off): LED_OFF, (buzzer, beep): BEEP, (sensor, get_temp): GET_TEMP } stm32_commands [] for cmd in cmd_list: key (cmd.get(device), cmd.get(action)) stm32_cmd action_map.get(key) if stm32_cmd: stm32_commands.append(stm32_cmd) return stm32_commands except json.JSONDecodeError as e: print(f解析JSON失败: {e}, 原始内容: {model_output}) return [] def send_to_stm32(command_list): 通过串口向STM32发送指令 for cmd in command_list: print(f发送指令: {cmd}) ser.write((cmd \n).encode()) # 发送指令并添加结束符 time.sleep(0.5) # 等待STM32执行 # 可以在这里读取STM32的回复 if ser.in_waiting: response ser.readline().decode().strip() print(fSTM32回复: {response}) def main(): print(智能硬件交互演示已启动输入quit退出。) while True: user_input input(\n请输入指令: ) if user_input.lower() quit: break # 1. 调用大模型获取结构化指令 model_output call_nanbeige_model(user_input) if not model_output: continue # 2. 解析为STM32指令 command_list parse_model_output(model_output) if not command_list: print(未识别出有效指令。) continue print(f解析出的指令序列: {command_list}) # 3. 发送给STM32执行 send_to_stm32(command_list) ser.close() print(程序退出。) if __name__ __main__: main()4. 全流程跑通与效果演示现在让我们把整个流程串起来看看效果。硬件准备按照前面的示意图连接好STM32和USB转TTL模块并连接到电脑。给STM32上电。软件准备将编译好的STM32程序下载到板子里。在电脑上运行上面的Python脚本确保安装了pyserial和requests库 (pip install pyserial requests)。将脚本中的API_KEY、API_URL和SERIAL_PORT替换成你自己的信息。交互演示运行Python脚本。在脚本提示符下输入自然语言例如“打开灯”。脚本会显示调用模型的过程并将解析后的指令LED_ON通过串口发送。你会看到STM32板载的LEDPC13被点亮同时串口终端会打印出STM32回复的LED is ON。你可以尝试更多指令“关灯”- 发送LED_OFF“先开灯再响一声”- 发送LED_ON 然后发送BEEP“读取一下温度然后关灯”- 发送GET_TEMP 然后发送LED_OFF虽然我们没接传感器但指令流程是通的5. 总结通过这个简单的项目我们完成了一次从“云端智能”到“边缘执行”的落地实验。整个过程的核心不在于让STM32去运行一个几十亿参数的大模型这不可能而在于设计了一套高效的协同机制。我们利用南北阁Nanbeige 4.1-3B这样的大模型作为“意图理解引擎”将模糊的自然语言转化为精确的结构化描述。再通过一个轻量级的本地“指令翻译器”Python脚本将结构化描述映射为硬件能执行的原子操作。STM32则专心致志、快速可靠地完成这些操作。这种架构非常灵活。如果你想增加控制风扇、舵机或者读取传感器只需要做三件事在STM32的代码中扩展你的指令集和执行函数。在给模型的提示词里更新可用的设备列表和动作。在Python的映射表中增加新的映射关系。这样一来你无需改动核心通信和解析逻辑就能让这个系统理解并执行更复杂的任务。它为你打开了一扇门让你可以用最熟悉的自然语言去指挥和编排硬件世界这本身就是一件充满乐趣和成就感的事情。不妨动手试试给你的STM32赋予一点“听懂人话”的能力吧。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。