mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-06-14 22:16:38 +08:00
添加gpio_key
This commit is contained in:
parent
37d6f70055
commit
3da80d5efb
BIN
User/.DS_Store
vendored
BIN
User/.DS_Store
vendored
Binary file not shown.
BIN
User/bsp/.DS_Store
vendored
BIN
User/bsp/.DS_Store
vendored
Binary file not shown.
@ -6,6 +6,7 @@
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static uint32_t led_stats; // 使用位掩码记录每个通道的状态,最多支持32LED
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
|
||||
#include "gpio.h"
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
/* Exported macro ----------------------------------------------------------- */
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
|
BIN
User/device/.DS_Store
vendored
BIN
User/device/.DS_Store
vendored
Binary file not shown.
@ -1,86 +1,65 @@
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "key_gpio.h"
|
||||
#include "device.h"
|
||||
#include <gpio.h>
|
||||
|
||||
#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) {
|
||||
// 持续按住超过20ms进入HOLD状态
|
||||
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)
|
||||
{
|
||||
BSP_GPIO_RegisterCallback(BSP_GPIO_USER_KEY, BSP_GPIO_EXTI_CB, KEY_Interrupt_Callback);
|
||||
|
||||
//仅按下就执行逻辑
|
||||
// if( key.state == DEVICE_KEY_PRESSED)
|
||||
// {
|
||||
// //循环执行逻辑(按下)
|
||||
// }
|
||||
//按住才执行逻辑,松开就停下
|
||||
if (key.state == DEVICE_KEY_LONG_PRESS)
|
||||
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
|
||||
{
|
||||
//停止逻辑
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t KEY_Get_State(void) {
|
||||
return key_pressed;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef KEY_GPIO_H
|
||||
#define KEY_GPIO_H
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
#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);
|
||||
#endif
|
||||
|
115
开发要求.md
115
开发要求.md
@ -1,10 +1,105 @@
|
||||
# BSP
|
||||
按照规范开发
|
||||
# component
|
||||
按照规范开发
|
||||
# develop
|
||||
按照规范开发
|
||||
# module
|
||||
按照规范开发
|
||||
# task
|
||||
按照规范开发
|
||||
# 嵌入式 代码
|
||||
|
||||
## 软件功能介绍
|
||||
|
||||
中心思想:
|
||||
|
||||
- 利用好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的运行容器,也包含通信、姿态解算等 |
|
||||
|
||||
## 系统介绍
|
||||
|
||||
### 硬件系统框图
|
||||
|
||||
|  |
|
||||
|:--:|
|
||||
| *步兵嵌入式硬件框图* |
|
||||
|
||||
### 软件流程图
|
||||
|
||||
|  |
|
||||
|:--:|
|
||||
| *步兵嵌入式硬件框图* |
|
||||
|
||||
|  |
|
||||
|:--:|
|
||||
| *嵌入式程序结构图* |
|
||||
|
||||
## 原理介绍
|
||||
|
||||
### 云台控制原理
|
||||
|
||||
|  |
|
||||
|:--:|
|
||||
| *云台控制原理(与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. 在步兵上完成所有功能。
|
||||
|
Loading…
Reference in New Issue
Block a user