STM32实现四驱小车(一)硬件与软件准备

STM32实现四驱⼩车(⼀)硬件与软件准备
⽬录
⼀. 绪论
匆匆忙忙的2020年结束了,在机器⼈平台开发⽅⾯算是搞清了些端倪。近来总算有时间回顾过往,稍作整理。计划写⼀个专题系列,内容即为“机器⼈控制系统设计与实现”,这将会是我的系列⽂章的宗旨。机器⼈平台从地⾯⽆⼈车到空中⽆⼈机到⽔下⽆⼈潜航器,这将是⼀个可上九天揽⽉、可下五洋捉鳖的宏⼤蓝图。讲述内容从控制算法到嵌⼊式软件开发,从计算机仿真到单⽚机实战,从底层驱动到上层应⽤。所有的代码源于项⽬实战,讲述⽅式将是雅俗共赏。记录与分享⼼得的过程是快乐的,既是悦⼰、也可及⼈。如果有志同道合的朋友们可以动动⼩⽖点个关注,我们⼀起成长、⼀起进步叭!
第⼀篇从实现⼀个四轮四驱⼩车开始~
⼆. 轮式机器⼈概述
在机器⼈的⼤家庭⾥,轮式机器⼈独领风骚。轮式机器⼈常见的有两轮平衡车(⼆驱差速)、四轮车(四驱差速)、三轮车(⼆驱)、阿克曼转向⼩车(与汽车最为相似)、麦克纳姆轮(Mecanum wheel)⼩车、全向轮(omni wheel)⼩车等。感兴趣的⼩伙伴可以分别去了解运动与控制原理,市场上的绝⼤
部分地⾯移动机器⼈⼤抵都是基于以上平台了。这⾥我们实现⼀个四轮⼩车,四轮都有电机驱动,左右电机各为⼀组,控制左右侧电机差速即可实现转向,很简单有⽊有? 但是⿇雀虽⼩,五脏俱全,在此篇中我们基于STM32实现机器⼈的控制,使⽤UCOS-III操作系统,实现遥控器通信、传感器数据读取、航向⾓串级PID控制、电机PID控制全部功能。上位机地⾯站的开发我放在下⼀篇四轴飞⾏器的讲解中。
三. 硬件准备
1. 机械底盘
搭建四轮⼩车的机械部分就不细讲了,有条件的⾃⼰设计机架机加⼯或3D打印,没条件的直接买⼀个四轮底盘即可,电机、轮⼦配套,成本不⾼。
2. 电机选择
电机选择就很多了,⼩型四轮车常见的是编码器电机,如图1所⽰,⼀般是六根接线,两根编码器电源线,两根电源线,两根编码器信号线(A相B相)。只需要⼀路编码器就可⽤于测速,两路可以测⽅向,控制板需要解析编码器信号做速度闭环控制。
另外⼀种是总线电机,常见的是CAN总线电机、串⼝总线电机,这种电机⼀般会有配套的驱动器,控制板只需要给定速度、位置信号。如图所⽰是⼤疆的M3508⾏星减速电机与配套的C620电调(RoboMaster⽤的电机同⼀系列),可以使⽤CAN总线控制和PWM两种控制⽅式。本篇我们就⽤这个电机,基于CAN总线⽅式去做速度闭环。
3. 驱动板
锌溴电池驱动板是⼩车的⼤脑,由于本篇所实现的功能只是实现基本运动,就是遥控器控制⼩车直⾏和转弯,所以只需要⼀个底层驱动控制板,在后续增加⾼级功能之后会叠加上层控制器(如树莓派、英伟达)。
板⼦可以买,以可以画。主要是要有IIC、串⼝、CAN总线、编码器接⼝等外设接⼝和电源接⼝。前述的编码器电机的接⼝是通⽤的,淘宝上有很多板⼦是带了这种接⼝的,如果没有的话将电机的线分别接到对应的IO⼝即可,只是不太好看。
本⽂选择⾃主开发的使⽤STM32F7主控的驱动板,时钟频率216MHz,⼀般的智能⼩车应⽤都⾜够了。
4. 传感器
传感器主要是需要姿态传感器,⼀般使⽤九轴惯性传感器,即三轴陀螺仪、三轴加速度计、三轴磁⼒计。最终⽬的就是解算三轴姿态⾓,这⾥简单粗暴,直接买了⼀个姿态⾓传感器,如图所⽰是维特智能的传感器,串⼝输出三轴姿态⾓,其内部还是使⽤姿态解算算法算出来的。如果使⽤MPU9250等模块就需要⾃⼰进⾏解算了,后⾯有时间专门写⼀篇滤波算法与姿态解算。
5. 电池
建议选⽤锂电池。
四. 软件准备——UCOS-III操作系统
本系列⽂章都会使⽤操作系统,UCOS-III和FreeRTOS原理差不多,只不过前者商⽤后者免费,我使⽤的是UCOS-III。如果没有嵌⼊式操作系统的⼩伙伴们⾃⾏补补课叭,不会也没关系。不影响核⼼代码部分的阅读。
在空的操作系统的⼯程模板中,创建4个任务,⼀个CommunicateTask,SensorTask,StabilizationTask,MotorTask,分别进⾏遥控器通信、传感器数据读取、姿态控制、电机控制。使⽤操作系统的优势就是实时性,请⼤家牢记这个概念。 在操作系统下,每个任务都像是同时运⾏的,其实是分时复⽤,只有在多核的处理器上才能实现真正的同时。
⾸先在main⽂件的起始部分定义任务优先级、任务堆栈、堆栈⼤⼩、任务函数等。这⾥的startTask⽤于创建其他任务,创建完之后就挂起⾃⼰。
#define START_TASK_PRIO 3
//任务堆栈⼤⼩
#define START_STK_SIZE 128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void*p_arg);
//communicate任务
//设置任务优先级
智能筷子#define COMMUNICATE_TASK_PRIO 5// SBUS 信号的更新是在串⼝中断中进⾏的//任务堆栈⼤⼩
#define COMMUNICATE_STK_SIZE 512
//任务控制块
OS_TCB CommunicateTaskTCB;
//任务堆栈
CPU_STK COMMUNICATE_TASK_STK[COMMUNICATE_STK_SIZE];
//led0任务
速冻隧道void communicate_task(void*p_arg);
//stabalizer任务
//设置任务优先级
#define STABILIZATION_TASK_PRIO 4
延时电路//任务堆栈⼤⼩
#define STABILIZATION_STK_SIZE 2048
//任务控制块
OS_TCB StabilizationTaskTCB;
//任务堆栈
CPU_STK STABILIZATION_TASK_STK[STABILIZATION_STK_SIZE];
//led0任务
void stabilization_task(void*p_arg);
//Motor电机任务
//设置任务优先级
#define MOTOR_TASK_PRIO 7
//任务堆栈⼤⼩
#define MOTOR_STK_SIZE 512
//任务控制块
OS_TCB MotorTaskTCB;
//任务堆栈
CPU_STK MOTOR_TASK_STK[MOTOR_STK_SIZE];
//motor任务
u8 motor_task(void*p_arg);
//sensorTask 参数配置任务在线调试参数并写⼊flash
//设置任务优先级
#define SENSOR_TASK_PRIO 6
//任务堆栈⼤⼩
#define SENSOR_STK_SIZE 512
//任务控制块
OS_TCB SensorTaskTCB;
//任务堆栈
CPU_STK SENSOR_TASK_STK[SENSOR_STK_SIZE];
//motor任务
u8 sensor_task(void*p_arg);
在main函数中系统初始化、外设初始化、创建开始任务
{
OS_ERR err;
CPU_SR_ALLOC();
Write_Through();//Cahce强制透写
MPU_Memory_Protection();//保护相关存储区域
苒苒草Cache_Enable();//打开L1-Cache
Stm32_Clock_Init(432,25,2,9);//设置时钟,216Mhz
HAL_Init();//初始化HAL库实木花盆
delay_init(216);//延时初始化
uart1_init(100000);//串⼝1初始化
uart2_init(115200);//串⼝2初始化
uart3_init(115200);//串⼝3初始化
IIC_Init();//IIC通讯⼝初始化
//uart_imu_Init();      // 初始化串⼝IMU
//JY901_Init();    // 初始化IIC IMU , IMU的初始化都只需要执⾏⼀次,之后注释掉这两⾏代码
MY_ADC_Init();
KEY_Init();//按键初始化
LED_Init();//初始化LED
PWM_Init();
CAN1_Mode_Init(CAN_SJW_1TQ, CAN_BS2_6TQ, CAN_BS1_11TQ,3, CAN_MODE_NORMAL);//CAN初始化正常模式,波特率1000Kbps OSInit(&err);//初始化UCOSIII
OS_CRITICAL_ENTER();//进⼊临界区
//创建开始任务
OSTaskCreate((OS_TCB *)&StartTaskTCB,//任务控制块
(CPU_CHAR *)"start task",//任务名字
(OS_TASK_PTR)start_task,//任务函数
(void*)0,//传递给任务函数的参数
(OS_PRIO)START_TASK_PRIO,//任务优先级
(CPU_STK *)&START_TASK_STK[0],//任务堆栈基地址
(CPU_STK_SIZE)START_STK_SIZE /10,//任务堆栈深度限位
(CPU_STK_SIZE)START_STK_SIZE,//任务堆栈⼤⼩
(OS_MSG_QTY)0,//任务内部消息队列能够接收的最⼤消息数⽬,为0时禁⽌接收消息
(OS_TICK)0,//当使能时间⽚轮转时的时间⽚长度,为0时为默认长度,
(void*)0,//⽤户补充的存储区
(OS_OPT)OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,//任务选项
(OS_ERR *)&err);//存放该函数错误时的返回值
OS_CRITICAL_EXIT();//退出临界区
OSStart(&err);//开启UCOSIII
while(1)
;
}
开始任务的内容如下,内容就是创建其他四个任务,之后把⾃⼰挂起。
//开始任务函数
void start_task(void*p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
CPU_Init();
#if OS_CFG_STAT_TASK_EN >0u
OSStatTaskCPUUsageInit(&err);//统计任务
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间
CPU_IntDisMeasMaxCurReset();

本文发布于:2024-09-23 01:20:54,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/154948.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:任务   电机   控制   机器
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议