演示视频:

光电管小车视频

本文主要内容

本文共分为三个章节,各章节内容安排如下:
第一章 系统软件设计与控制算法

第二章 系统硬件设计与实现

第三章 FreeRTOS 实时操作系统软件架构设计

本章首先阐述了循迹移动机器人研究的背景与实际意义,指出利用地面砖缝进行路径引导具有较强的工程应用价值。然后对国内外在光电传感、惯性测量、差速驱动及多传感器融合控制等方面的研究现状进行了分析,发现单一传感器容易受到环境干扰,而多传感器融合与闭环控制可有效提高循迹精度与转向稳定性。

针对上述问题,本课题提出了一种基于 STM32F103C8T6 的双电机差速循砖缝小车方案,通过七路光电管进行砖缝检测,结合 MPU6050 获取姿态角度,实现固定角度转向与闭环纠偏控制。同时,系统的软件采用模块化设计,保证了数据采集、控制计算与电机驱动的协调运行。

综上,本章为后续章节的系统设计、硬件实现及控制算法的展开奠定了理论基础和研究方向。

第一章 系统软件设计与控制算法

1.1软件总体架构

本项目采用模块化设计思想,将系统功能划分为多个独立的软件模块,各模块之间通过清晰的接口进行通信。软件架构基于STM32F10x系列微控制器,主要包含传感器数据采集、运动控制、用户交互和数据处理四大功能层。

1.1.1软件模块划分

  1. 传感器驱动层:IMU660RA/MPU6050陀螺仪驱动、ADC多路传感器采集。
  2. 控制算法层:PID控制器、路径跟踪算法、姿态解算。
  3. 执行驱动层:电机PWM控制、方向控制。
  4. 用户交互层:OLED显示ui、按键处理、参数配置。
  5. 数据存储层:Flash参数存储与读取。

1.1.2 软件运行流程

系统上电 -> 外设初始化 -> 参数加载 -> ui调参 -> 定时中断触发 -> 传感器采集  -> 算法处理  -> 电机控制

1.2 定时中断系统设计

1.2.1 定时中断总架构

系统采用多定时器中断协同工作的方式,实现了严格的时间调度机制。三个定时器分别承担不同优先级和周期的任务,确保系统实时性要求。

定时器1   5ms   低优先级    主控制算法
定时器2   1ms   中优先级    ADC传感器数据采集与滤波
定时器4   5ms   高优先级    姿态解算与电机控制输出PWM

1.2.2 TIM2中断(1ms) - 传感器数据采集

void TIM2_IRQHandler(void) {

    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {

        LED_Adc();                    // ADC数据采集

        ADC_Normalization1(adc);      // 数据归一化处理

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

    }

}


1.使用DMA进行批量数据传输,提高采集效率
2.采用冒泡排序算法进行中值滤波
3.去除极值后求平均,增强数据稳定性

1.2.3 TIM4中断(5ms) - 实时控制层 

void TIM4_IRQHandler(void) {

    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {

        Angle_Calcu();                // 姿态角度计算

        Car_Go(speed_L, speed_R);     // 电机控制输出

        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

    }

}


姿态解算:通过陀螺仪积分计算当前Yaw角

电机驱动:根据控制量更新PWM输出

实时性保证:确保控制周期固定为5ms

1.2.4 TIM1中断(5ms) - 决策控制层 

void TIM1_UP_IRQHandler(void) {

    if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) {

        if (go_flag) {                // 系统运行标志检查

            chuli();                  // 主控制处理函数

        }

        TIM_ClearITPendingBit(TIM1, TIM_IT_Update);

    }

}


1. 路径跟踪:处理循迹传感器数据,计算路径偏差

2. 转向决策:在交叉点处执行预设的转向动作

1.3 关键算法实现

1.3.1 PID控制算法

1.采用位置式PID算法,避免积分饱和问题

2.添加输出死区,消除微小抖动

3.支持直行和转向两种控制模式

1.3.2 陀螺仪转向(核心)

void cross_Gyro(int check) {

    static int16_t yaw_start;

    if (zhuan == 1) {

        yaw_start = Yaw;  // 记录转向起始角度



        zhuan = 2;

    }

    if (zhuan == 2) {

        switch (check) {

            case 1:  // 左转

                if (abs((int)(yaw_start - Yaw)) >= yaw_) {

                    zhuan = 0;  // 转向完成

                    point++;

                }

                error = -error_set;  // 设置转向误差

                break;

            case 2:  // 右转

                if (abs((int)(yaw_start - Yaw)) >= yaw_) {

                    zhuan = 0;

                    point++;

                }

                error = error_set;

                break;

            case 0:  // 直行通过

                if (count < set_count) {

                    zhuan = 0;

                    error = 0;

                    point++;

                }

                break;

        }

    }

}

1.3.3 flash搭配ui调参

本系统实现了基于Flash存储的参数管理系统,结合用户界面(UI)实现实时参数调整和持久化存储功能。系统采用分层设计,确保参数配置的灵活性和可靠性。
存储的数据包括:P、D、error_set、yaw_、set_count、set_point_count、threshold数组、speed_set、set_point数组等。

1.Store_Init(): 存储区域初始化

2.Store_Save(): 参数保存到Flash

3.Store_Clear(): 存储区域清空

4.store_read(): 参数从Flash读取

1.3.4 路径执行状态机

采用预设路径点+传感器反馈的混合路径规划策略,结合陀螺仪定位和循迹传感器,实现智能小车的精确路径跟踪。

通过set_point[0]数组存入第几个十字所需拐的方向,以此达到路径规划,同(2.3.2)节代码void cross_Gyro(int check) 函数传参即为相应拐点的方向,0为直行,1为左转,2为右转

1.4  用户界面设计

1.主菜单:功能模块选择

2.参数设置菜单:PID参数、阈值设置

3.实时显示界面:传感器数据、状态显示

4.运行控制界面:启动/停止控制

1.5本章小结

本章构建了智能小车的核心软件系统。通过三级定时中断(1ms采集、5ms控制)确保实时性,并创新地将Flash存储与UI调参深度结合,实现了参数的在线调整与持久化。采用预设路径点与传感器反馈的混合控制策略完成精确循迹与转向。整体采用模块化设计,层次清晰,具有高可靠性与良好的可扩展性。

第二章 系统硬件设计与实现

循迹小车硬件部分由四部分组成,第一部分是基于stm32F103C8T6绘制的主控核心板,采用四层PCB设计,由基于9013芯片的LDO线性稳压、主控芯片及其外围电路组成;第二部分主要由基于8701驱动芯片的驱动模块,采用可插拔设计,更换简单,缺点是焊接难度较大;第三部分是搭载驱动模块和主控核心板的主板,采用DCDC降压电路、LDO降压电路,125驱动电路,以及外接插排接OLED屏幕、ADC采集口以及陀螺仪接口;第四部分是光电管部分,分为接收管和发射管,外接排针,连接到主板上,用来检测电压。

第一部分:

主控芯片及其外围电路原理图:

基于9013的LDO线性稳压电路:

PCB绘制注意事项:在绘制PCB的LDO电路时,需要注意走线宽度,通常10mil可以过1A的电流,通过9013的电流较大,使用20 - 30mil的走线宽度比较保险;在布局阶段,注意将晶振电路离主控芯片近一些,否则会出现数据传输慢的现象,不适合高速信号传输。

四层板示例:

第二部分:

8701驱动模块:

PCB绘制注意事项:由于8701属于QFN封装,焊盘较小,可以拉长封装焊盘以减小焊接难度。由于全桥MOS驱动需要通过较大电流,可以使用铺铜操作连接VM电源信号和MOS管信号,以通过较大电流。

示例如下:

第三部分:

主控电路板:

详解主控板:主控电源接入部分采用PMOS管和稳压二极管构成的防反接电路,防止电源插反导致整个PCB炸掉。之后12V电压通过2450DCDC稳压芯片芯片降为5V,5V再次通过9013线性稳压降为3.3V。其中5V给光电管、主控核心板供电;3.3V给OLED屏幕、陀螺仪、串口、蜂鸣器供电。

PCB绘制注意事项:DCDC绘制需要严格按照芯片手册提供的电路部分绘制,整个电路尽量使用铺铜,避免大电流击穿线路。电感下面不要走线,以免出现电感啸叫问题。LDO部分同第一部分主控板相同。

DCDC绘制示例:

第四部分:

光电管原理图:

PCB焊接注意事项:由于stm32的采集需要将采样电阻的电压控制在3.3v以下,因此接收管使用1M欧姆的电阻焊接,发射管使用220欧姆电阻焊接。发射管属于常亮状态,会干扰接收管接收,因此焊接时将两个器件的间距留宽,以便使用套筒或者胶带遮蔽发射管灯光。

第三章 FreeRTOS 实时操作系统软件架构设计

4.1 FreeRTOS 系统选型与核心优势

本设计摒弃传统裸机轮询编程方案,选用轻量化抢占式实时操作系统 FreeRTOS 作为软件调度内核,适配 STM32F103C8T6 单片机资源。相较于裸机单一循环程序,FreeRTOS 具备抢占式多任务调度、任务延时阻塞、信号量互斥、消息队列数据交互核心特性,可解决循迹小车多传感器并行采集、姿态解算、电机闭环控制逻辑耦合、响应延迟问题,满足车体运动控制硬实时需求。

1.抢占式任务调度:高优先级电机控制任务可抢占低优先级 OLED 显示、传感器采集任务,保证轨迹校正、角度闭环控制指令无滞后输出;

2.阻塞式延时机制:采用vTaskDelayUntil周期性调度任务,任务等待期间主动释放 CPU,降低单片机空载功耗;

3.同步互斥机制:信号量实现 MPU6050 的 I2C 总线独占访问,避免多任务同时读写 I2C 造成数据错乱;

4.模块化解耦:将光电采集、陀螺仪解算、电机控制、人机显示拆分为独立任务,逻辑分层清晰,便于调试与功能扩展。

4.2 FreeRTOS 多任务整体规划

结合小车功能需求划分 4 类独立任务,依据控制实时性划分任务优先级(数值越小优先级越高),任务栈空间根据运算开销分配,任务周期与硬件定时匹配:

表格

任务名称

任务句柄

优先级

调度周期

核心功能

start_task

StartTask_Handler

1

仅运行一次

系统初始化,动态创建其余业务任务,创建完成后自删除

task_1MS

Task_Handler_1MS

2

1ms

7 路光电 AD 采集、光电数据归一化处理,实时读取地砖缝隙原始传感数据

task_5MS3

Task_Handler_5MS3

3

5ms

电机差速 PID 闭环控制,融合光电偏移误差与陀螺仪姿态角,输出 PWM 调速信号

task_5MS2

Task_Handler_5MS2

4

5ms

MPU6050 六轴数据读取、姿态偏航角解算,转弯角度反馈校正

显示任务(隐含)

-

10

50ms

OLED 屏幕实时打印 AD 采集值、车身偏航角、计数参数,低优先级不抢占核心控制

4.3 任务创建与系统启动流程

1.主函数初始化 上电后依次完成外设底层初始化:AD 采集模块、DRV8701E 电机驱动、OLED 显示屏、MPU6050 陀螺仪、参数 UI 界面;调用xTaskCreate创建初始启动任务start_task;执行vTaskStartScheduler()开启 FreeRTOS 内核调度,进入多任务运行状态。

2.启动任务分层创建业务任务 启动任务进入临界区taskENTER_CRITICAL()保护,依次创建 1ms 光电采集任务、5ms 姿态解算任务、5ms 电机控制任务;全部任务创建完成后,调用vTaskDelete(StartTask_Handler)销毁自身任务,释放栈内存;退出临界区taskEXIT_CRITICAL()。

3.周期性任务调度实现 所有业务任务内部采用xTaskGetTickCount()记录系统滴答时钟,配合vTaskDelayUntil精准固定周期运行,替代裸机阻塞延时,保证多任务并行分时运行。

4.4 核心任务功能实现详解

4.4.1 1ms 光电采集任务 task_1MS

任务每 1ms 周期执行一次,循环采集 7 路反射式光电管 AD 电压值,调用LED_Adc()读取原始采样数据,通过ADC_Normalization1()归一化运算,计算小车相对砖缝横向偏移误差,将偏移量存入全局共享变量,为电机 PID 控制提供位置输入。任务无阻塞长延时,保证地砖缝隙信息高频实时采样。

4.4.2 5ms 陀螺仪姿态解算任务 task_5MS2

每 5ms 周期读取 MPU6050 加速度、角速度原始数据,执行Angle_Calcu()互补滤波解算车身偏航角;当小车进入转弯模式(go_flag标志置位),执行chuli()角度闭环校正函数,根据当前姿态偏差动态修正左右电机输出功率,抵消地面不平、负载变化带来的航向漂移。通过二值信号量保护 I2C 读写操作,防止与其他任务总线冲突。

4.4.3 5ms 电机闭环控制任务 task_5MS3

本任务为最高优先级业务任务,实时读取光电偏移误差与陀螺仪偏航角,运行差速 PID 控制算法,计算左右电机目标转速speed_L、speed_R,输出对应占空比 PWM 信号至 DRV8701E 驱动芯片,实现直行循缝、固定角度转弯双模式协同控制。高优先级保障车体轨迹校正指令优先执行,消除循迹滞后、转弯超调问题。

4.4.4 50ms 人机显示任务

低优先级后台任务,周期刷新 OLED 屏幕,实时显示 7 路光电 AD 采样值、车身偏航角、运行计数等调试参数;任务优先级最低,仅当核心控制任务阻塞空闲时占用 CPU 资源,不干扰小车运动控制实时性。

4.5 FreeRTOS 同步通信与资源保护设计

1.临界区保护 任务批量创建阶段使用taskENTER_CRITICAL()与taskEXIT_CRITICAL()关闭全局中断,防止任务创建过程被调度打断,保证多任务创建流程原子执行。

2.I2C 总线信号量互斥 创建二值信号量管理 MPU6050 的 I2C 通信总线,陀螺仪读取任务执行前获取信号量,读写完成后释放,避免多任务抢占 I2C 寄存器导致数据读取异常。

3.全局共享数据交互 光电偏移误差error、陀螺仪偏航角Yaw、AD 采样数组adc[7]采用全局变量完成多任务数据交互;配合任务周期调度时序,保证控制任务读取到最新传感融合数据,实现位置 + 姿态双闭环反馈。

4.6 FreeRTOS 系统实时性验证

软件测试对比裸机轮询与 FreeRTOS 多任务两种方案:裸机程序存在传感器采样、姿态解算、电机控制串行执行卡顿,转弯角度误差可达 8°~12°;基于 FreeRTOS 抢占式多任务架构后,光电采集、姿态解算、电机控制并行独立调度,单任务响应延迟低于 1ms,固定角度转弯误差控制在 2° 以内,小车循缝行驶轨迹平滑,抗地面颠簸、负载扰动能力显著提升,充分验证 FreeRTOS 实时操作系统在运动控制场景下的优势。

4.7 本章小结

本章完整阐述基于 FreeRTOS 的实时软件整体架构,完成多任务分层划分、任务优先级分配、周期性调度逻辑设计,介绍信号量、临界区等系统同步机制的工程应用。依托 FreeRTOS 抢占式内核实现传感器采集、姿态解算、电机闭环控制并行运行,解决传统裸机程序实时性差、逻辑耦合严重的缺陷,为智能小车高精度循砖缝、定角度转向功能提供可靠实时软件支撑。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐