CAN:PA11,PA12
RS485:PC12,PD2
串口:PA9,PA10
W25Q64:PB14,PB4,PB3,PB5
网口:PC4,PC5,PA1,PG13,PA7,PA2,PC1,PG11,PG14
LED心跳:PF9,PF10
3个编码器接口:PB6,PB7;PB10,PB11;PC8,PC9;
步进电机接口:DIR1:PF1,EN1:PF0,PUL1:PC6;
DIR2:PF3,EN2:PF2,PUL2:PC7;
| 电机编号 | DIR 引脚 | EN 引脚 | PUL 引脚 |
|---|---|---|---|
| 电机 1 | PF1 | PF0 | PC6 |
| 电机 2 | PF3 | PF2 | PC7 |
4个光源:PD7,PE6,PF6,PF7
IO输入:PF6,PF10,PF11,PF9,PF7,PC3,PC2,PC0
IO输出:PE2,PE3,PE4,PE5,PE6,PG6,PG7,PG8
考虑到布局版本2:IO输入:PC2,PC3,PC10,PC11,PE7,PE8,PE9,PE10
IO输出:PD8,PD9,PD10,PD11,PF0,PF1,PF2,PF3
程序思路:
系统分层架构
🧩 一、启动层(Startup Layer)
📁 典型目录:Startup/
作用:
-
负责系统最底层的初始化,是程序运行的起点。
-
设置堆栈、向量表、中断入口地址。
-
跳转到
main()。
主要内容:
-
startup_stm32f407xx.s(汇编启动文件) -
_vector_table中断向量表定义
👉 一句话总结 :上电后 CPU 从这里开始跑,最终跳到 main()。
⚙️ 二、系统层(System Layer)
📁 典型目录:Drivers/SYSTEM/
作用:
-
提供系统级初始化和公共基础功能。
-
给驱动层和应用层提供通用支持。
主要内容:
-
系统时钟配置(
system_clock.c) -
中断优先级管理
-
延时函数、SysTick管理
-
printf重定向、调试输出
-
任务调度基础接口(如果FreeRTOS集成)
👉 一句话总结:负责 MCU "环境搭好",时钟、调试、中断都在这里准备好。
🔧 三、驱动层(Driver Layer)
📁 典型目录:Drivers/BSP/、Drivers/STM32F4xx_HAL_Driver/
作用:
-
封装对硬件的直接操作(即驱动层 = HAL + BSP)。
-
为上层提供统一的硬件访问接口。
划分两部分:
| 层次 | 内容 |
|---|---|
| HAL 驱动(底层) | ST 官方库,直接操作寄存器。 |
| BSP 驱动(板级) | 封装 HAL,针对你的板子功能,比如 LED、CAN、IO、步进电机、编码器、RS485、Flash。 |
例子:
-
bsp_led.c→ 控制LED -
bsp_motor.c→ 控制步进电机 -
bsp_encoder.c→ 编码器读取 -
bsp_can.c→ CAN收发封装 -
bsp_w25q64.c→ SPI Flash驱动
👉 一句话总结 :屏蔽底层差异,上层只管调用函数比如 LED_Toggle()、Motor_Run()。
🧠 四、中间层(Middleware Layer)
📁 典型目录:Middlewares/
作用:
-
提供通用的协议栈、内核、内存管理等功能。
-
它是驱动和应用之间的"协议/系统中间件"。
主要内容:
-
FreeRTOS/:实时系统内核(任务、信号量、队列) -
lwIP/:TCP/IP 协议栈 -
MALLOC/:内存管理 -
USMART/:调试命令接口 -
(你后期可以加)
ModbusTCP/:协议解析任务
👉 一句话总结:相当于操作系统和通信协议的"软件中间件"。
🚀 五、应用层(Application Layer)
📁 典型目录:User/(可以再细分出 App/)
作用:
-
实现系统的业务逻辑和控制策略。
-
创建任务、管理场景、执行功能。
建议结构:
| 子模块 | 说明 |
|---|---|
main.c |
系统入口,启动 FreeRTOS、创建任务 |
app_task.c |
各种任务函数(通信、控制、监测) |
scene_manager.c |
场景切换逻辑(对应你的场景1~11) |
modbus_parser.c |
TCP指令解析 |
io_control.c |
IO输入检测与报警输出 |
motor_ctrl.c |
步进电机控制(调用 BSP 层) |
👉 一句话总结:这是整个系统"思考和决策"的层,调用下层实现所有功能。
📘 总结一句话版
| 层级 | 职责 | 举例 |
|---|---|---|
| 启动层 | 上电启动、跳转到main | startup_stm32f407xx.s |
| 系统层 | 时钟、中断、延时、系统基础 | system_init.c |
| 驱动层 | 封装硬件接口、屏蔽底层差异 | bsp_led.c, bsp_motor.c |
| 中间层 | 操作系统与协议栈支持 | FreeRTOS, lwIP, ModbusTCP |
| 应用层 | 实现具体业务逻辑和场景控制 | main.c, app_task.c |
1,急停按钮,1个输入io(PE7使用外部中断)
2,限位接口,4个输入io,还剩余3个()
3,报警灯接口,6个输出io口,还剩余2个
DB15思路:电机口:12个;io输入口,8个,io输出口8个,编码器接口:12个
4个DB15接口
那么急停按钮怎么快速响应呢?有按钮按下立即执行电机停止,限位接收到信号,电机向反方向进行运行;
场景一:当8路io输入只要其中一路有输入信号触发,8路输出口io进行输出(报警灯),通过tcp上传报警指令;
场景二:当8路io输入只要其中一路有输入信号触发,主动发送触发信号,通过网口tcp传给上位机
场景三:上位机通过指令,通过网口tcp进行读取编码器脉冲数和速度;
场景四:上位机通过指令,通过网口tcp进行控制步进电机直线插补或圆弧插补,当触发限位信号时,停止运动;
场景五:通过上位机指令进行控制一个步进电机,向一个方向运行,当触发限位信号向反方向运行,两个限位信号,刚好在里面来回运动;
场景六:当控制4轴步进电机时,可以通过CAN进行模块连接通信,然后实现4轴的控制,可以对四轴进行电机正翻转,速度控制,配合编码器进行闭环控制;控制电机到达指定位置;可以通过急停按钮进行暂停保护;
场景七:当要实现多组io接受时,主动发送给上位机时,io口不够用,可以通过RS485进行IO扩展
,读取信号,主动发送给上位机状态
场景八:当要实现多路io输出,可以通过rs485进行扩展输出,通过上位机指令进行io输出控制;
扩展:
场景九:可以控制有刷电机闭环控制,控制速度和运行到指定位置;
场景十:可以进行无刷电机的闭环控制;
场景十一:进行FOC控制
功能设想:板子作为服务端,连上串口LED0闪烁,可以进行串口调试,板子默认远程地址:192.168.1.30;本地地址:192.168.1.33;如果跟其他设备有冲突,可以通过串口进行更改远程地址和本地地址,也可以进行场景功能切换;然后当连上tcp通信时,LED1闪烁可以通过tcp进行模式的指令的接收,可以切换场景模式,以及设备发送给上位机的指令,和上位机发给下位机其他操作指令,通过modbus tcp协议;使用modbustcp进行控制,定义一下八种模式的切换对应modbustcp指令,
在freertos中创建一个任务进行modbustcp的解析,通过解析得到的数据进行场景任务切换。
例如模式切换完之后,要保存到W25Q64当中,当设备断电时,不用重新配置,直接读取W25Q64当中的内容,进行模式的切换;