diff --git a/.DS_Store b/.DS_Store index c294515..e1626b4 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/User/.DS_Store b/User/.DS_Store index 01d915e..cf5987b 100644 Binary files a/User/.DS_Store and b/User/.DS_Store differ diff --git a/User/bsp/.DS_Store b/User/bsp/.DS_Store index d0dc709..dc0ff54 100644 Binary files a/User/bsp/.DS_Store and b/User/bsp/.DS_Store differ diff --git a/User/bsp/led_gpio.c b/User/bsp/led_gpio.c index 35b2902..c34b179 100644 --- a/User/bsp/led_gpio.c +++ b/User/bsp/led_gpio.c @@ -6,6 +6,7 @@ /* Private define ----------------------------------------------------------- */ /* Private macro ------------------------------------------------------------ */ /* Private typedef ---------------------------------------------------------- */ + /* Private variables -------------------------------------------------------- */ static uint32_t led_stats; // 使用位掩码记录每个通道的状态,最多支持32LED diff --git a/User/bsp/led_gpio.h b/User/bsp/led_gpio.h index 54b7aef..2d413b9 100644 --- a/User/bsp/led_gpio.h +++ b/User/bsp/led_gpio.h @@ -2,7 +2,7 @@ /* Includes ----------------------------------------------------------------- */ #include - +#include "gpio.h" /* Exported constants ------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */ diff --git a/User/device/.DS_Store b/User/device/.DS_Store index f792790..c4f3e22 100644 Binary files a/User/device/.DS_Store and b/User/device/.DS_Store differ diff --git a/User/device/key_gpio.c b/User/device/key_gpio.c index d15e240..a5ce605 100644 --- a/User/device/key_gpio.c +++ b/User/device/key_gpio.c @@ -1,86 +1,65 @@ /* Includes ----------------------------------------------------------------- */ #include "key_gpio.h" #include "device.h" -#include - +#include "bsp/gpio_exti.h" +#include "gpio.h" /* Private define ----------------------------------------------------------- */ +#define DEBOUNCE_TIME_MS 20 /* Private macro ------------------------------------------------------------ */ /* Private typedef ---------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */ +/* Private function -------------------------------------------------------- */ +/* ⲿ־λ־λ */ +volatile uint8_t key_flag = 0; // 1=£0=ɿ +volatile uint8_t key_exti = 0; +volatile uint8_t key_pressed = 0; // ȫֱ־λ +static uint32_t last_debounce_time = 0; // -static uint32_t key_stats; // ʹλ¼ÿͨ״̬֧32LED +/* Private function -------------------------------------------------------- */ +static void KEY_Interrupt_Callback(void) { + // л־λ״̬ -/* ⲿ־λ־ʣ */ -extern volatile uint8_t key_flag; // 1=£0=ɿ + key_flag = !key_flag; + key_exti = 1; -/* ״̬ṹ */ -typedef struct { - uint16_t state; // ǰ״̬ - uint32_t press_timestamp; // ʱ - uint8_t last_flag; // һεı־λ -} Key_Status_t; +} -static Key_Status_t key = { - .state = DEVICE_KEY_RELEASED, - .press_timestamp = 0, - .last_flag = 0 -}; - -/* жϴ */ -void Key_Process(void) { - uint32_t now = HAL_GetTick(); - uint8_t current_flag = key_flag; // ȡǰ־λ - - switch(key.state) { - case DEVICE_KEY_RELEASED: - if(current_flag == 1) { - // ״μ⵽£¼ʱ - if(key.last_flag == 0) { - key.press_timestamp = now; - } - // ȷϣ20msΪ£ - if((now - key.press_timestamp) > 20) { - key.state = DEVICE_KEY_PRESSED; - } - } - break; - - case DEVICE_KEY_PRESSED: - case DEVICE_KEY_LONG_PRESS: - if(current_flag == 1) { - // ס20msHOLD״̬ - if((now - key.press_timestamp) > 20) { - key.state = DEVICE_KEY_LONG_PRESS; - } - } else { - key.state = DEVICE_KEY_RELEASED; // ɿλ - } - break; - } - - key.last_flag = current_flag; // ʷ״̬ -} - -//ȡǰ״̬ -uint16_t Get_Key_State(void) { - return key.state; -} -//ҲǺ߼(ǰĴѭ -void KeyTask(void) +/* Exported functions ------------------------------------------------------- */ +void KEY_Process(void) { - - //¾ִ߼ -// if( key.state == DEVICE_KEY_PRESSED) -// { -// //ѭִ߼£ -// } - //סִ߼ɿͣ - if (key.state == DEVICE_KEY_LONG_PRESS) + BSP_GPIO_RegisterCallback(BSP_GPIO_USER_KEY, BSP_GPIO_EXTI_CB, KEY_Interrupt_Callback); + + if(key_exti == 1) { - //ִ߼ - } - else if (key.state == DEVICE_KEY_RELEASED) + uint32_t now = HAL_GetTick(); + // Ƿ񳬹ʱ + if ((now - last_debounce_time) > DEBOUNCE_TIME_MS) { + // Ч״̬谴Ϊ͵ƽ + if(key_flag == 0) + { + key_pressed = DEVICE_KEY_RELEASED; + } + if(key_flag == 1) + { + key_pressed = DEVICE_KEY_PRESSED; + } + } + else + { + HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6); + + } + last_debounce_time = now; // ʱ + key_exti = 0; + } + else { - //ֹͣ߼ + } -} \ No newline at end of file + } + +uint8_t KEY_Get_State(void) { + return key_pressed; +} + + diff --git a/User/device/key_gpio.h b/User/device/key_gpio.h index 861279c..8e0024a 100644 --- a/User/device/key_gpio.h +++ b/User/device/key_gpio.h @@ -1,9 +1,9 @@ -#pragma once - +#ifndef KEY_GPIO_H +#define KEY_GPIO_H /* Includes ----------------------------------------------------------------- */ #include #include "main.h" -//#include "key_gpio.h" + /* Exported constants ------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */ @@ -13,26 +13,9 @@ typedef enum { DEVICE_KEY_RELEASED, //ͷ DEVICE_KEY_PRESSED, // - DEVICE_KEY_LONG_PRESS, // } DEVICE_KEY_Status_t; +void KEY_Process(void); +uint8_t KEY_Get_State(void); -/* ͨ */ -typedef enum { - DEVICE_KEY_1, - DEVICE_KEY_2, - /* ɸҪչ */ - DEVICE_KEY_COUNT -} DEVICE_Key_Channel_t; - -/* Ӳýṹ */ -typedef struct { - GPIO_TypeDef *port; // GPIO˿ - uint16_t pin; // ű - uint8_t active_level; // ЧƽGPIO_PIN_SET/RESET - uint32_t trigger_edge; // жϴأRISING/FALLING -} DEVICE_Key_Config_t; - -void Key_Process(void); -uint16_t Get_Key_State(void); -void KeyTask(void); \ No newline at end of file +#endif diff --git a/开发要求.md b/开发要求.md index 2dd02ce..84970c1 100644 --- a/开发要求.md +++ b/开发要求.md @@ -1,10 +1,105 @@ -# BSP -按照规范开发 -# component -按照规范开发 -# develop -按照规范开发 -# module -按照规范开发 -# task -按照规范开发 \ No newline at end of file +# 嵌入式 代码 + +## 软件功能介绍 + +中心思想: + +- 利用好RTOS和中断,释放CPU性能,保证实时性。 +- 一个项目适配不同型号的机器人和不同的操作手。 + +减少维护的工作量,减少出错的可能性。 + +## 依赖&环境 + +- Windows平台下用CubeMX生成项目,然后用Keil uvesrion进行编辑、烧写和调试。 + +## 使用说明 + +- 环境安装 + - [MDK-ARM](https://www.keil.com/) (必备) + - [STM32CubeMX](https://www.st.com/zh/development-tools/stm32cubemx.html) (可选) + + +- 针对不同板子需要到不同的CubeMX工程文件(DevA.ioc、DevC.ioc)。 + +- (可选)利用CubeMX生成对应的外设初始化代码和Keil工程文件。忽略CAN总线相关错误。 + + - 每次生成代码后,请利用Git丢弃Middlewares文件夹中的所有改变。原因如下。 + + 1. 使用了AC6,与CubeMX默认不匹配,会影响到FreeRTOS的移植。 + 2. 使用了比CubeMX更新的FreeRTOS版本,降版本会导致部分代码无法编译。 + + - 因为已经生成过Keil工程文件,所以只会覆盖以前生成的代码,而不会影响手写的代码。 + + - 每次生成代码后,请在HAL_InitTick函数中添加uwTickPrio = TickPriority; + +- 打开MDK-ARM中的DevC.uvprojx即可进行编辑、烧写或调试。 + +- Keil工程中有两个Target,其中Debug用来调试,不包含编译器优化等;DevC/DevA用来编译输出最终固件。 + +## 文件目录结构&文件用途说明 + +| 文件夹 | 来源 | 内容 | +| ---- | ---- | ---- | +| Core | CubeMX | 包含核心代码,外设初始化,系统初始化等 | +| Doc | 开发者 | 文档 | +| Drivers | CubeMX | CMSIS相关库、STM32 HAL | +| Image | 开发者 | 图片 | +| MDK-ARM | CubeMX | Keil uversion 项目相关文件 | +| Middlewares | 开发者 / CubeMX | 中间件 | +| USB_DEVICE | CubeMX | USB相关文件 | +| User | 开发者 | 手动编写的代码 | +| Utils | 开发者 | 使用到的工具,如CubeMonitor, Matlab | + +| User内 | 内容 | +| ---- | ---- | +| bsp | 文件夹内包含开发板信息,基于STM32 HAL对板载的外设进行控制| +| component | 包含各种组件,自成一体,相互依赖,但不依赖于其他文件夹| +| device | 独立于开发板的设备,依赖于HAL和bsp| +| module | 对机器人各模块的抽象,各模块一起组成机器人| +| task | 独立的任务,module的运行容器,也包含通信、姿态解算等 | + +## 系统介绍 + +### 硬件系统框图 + +| ![步兵嵌入式硬件框图](./Image/步兵嵌入式硬件框图.png?raw=true "步兵嵌入式硬件框图") | +|:--:| +| *步兵嵌入式硬件框图* | + +### 软件流程图 + +| ![步兵嵌入式硬件框图](./Image/嵌入式程序流程图.png?raw=true "步兵嵌入式硬件框图") | +|:--:| +| *步兵嵌入式硬件框图* | + +| ![嵌入式程序结构图](./Image/嵌入式程序结构图.png?raw=true "嵌入式程序结构图") | +|:--:| +| *嵌入式程序结构图* | + +## 原理介绍 + +### 云台控制原理 + +| ![云台控制原理(与PX类似)](./Image/云台控制原理.png?raw=true "嵌入式程序结构图") | +|:--:| +| *云台控制原理(与PX类似)* | + +### 其他参考文献 + +- 软件架构参考[PX4 Architectural Overview](https://dev.px4.io/master/en/concept/architecture.html) + +- 云台控制参考[PX4 Controller Diagrams](https://dev.px4.io/master/en/flight_stack/controller_diagrams.html) + +- 底盘Mixer和CAN的Control Group参考[PX4 Mixing and Actuators](https://dev.px4.io/master/en/concept/mixing.html) + +## TODO +- 给BSP USB print加保护,允许不同进程的使用。 + - 给所有BSP加保护 + - device.c里面加上一个Device_Init(),在里面初始化所有mutex +- CAN设备代码优化。消息解析发送方向。 + - CAN设备动态初始化,保存好几组配置。 + +## Roadmap + +1. 在步兵上完成所有功能。