# Hero2022-vcode **Repository Path**: RosenYin/hero2022-vcode ## Basic Information - **Project Name**: Hero2022-vcode - **Description**: gcc编译器开发的英雄云台C板程序 - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-22 - **Last Updated**: 2023-06-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README /************************************************************************************\ * * _____ _____ ____ * /\ \ /\ \ /\ \ * /::\ \ /::\ \ /::\ \ * \:::\ \ /::::\ \ /::::\ \ * \:::\ \ /::::::\ \ /::::::\ \ * \:::\ \ /:::/\:::\ \ /:::/\:::\ \ * \:::\ \ /:::/ \:::\ \ /:::/__\:::\ \ * /::::\ \ /:::/ \:::\ \ /::::\ \:::\ \ * /::::::\ \ /:::/ / \:::\ \ /::::::\ \:::\ \ * /:::/\:::\ \ /:::/ / \:::\ \ /:::/\:::\ \:::\ \ * /:::/ \:::\____\/:::/____/ \:::\____\/:::/__\:::\ \:::\____\ * /:::/ /\::/ /\:::\ \ /:::/ /\:::\ \:::\ \::/ / * /:::/ / \/____/ \:::\ \ /:::/ / \:::\ \:::\ \/____/ * /:::/ / \:::\ \ /:::/ / \:::\ \:::\ \ * /:::/ / \:::\ /:::/ / \:::\ \:::\____\ * /:::/ / \:::\ /:::/ / \:::\ \::/ / * /:::/ / \:::\/:::/ / \:::\ \/____/ * /:::/ / \::::::/ / \:::\ \ * /:::/ / \::::/ / \:::\____\ * \::/ / \::/ / \::/ / * \/___/ \/____/ \/____/ ************************************************************************************\ */ 我的环境配置教程:https://robomaster.ones.pro/wiki/#/team/T6gsU22v/space/oqJvJWK4/page/2okLKyCo 注意:链接可能会挂,打开ones后,有一个配置教程模块,vscode开发STM32配置教程在电控配置里。 VsCode工程缺点: 没有一个十分好用的debug,无法像别的IDE一样能够在debug的时候实时查看变量信息 所以建议使用JLink,它官方自带的Ozone非常好用(比keil好用),弥补了vscode不能debug的缺陷。 如果你想在Ozone中实时查看FreeRTOS中每个任务占据的内存大小的话,需要你在 Inc\FreeRTOSConfig.h 文件中增加 #define configRECORD_STACK_HIGH_ADDRESS 1 这一行代码,你可以先检查一下自己的程序中是不是有。 ----->注意: 1.如果你要使用CubeMX重新生成程序,有可能会导致makefile清空,建议重新生成前把makefile添加bak后缀,防止被覆盖掉。 2.文件夹名字中绝不可以有空格!!! 3.那些烧录工具尽量添加到系统环境变量里,否则要在.vscode/tasks.json中修改路径 4.想换车必须要在./Module/Mode_Switch.h中修改宏定义,只要你有多台车,就不可以把程序分成两个工程。 一、学习路线 1、嵌入式基础学习 先从CubeMX创建一个现成的IDE开始(Keil、CubeIDE、sw4stm32等),学习创建工程、IDE的使用,如何使用HAL库函数的API,学着自己去写一个bsp板级支持包 遇到不会的一定要补基础,一定要看明白总线每个参数或者寄存器什么意思,最起码用到的要眼熟掌握,可以用过往学长的bsp或者一些程序或者官方程序去学习, 因为对我们的比赛调车是直接性帮助。 2、学习编译的一些基本原理,最起码gcc生成一个可执行文件的流程要清楚(VsCode要掌握) 学习gcc命令,Makefile语法,学着自己去创建一个多文件c工程然后使用gcc和makefile编译 然后就可以学着去搭建自己的工具链,当然了解后还是建议使用成品IDE,因为简单好用,让你的精力集中在优化你的代码上,而不是天天配环境 3、CMake、xmake等编译工具的使用 可以依靠VsCode,去用插件来辅助,编译一些简单C\C++工程,就足够了,CMake是常用工具,建议学一下。 二、程序结构 咱的.c和.h文件放在同一个路径下了,单纯为了方便,因为.h文件也有好多有关配置的,方便好找就放在一起了,你可以.c一个文件夹.h一个文件夹,看个人喜好 1、所有bsp板级支持包文件放在./bsp/board里; bsp_can.c文件是最重要的文件,里面有电机数据接收、底盘C板数据接收和UI数据的一些转发; Bsp_RC.c文件是照着官方移植的遥控器数据串口接收程序,使用了双缓冲DMA,可以仔细看看源码,我标注了详细的注释; bsp_usart.c文件中主要使用C板4pin口的那个usart1,用来无线调参和数据打印; bsp_timer.c文件主要是控制C板上那个小2pin插口的pwm,这个是用来控制RM官方那个红外激光的; 其余的bsp文件都是官方自己的。 2、所有线程的文件放在 Thread 里: 云台控制程序放在Gimbal_task.c中; 底盘控制程序放在Chassis_task.c中; 发射机构控制程序放在Shoot_task.c中; 陀螺仪数据处理程序在INS_task.c中; 自检程序(计算FPS,蜂鸣器报警)在Monitor_task.c中; 串口打印程序我单开了一个线程,堆栈给了很大,专门用来蓝牙打印串口用; 其余的线程是官方自带的,主要是C板全片擦写后陀螺仪校准数据存在flash中。 3、模式控制以及pid计算放在Module里, Chassis.c文件用来解算底盘运动,然后计算pid,最后给电机发送电流; Gimbal.c文件用来解算云台; Shoot.c文件用来解算发射机构电机电流。 4、有关stm32外接设备相关的都在./components/devices, 串口重定向格式化文件print.c也在里面,这个是arm-gcc工程专有的,如果你用Keil,简单重定向就好了,参考实验室祖传代码或者正点原子的教程 其中的设备有:BMI088、IST8310、NUC、串口发送(printf)。 5、有关控制设备的都在./components/controller,比如: 计算总线fps和蜂鸣器报警在Monitor里; STMGood上位机在STMGood.c里,已经开启了所有通道的参数输入; 电机编码器解算在motor.c里。 6、有关控制算法的都在./components/algorithm里, pid.c文件是一些pid解算的接口; CRC_Check.c是给PC发送数据时用到的,用来校验串口数据; ramp.c是计算斜坡函数的,是有关斜坡函数的一些接口; filter.c文件是陈澍学长写的低通滤波接口,跟INS_task.c文件中写的滤波一摸一样,是为了调用方便,后来也没再用了; user_lib.c是自己总结的一些常用快速算法,比如快速开方之类的; 剩余的比如 MahonyAHRS.c、AHRS_middleware.c 都是有关陀螺仪解算的接口。 7、一些官方的静态库文件和arm的数学静态库文件放在了./lib路径下 主要是 libAHRS.a 和 libarm_cortexM4lf_math.a; 一个是官方陀螺仪解算,一个是STM32官方的库文件,这个文件我是在cubemx下载的stm32f407ig包里找到的。 8、最终的二进制文件保存在./build。 9、UI的程序是用keil构建的,这个懒得重构了。 三、程序设计思路 在基础差不多学完以后,就该开始设计一个自己熟悉的程序框架了,我的框架是基于丁羽昊学长的框架,在其上修修补补的 首先所有的解算与功能放在一起,用标志位去控制模式,再用遥控器或者按键去改变标志位,要有一个习惯,硬件上的操作基本都是操作标志位,然后通过标志位 来改变你想要的功能,在中断里去处理数据是非常耗费性能的,但是有时候为了不出现一些奇怪的bug,还是在中断里去处理了,那是极少的一部分。 我们与PC数据传输的方式是使用虚拟USB,随便搜一个教程,在CubeMX里点点就可以配置成功了,只不过注意,要接收消息必须要把接收消息的函数写在usbd_cdc_if.c 文件里的 CDC_Receive_FS 函数中,发送消息只需要调用 CDC_Transmit_FS 函数即可。