# 基于立创梁山派的21年电赛F题智能送药小车
**⚙️简介:**:全国产化器件制作的基于立创梁山派的21年电赛F题智能送药小车
* **硬件部分**:扩展板由电机驱动,国产姿态传感器及磁力计,蜂鸣器驱动,按键和药物检测,ADC电压采集,CAN芯片等组成。国产蓝牙模块实现双车通讯,K210实现数字识别和巡红线。
* **软件部分**:国产RT-Thread,PID控制电机实现位置环和速度环,姿态解算,K210数字识别和红线识别,定义串口通讯协议并DMA接收+ringbufer缓存处理,各数据交换使用发布订阅机制。
* **教程部分**:[请点这里](https://dri8c0qdfb.feishu.cn/wiki/ZDYbwqDfCiwVlckUEcScF0KSnRh)
![medical_car](./4_Docs/images/medical_car.png)
**简要视频:**
1. [赛题分析](https://www.bilibili.com/video/BV1Ku411s7Pu/)
2. [电路设计](https://www.bilibili.com/video/BV1424y1A7b2/)
3. [代码编写](https://www.bilibili.com/video/BV18M4y1e7UP/)
------
**简要文章:**
1. [赛题分析](./4_Docs/赛题分析.md)
1. [电路设计](./4_Docs/电路设计.md)
------
**精简文档:**
1. [00_单个小车BOM表](./4_Docs/00_单个小车BOM表.md)
2. [01_组装文档](./4_Docs/01_组装文档.md)
3. [02_编译文档](./4_Docs/02_编译文档.md)
4. [03_软件工具与调试工具介绍](./4_Docs/03_软件工具与调试工具介绍.md)
5. [04_建立RT-Thread工程模板](./4_Docs/04_建立RT-Thread工程模板.md)
6. [05_Finsh控制台的使用](./4_Docs/05_Finsh控制台的使用.md)
7. [06_如何计算小车轮子转速](./4_Docs/06_如何计算小车轮子转速.md)
8. [07_电机驱动-舵机-蜂鸣器PWM配置](./4_Docs/07_电机驱动-舵机-蜂鸣器PWM配置.md)
9. [08_直流减速电机PID速度环与位置环调试](./4_Docs/08_直流减速电机PID速度环与位置环调试.md)
10. [09_国产IMU移植及姿态解算](./4_Docs/09_国产IMU移植及姿态解算.md)
11. [10_小车角度环的调试与实现](./4_Docs/10_小车角度环的调试与实现.md)
12. [11_K210更换固件-运行基础颜色识别例程](./4_Docs/11_K210更换固件-运行基础颜色识别例程.md)
13. [12_K210的KPU数字识别训练](./4_Docs/12_K210的KPU数字识别训练.md)
14. [13_K210功能实现代码讲解](./4_Docs/13_K210功能实现代码讲解.md)
15. [14_立创梁山派与K210串口通信协议框架搭建](./4_Docs/14_立创梁山派与K210串口通信协议框架搭建.md)
16. [15_小车寻红线环的调试与实现](./4_Docs/15_小车寻红线环的调试与实现.md)
17. [16_按键检测的消抖和实现](./4_Docs/16_按键检测的消抖和实现.md)
18. [17_送药小车数据的发布与订阅](./4_Docs/17_送药小车数据的发布与订阅.md)
19. [18_送药小车实现思路](./4_Docs/18_送药小车实现思路.md)
# 一 目录结构
- [0_STL](./0_STL):小车上的3D打印文件。
- [1_Hardware](./1_Hardware):小车扩展板PCB以及底板PCB结构件。
- [2_Code](./2_Code):代码部分,包含梁山派MDK工程和K210程序。
- [3_Tool](./3_Tool):常用软件工具。
- [4_Docs](./4_Docs):文档说明。
# 二 使用说明
## 了解过 RT-Thread ENV 开发工具
1. 克隆本仓库到本地。
2. 进入`2_Code`目录,使用 [ENV](https://club.rt-thread.org/ask/question/5699.html) 工具执行 `pkgs --update`下载缺失的软件包。
3. 使用 [ENV](https://club.rt-thread.org/ask/question/5699.html) 工具执行 `scons --target=mdk5`更新MDK5工程文件。
4. 打开`2_Code`目录下的`project.uvprojx`即可正常编译使用了。
## 从来没用过RT-Thread
1. 去[RT-Thread文档中心](https://www.rt-thread.org/document/site/#/)了解了解。
2. 进入仓库的[发行版](https://gitee.com/lcsc/medical_car/releases/tag/V1.0.0),下载附件[2_code.zip](https://gitee.com/lcsc/medical_car/releases/download/V1.0.0/2_Code.zip)。
3. 解压后打开目录下的`project.uvprojx`即可正常编译使用了。
# 三 代码介绍
所有自己添加的文件都在[applications](https://gitee.com/lcsc/medical_car/tree/master/2_Code/applications)目录下。
## 梁山派GD32端
### RTOS选择并建立模板
为了配合梁山派的全国产化,本次的RTOS选择国内优秀的RT-Thread,RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。经过 16 个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。
它与其他RTOS最大的区别是他有一个软件包库,有许多开源的大佬分享自己做的软件包。如果你选用支持RT-Thread的芯片来开发项目,就可以使用它丰富的软件包。比如说想读取MPU6050的数据,直接在ENV工具中选择MUP6050的软件包,重新生成工程,运行例程就可以获得数据了。比如想做一个按键驱动,在软件包中搜索 按钮,就会有数个软件包供你选择,你可以专注于做应用,底层的大部分驱动都是可以复用的。
梁山派目前已经适配基础版RT-Thread,[链接](https://github.com/RT-Thread/rt-thread/tree/master/bsp/gd32/arm/gd32470z-lckfb).
建议不要选择master分支进行开发,因为主分支处于一直开发的状态,可能会有意想不到的BUG。一般要选一个稳定的版本。我这里选用的RT-Thread-V4.1.1。
### BSP底层初始化编写
当前梁山派还没有适配RT-Thread的PWM,ENCODER等外设资源,所以需要我们自己进行初始化配置。
主要有蜂鸣器PWM的配置,电机驱动PWM的配置,正交编码器的配置,舵机PWM的配置。
以蜂鸣器初始化为例。
首先要知道确切的系统时钟和定时器时钟频率。打开GD32参考手册的第四章节:复位和时钟单元(RCU)里面的图4-2.时钟树。再找到keil工程下面Drivers里面的board.c里面的SystemClock_Config。找到系统时钟之后找一下APB2和APB1的时钟频率。以蜂鸣器的PWM配置为例。可以看到BEEP_TIMER就是TIMER12,它挂在APB1时钟下,/* APB1 = AHB/4 */就是说APB1是60M,TIMER时钟由AHB时钟分频获得,它的频率可以等于CK_APBx、CK_APBx的两倍或CK_APBx 的四倍。详细信息请参考RCU_CFG1寄存器的TIMERSEL位,因为我们是给APB分频了的。所以定时器时钟等于 APB 时钟的两倍,所以这里的TIMER12时钟是60M*2=120Mhz,在这里的30-1,要-1是因为这里的计数是从0开始的。接下来就是简单的除法计算了。//120Mhz/30=4000000Hz
这里用到了自动初始化:RT-Thread总共有六个初始化顺序
> 1 INIT_BOARD_EXPORT(fn)
>
> 非常早期的初始化,此时调度器还未启动
>
> 2 INIT_PREV_EXPORT(fn)
>
> 主要是用于纯软件的初始化、没有太多依赖的函数
>
> 3 INIT_DEVICE_EXPORT(fn)
>
> 外设驱动初始化相关,比如网卡设备
>
> 4 INIT_COMPONENT_EXPORT(fn)
>
> 组件初始化,比如文件系统或者 LWIP
>
> 5 INIT_ENV_EXPORT(fn)
>
> 系统环境初始化,比如挂载文件系统
>
> 6 INIT_APP_EXPORT(fn)
>
> 应用初始化,比如 GUI 应用
#### bsp_beep
这段代码是一个嵌入式系统中的示例程序,主要用于初始化和控制蜂鸣器(beep)的功能。
代码的主要功能如下:
1. 导入头文件:包含了一些需要使用的头文件,包括`stdio.h`(标准输入输出)、`rtthread.h`(RT-Thread操作系统)、`board.h`(板级支持包)、`gd32f4xx_libopt.h`(GD32F4xx外设库)、`bsp_beep.h`(蜂鸣器驱动头文件)等。
2. `beep_pwm_gpio_init`函数:该函数用于初始化蜂鸣器的GPIO引脚。具体操作包括使能蜂鸣器所在的GPIO时钟、配置GPIO引脚为复用功能、设置GPIO输出选项等。
3. `beep_timer_init`函数:该函数用于初始化蜂鸣器的定时器(timer)。具体操作包�