mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-02-04 18:00:19 +08:00
更新
This commit is contained in:
parent
d7aa8eb75c
commit
8138a777bd
79
bsp/fdcan/can.h
Normal file
79
bsp/fdcan/can.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file can.h
|
||||
* @brief CAN兼容层 - 将CAN接口映射到FDCAN
|
||||
* @note 本文件用于FDCAN兼容CAN接口,设备层代码可以继续使用BSP_CAN_xxx接口
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "bsp/fdcan.h"
|
||||
|
||||
/* 类型映射 */
|
||||
typedef BSP_FDCAN_t BSP_CAN_t;
|
||||
typedef BSP_FDCAN_Callback_t BSP_CAN_Callback_t;
|
||||
typedef BSP_FDCAN_Format_t BSP_CAN_Format_t;
|
||||
typedef BSP_FDCAN_FrameType_t BSP_CAN_FrameType_t;
|
||||
typedef BSP_FDCAN_Message_t BSP_CAN_Message_t;
|
||||
typedef BSP_FDCAN_StdDataFrame_t BSP_CAN_StdDataFrame_t;
|
||||
typedef BSP_FDCAN_ExtDataFrame_t BSP_CAN_ExtDataFrame_t;
|
||||
typedef BSP_FDCAN_RemoteFrame_t BSP_CAN_RemoteFrame_t;
|
||||
typedef BSP_FDCAN_IdParser_t BSP_CAN_IdParser_t;
|
||||
|
||||
/* 常量映射 */
|
||||
#define BSP_CAN_MAX_DLC BSP_FDCAN_MAX_DLC
|
||||
#define BSP_CAN_DEFAULT_QUEUE_SIZE BSP_FDCAN_DEFAULT_QUEUE_SIZE
|
||||
#define BSP_CAN_TIMEOUT_IMMEDIATE BSP_FDCAN_TIMEOUT_IMMEDIATE
|
||||
#define BSP_CAN_TIMEOUT_FOREVER BSP_FDCAN_TIMEOUT_FOREVER
|
||||
#define BSP_CAN_TX_QUEUE_SIZE BSP_FDCAN_TX_QUEUE_SIZE
|
||||
|
||||
/* 枚举值映射 */
|
||||
#define BSP_CAN_1 BSP_FDCAN_1
|
||||
#define BSP_CAN_2 BSP_FDCAN_2
|
||||
#define BSP_CAN_3 BSP_FDCAN_3
|
||||
#define BSP_CAN_NUM BSP_FDCAN_NUM
|
||||
#define BSP_CAN_ERR BSP_FDCAN_ERR
|
||||
|
||||
#define BSP_CAN_FORMAT_STD_DATA BSP_FDCAN_FORMAT_STD_DATA
|
||||
#define BSP_CAN_FORMAT_EXT_DATA BSP_FDCAN_FORMAT_EXT_DATA
|
||||
#define BSP_CAN_FORMAT_STD_REMOTE BSP_FDCAN_FORMAT_STD_REMOTE
|
||||
#define BSP_CAN_FORMAT_EXT_REMOTE BSP_FDCAN_FORMAT_EXT_REMOTE
|
||||
|
||||
#define BSP_CAN_FRAME_STD_DATA BSP_FDCAN_FRAME_STD_DATA
|
||||
#define BSP_CAN_FRAME_EXT_DATA BSP_FDCAN_FRAME_EXT_DATA
|
||||
#define BSP_CAN_FRAME_STD_REMOTE BSP_FDCAN_FRAME_STD_REMOTE
|
||||
#define BSP_CAN_FRAME_EXT_REMOTE BSP_FDCAN_FRAME_EXT_REMOTE
|
||||
|
||||
/* 函数映射 */
|
||||
#define BSP_CAN_Init() BSP_FDCAN_Init()
|
||||
#define BSP_CAN_GetHandle(can) BSP_FDCAN_GetHandle(can)
|
||||
#define BSP_CAN_RegisterCallback(can, type, callback) \
|
||||
BSP_FDCAN_RegisterCallback(can, type, callback)
|
||||
#define BSP_CAN_Transmit(can, format, id, data, dlc) \
|
||||
BSP_FDCAN_Transmit(can, format, id, data, dlc)
|
||||
#define BSP_CAN_TransmitStdDataFrame(can, frame) \
|
||||
BSP_FDCAN_TransmitStdDataFrame(can, frame)
|
||||
#define BSP_CAN_TransmitExtDataFrame(can, frame) \
|
||||
BSP_FDCAN_TransmitExtDataFrame(can, frame)
|
||||
#define BSP_CAN_TransmitRemoteFrame(can, frame) \
|
||||
BSP_FDCAN_TransmitRemoteFrame(can, frame)
|
||||
#define BSP_CAN_RegisterId(can, can_id, queue_size) \
|
||||
BSP_FDCAN_RegisterId(can, can_id, queue_size)
|
||||
#define BSP_CAN_GetMessage(can, can_id, msg, timeout) \
|
||||
BSP_FDCAN_GetMessage(can, can_id, msg, timeout)
|
||||
#define BSP_CAN_GetQueueCount(can, can_id) \
|
||||
BSP_FDCAN_GetQueueCount(can, can_id)
|
||||
#define BSP_CAN_FlushQueue(can, can_id) \
|
||||
BSP_FDCAN_FlushQueue(can, can_id)
|
||||
#define BSP_CAN_RegisterIdParser(parser) \
|
||||
BSP_FDCAN_RegisterIdParser(parser)
|
||||
#define BSP_CAN_ParseId(original_id, frame_type) \
|
||||
BSP_FDCAN_ParseId(original_id, frame_type)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -26,10 +26,18 @@ void BSP_Flash_EraseSector(uint32_t sector) {
|
||||
flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
flash_erase.NbSectors = 1;
|
||||
#if defined(STM32H7)
|
||||
flash_erase.Banks = FLASH_BANK_1; // H7 requires Bank parameter
|
||||
#endif
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
#if defined(STM32H7)
|
||||
while (FLASH_WaitForLastOperation(50, FLASH_BANK_1) != HAL_OK)
|
||||
;
|
||||
#else
|
||||
while (FLASH_WaitForLastOperation(50) != HAL_OK)
|
||||
;
|
||||
#endif
|
||||
HAL_FLASHEx_Erase(&flash_erase, §or_error);
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
@ -39,6 +47,24 @@ void BSP_Flash_EraseSector(uint32_t sector) {
|
||||
|
||||
void BSP_Flash_WriteBytes(uint32_t address, const uint8_t *buf, size_t len) {
|
||||
HAL_FLASH_Unlock();
|
||||
#if defined(STM32H7)
|
||||
// H7 uses FLASHWORD (32 bytes) programming
|
||||
uint8_t flash_word[32] __attribute__((aligned(32)));
|
||||
while (len > 0) {
|
||||
size_t chunk = (len < 32) ? len : 32;
|
||||
memset(flash_word, 0xFF, 32);
|
||||
memcpy(flash_word, buf, chunk);
|
||||
|
||||
while (FLASH_WaitForLastOperation(50, FLASH_BANK_1) != HAL_OK)
|
||||
;
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address, (uint32_t)flash_word);
|
||||
|
||||
address += 32;
|
||||
buf += chunk;
|
||||
len -= chunk;
|
||||
}
|
||||
#else
|
||||
// F4/F7 use byte programming
|
||||
while (len > 0) {
|
||||
while (FLASH_WaitForLastOperation(50) != HAL_OK)
|
||||
;
|
||||
@ -47,6 +73,7 @@ void BSP_Flash_WriteBytes(uint32_t address, const uint8_t *buf, size_t len) {
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
#endif
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
|
||||
@ -5,4 +5,5 @@ error_detect,bsp/mm
|
||||
pid,component/filter
|
||||
filter,component/ahrs
|
||||
mixer,component/user_math.h
|
||||
ui,component/user_math.h
|
||||
ui,component/user_math.h
|
||||
kalman_filter,arm_math.h
|
||||
|
@ -11,4 +11,5 @@ limiter,限幅器
|
||||
mixer,混控器
|
||||
ui,用户交互
|
||||
user_math,用户自定义数学函数
|
||||
pid,PID控制器
|
||||
pid,PID控制器
|
||||
kalman_filter,卡尔曼滤波器
|
||||
|
591
component/kalman_filter/kalman_filter.c
Normal file
591
component/kalman_filter/kalman_filter.c
Normal file
@ -0,0 +1,591 @@
|
||||
/*
|
||||
卡尔曼滤波器 modified from wang hongxi
|
||||
支持动态量测调整,使用ARM CMSIS DSP优化矩阵运算
|
||||
|
||||
主要特性:
|
||||
- 基于量测有效性的 H、R、K 矩阵动态调整
|
||||
- 支持不同传感器采样频率
|
||||
- 矩阵 P 防过度收敛机制
|
||||
- ARM CMSIS DSP 优化的矩阵运算
|
||||
- 可扩展架构,支持用户自定义函数(EKF/UKF/ESKF)
|
||||
|
||||
使用说明:
|
||||
1. 矩阵初始化:P、F、Q 使用标准初始化方式
|
||||
H、R 在使用自动调整时需要配置量测映射
|
||||
|
||||
2. 自动调整模式 (use_auto_adjustment = 1):
|
||||
- 提供 measurement_map:每个量测对应的状态索引
|
||||
- 提供 measurement_degree:H 矩阵元素值
|
||||
- 提供 mat_r_diagonal_elements:量测噪声方差
|
||||
|
||||
3. 固定模式 (use_auto_adjustment = 0):
|
||||
- 像初始化 P 矩阵那样正常初始化 z、H、R
|
||||
|
||||
4. 量测更新:
|
||||
- 在传感器回调函数中更新 measured_vector
|
||||
- 值为 0 表示量测无效
|
||||
- 向量在每次 KF 更新后会被重置为 0
|
||||
|
||||
5. 防过度收敛:
|
||||
- 设置 state_min_variance 防止 P 矩阵过度收敛
|
||||
- 帮助滤波器适应缓慢变化的状态
|
||||
|
||||
使用示例:高度估计
|
||||
状态向量 x =
|
||||
| 高度 |
|
||||
| 速度 |
|
||||
| 加速度 |
|
||||
|
||||
KF_t Height_KF;
|
||||
|
||||
void INS_Task_Init(void)
|
||||
{
|
||||
// 初始协方差矩阵 P
|
||||
static float P_Init[9] =
|
||||
{
|
||||
10, 0, 0,
|
||||
0, 30, 0,
|
||||
0, 0, 10,
|
||||
};
|
||||
|
||||
// 状态转移矩阵 F(根据运动学模型)
|
||||
static float F_Init[9] =
|
||||
{
|
||||
1, dt, 0.5*dt*dt,
|
||||
0, 1, dt,
|
||||
0, 0, 1,
|
||||
};
|
||||
|
||||
// 过程噪声协方差矩阵 Q
|
||||
static float Q_Init[9] =
|
||||
{
|
||||
0.25*dt*dt*dt*dt, 0.5*dt*dt*dt, 0.5*dt*dt,
|
||||
0.5*dt*dt*dt, dt*dt, dt,
|
||||
0.5*dt*dt, dt, 1,
|
||||
};
|
||||
|
||||
// 设置状态最小方差(防止过度收敛)
|
||||
static float state_min_variance[3] = {0.03, 0.005, 0.1};
|
||||
|
||||
// 开启自动调整
|
||||
Height_KF.use_auto_adjustment = 1;
|
||||
|
||||
// 量测映射:[气压高度对应状态1, GPS高度对应状态1, 加速度计对应状态3]
|
||||
static uint8_t measurement_reference[3] = {1, 1, 3};
|
||||
|
||||
// 量测系数(H矩阵元素值)
|
||||
static float measurement_degree[3] = {1, 1, 1};
|
||||
// 根据 measurement_reference 与 measurement_degree 生成 H 矩阵如下
|
||||
// (在当前周期全部量测数据有效的情况下)
|
||||
// |1 0 0|
|
||||
// |1 0 0|
|
||||
// |0 0 1|
|
||||
|
||||
// 量测噪声方差(R矩阵对角元素)
|
||||
static float mat_r_diagonal_elements[3] = {30, 25, 35};
|
||||
// 根据 mat_r_diagonal_elements 生成 R 矩阵如下
|
||||
// (在当前周期全部量测数据有效的情况下)
|
||||
// |30 0 0|
|
||||
// | 0 25 0|
|
||||
// | 0 0 35|
|
||||
|
||||
// 初始化卡尔曼滤波器(状态维数3,控制维数0,量测维数3)
|
||||
KF_Init(&Height_KF, 3, 0, 3);
|
||||
|
||||
// 设置矩阵初值
|
||||
memcpy(Height_KF.P_data, P_Init, sizeof(P_Init));
|
||||
memcpy(Height_KF.F_data, F_Init, sizeof(F_Init));
|
||||
memcpy(Height_KF.Q_data, Q_Init, sizeof(Q_Init));
|
||||
memcpy(Height_KF.measurement_map, measurement_reference,
|
||||
sizeof(measurement_reference));
|
||||
memcpy(Height_KF.measurement_degree, measurement_degree,
|
||||
sizeof(measurement_degree));
|
||||
memcpy(Height_KF.mat_r_diagonal_elements, mat_r_diagonal_elements,
|
||||
sizeof(mat_r_diagonal_elements));
|
||||
memcpy(Height_KF.state_min_variance, state_min_variance,
|
||||
sizeof(state_min_variance));
|
||||
}
|
||||
|
||||
void INS_Task(void const *pvParameters)
|
||||
{
|
||||
// 循环更新卡尔曼滤波器
|
||||
KF_Update(&Height_KF);
|
||||
vTaskDelay(ts);
|
||||
}
|
||||
|
||||
// 传感器回调函数示例:在数据就绪时更新 measured_vector
|
||||
void Barometer_Read_Over(void)
|
||||
{
|
||||
......
|
||||
INS_KF.measured_vector[0] = baro_height; // 气压计高度
|
||||
}
|
||||
|
||||
void GPS_Read_Over(void)
|
||||
{
|
||||
......
|
||||
INS_KF.measured_vector[1] = GPS_height; // GPS高度
|
||||
}
|
||||
|
||||
void Acc_Data_Process(void)
|
||||
{
|
||||
......
|
||||
INS_KF.measured_vector[2] = acc.z; // Z轴加速度
|
||||
}
|
||||
*/
|
||||
|
||||
#include "kalman_filter.h"
|
||||
|
||||
/* USER INCLUDE BEGIN */
|
||||
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* USER DEFINE BEGIN */
|
||||
|
||||
/* USER DEFINE END */
|
||||
|
||||
/* 私有函数声明 */
|
||||
static void KF_AdjustHKR(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 初始化卡尔曼滤波器并分配矩阵内存
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @param xhat_size 状态向量维度
|
||||
* @param u_size 控制向量维度(无控制输入时设为0)
|
||||
* @param z_size 量测向量维度
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_Init(KF_t *kf, uint8_t xhat_size, uint8_t u_size, uint8_t z_size) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
kf->xhat_size = xhat_size;
|
||||
kf->u_size = u_size;
|
||||
kf->z_size = z_size;
|
||||
|
||||
kf->measurement_valid_num = 0;
|
||||
|
||||
/* 量测标志分配 */
|
||||
kf->measurement_map = (uint8_t *)user_malloc(sizeof(uint8_t) * z_size);
|
||||
memset(kf->measurement_map, 0, sizeof(uint8_t) * z_size);
|
||||
|
||||
kf->measurement_degree = (float *)user_malloc(sizeof(float) * z_size);
|
||||
memset(kf->measurement_degree, 0, sizeof(float) * z_size);
|
||||
|
||||
kf->mat_r_diagonal_elements = (float *)user_malloc(sizeof(float) * z_size);
|
||||
memset(kf->mat_r_diagonal_elements, 0, sizeof(float) * z_size);
|
||||
|
||||
kf->state_min_variance = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
memset(kf->state_min_variance, 0, sizeof(float) * xhat_size);
|
||||
|
||||
kf->temp = (uint8_t *)user_malloc(sizeof(uint8_t) * z_size);
|
||||
memset(kf->temp, 0, sizeof(uint8_t) * z_size);
|
||||
|
||||
/* 滤波数据分配 */
|
||||
kf->filtered_value = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
memset(kf->filtered_value, 0, sizeof(float) * xhat_size);
|
||||
|
||||
kf->measured_vector = (float *)user_malloc(sizeof(float) * z_size);
|
||||
memset(kf->measured_vector, 0, sizeof(float) * z_size);
|
||||
|
||||
kf->control_vector = (float *)user_malloc(sizeof(float) * u_size);
|
||||
memset(kf->control_vector, 0, sizeof(float) * u_size);
|
||||
|
||||
/* 状态估计 xhat x(k|k) */
|
||||
kf->xhat_data = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
memset(kf->xhat_data, 0, sizeof(float) * xhat_size);
|
||||
KF_MatInit(&kf->xhat, kf->xhat_size, 1, kf->xhat_data);
|
||||
|
||||
/* 先验状态估计 xhatminus x(k|k-1) */
|
||||
kf->xhatminus_data = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
memset(kf->xhatminus_data, 0, sizeof(float) * xhat_size);
|
||||
KF_MatInit(&kf->xhatminus, kf->xhat_size, 1, kf->xhatminus_data);
|
||||
|
||||
/* 控制向量 u */
|
||||
if (u_size != 0) {
|
||||
kf->u_data = (float *)user_malloc(sizeof(float) * u_size);
|
||||
memset(kf->u_data, 0, sizeof(float) * u_size);
|
||||
KF_MatInit(&kf->u, kf->u_size, 1, kf->u_data);
|
||||
}
|
||||
|
||||
/* 量测向量 z */
|
||||
kf->z_data = (float *)user_malloc(sizeof(float) * z_size);
|
||||
memset(kf->z_data, 0, sizeof(float) * z_size);
|
||||
KF_MatInit(&kf->z, kf->z_size, 1, kf->z_data);
|
||||
|
||||
/* 协方差矩阵 P(k|k) */
|
||||
kf->P_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
memset(kf->P_data, 0, sizeof(float) * xhat_size * xhat_size);
|
||||
KF_MatInit(&kf->P, kf->xhat_size, kf->xhat_size, kf->P_data);
|
||||
|
||||
/* 先验协方差矩阵 P(k|k-1) */
|
||||
kf->Pminus_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
memset(kf->Pminus_data, 0, sizeof(float) * xhat_size * xhat_size);
|
||||
KF_MatInit(&kf->Pminus, kf->xhat_size, kf->xhat_size, kf->Pminus_data);
|
||||
|
||||
/* 状态转移矩阵 F 及其转置 FT */
|
||||
kf->F_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
kf->FT_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
memset(kf->F_data, 0, sizeof(float) * xhat_size * xhat_size);
|
||||
memset(kf->FT_data, 0, sizeof(float) * xhat_size * xhat_size);
|
||||
KF_MatInit(&kf->F, kf->xhat_size, kf->xhat_size, kf->F_data);
|
||||
KF_MatInit(&kf->FT, kf->xhat_size, kf->xhat_size, kf->FT_data);
|
||||
|
||||
/* 控制矩阵 B */
|
||||
if (u_size != 0) {
|
||||
kf->B_data = (float *)user_malloc(sizeof(float) * xhat_size * u_size);
|
||||
memset(kf->B_data, 0, sizeof(float) * xhat_size * u_size);
|
||||
KF_MatInit(&kf->B, kf->xhat_size, kf->u_size, kf->B_data);
|
||||
}
|
||||
|
||||
/* 量测矩阵 H 及其转置 HT */
|
||||
kf->H_data = (float *)user_malloc(sizeof(float) * z_size * xhat_size);
|
||||
kf->HT_data = (float *)user_malloc(sizeof(float) * xhat_size * z_size);
|
||||
memset(kf->H_data, 0, sizeof(float) * z_size * xhat_size);
|
||||
memset(kf->HT_data, 0, sizeof(float) * xhat_size * z_size);
|
||||
KF_MatInit(&kf->H, kf->z_size, kf->xhat_size, kf->H_data);
|
||||
KF_MatInit(&kf->HT, kf->xhat_size, kf->z_size, kf->HT_data);
|
||||
|
||||
/* 过程噪声协方差矩阵 Q */
|
||||
kf->Q_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
memset(kf->Q_data, 0, sizeof(float) * xhat_size * xhat_size);
|
||||
KF_MatInit(&kf->Q, kf->xhat_size, kf->xhat_size, kf->Q_data);
|
||||
|
||||
/* 量测噪声协方差矩阵 R */
|
||||
kf->R_data = (float *)user_malloc(sizeof(float) * z_size * z_size);
|
||||
memset(kf->R_data, 0, sizeof(float) * z_size * z_size);
|
||||
KF_MatInit(&kf->R, kf->z_size, kf->z_size, kf->R_data);
|
||||
|
||||
/* 卡尔曼增益 K */
|
||||
kf->K_data = (float *)user_malloc(sizeof(float) * xhat_size * z_size);
|
||||
memset(kf->K_data, 0, sizeof(float) * xhat_size * z_size);
|
||||
KF_MatInit(&kf->K, kf->xhat_size, kf->z_size, kf->K_data);
|
||||
|
||||
/* 临时矩阵分配 */
|
||||
kf->S_data = (float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
kf->temp_matrix_data =
|
||||
(float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
kf->temp_matrix_data1 =
|
||||
(float *)user_malloc(sizeof(float) * xhat_size * xhat_size);
|
||||
kf->temp_vector_data = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
kf->temp_vector_data1 = (float *)user_malloc(sizeof(float) * xhat_size);
|
||||
|
||||
KF_MatInit(&kf->S, kf->xhat_size, kf->xhat_size, kf->S_data);
|
||||
KF_MatInit(&kf->temp_matrix, kf->xhat_size, kf->xhat_size,
|
||||
kf->temp_matrix_data);
|
||||
KF_MatInit(&kf->temp_matrix1, kf->xhat_size, kf->xhat_size,
|
||||
kf->temp_matrix_data1);
|
||||
KF_MatInit(&kf->temp_vector, kf->xhat_size, 1, kf->temp_vector_data);
|
||||
KF_MatInit(&kf->temp_vector1, kf->xhat_size, 1, kf->temp_vector_data1);
|
||||
|
||||
/* 初始化跳过标志 */
|
||||
kf->skip_eq1 = 0;
|
||||
kf->skip_eq2 = 0;
|
||||
kf->skip_eq3 = 0;
|
||||
kf->skip_eq4 = 0;
|
||||
kf->skip_eq5 = 0;
|
||||
|
||||
/* 初始化用户函数指针 */
|
||||
kf->User_Func0_f = NULL;
|
||||
kf->User_Func1_f = NULL;
|
||||
kf->User_Func2_f = NULL;
|
||||
kf->User_Func3_f = NULL;
|
||||
kf->User_Func4_f = NULL;
|
||||
kf->User_Func5_f = NULL;
|
||||
kf->User_Func6_f = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取量测并在启用自动调整时调整矩阵
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_Measure(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
/* 根据量测有效性自动调整 H, K, R 矩阵 */
|
||||
if (kf->use_auto_adjustment != 0) {
|
||||
KF_AdjustHKR(kf);
|
||||
} else {
|
||||
memcpy(kf->z_data, kf->measured_vector, sizeof(float) * kf->z_size);
|
||||
memset(kf->measured_vector, 0, sizeof(float) * kf->z_size);
|
||||
}
|
||||
|
||||
memcpy(kf->u_data, kf->control_vector, sizeof(float) * kf->u_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 步骤1:先验状态估计 - xhat'(k) = F·xhat(k-1) + B·u
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_PredictState(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
if (!kf->skip_eq1) {
|
||||
if (kf->u_size > 0) {
|
||||
/* 有控制输入: xhat'(k) = F·xhat(k-1) + B·u */
|
||||
kf->temp_vector.numRows = kf->xhat_size;
|
||||
kf->temp_vector.numCols = 1;
|
||||
kf->mat_status = KF_MatMult(&kf->F, &kf->xhat, &kf->temp_vector);
|
||||
|
||||
kf->temp_vector1.numRows = kf->xhat_size;
|
||||
kf->temp_vector1.numCols = 1;
|
||||
kf->mat_status = KF_MatMult(&kf->B, &kf->u, &kf->temp_vector1);
|
||||
kf->mat_status =
|
||||
KF_MatAdd(&kf->temp_vector, &kf->temp_vector1, &kf->xhatminus);
|
||||
} else {
|
||||
/* 无控制输入: xhat'(k) = F·xhat(k-1) */
|
||||
kf->mat_status = KF_MatMult(&kf->F, &kf->xhat, &kf->xhatminus);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 步骤2:先验协方差 - P'(k) = F·P(k-1)·F^T + Q
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_PredictCovariance(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
if (!kf->skip_eq2) {
|
||||
kf->mat_status = KF_MatTrans(&kf->F, &kf->FT);
|
||||
kf->mat_status = KF_MatMult(&kf->F, &kf->P, &kf->Pminus);
|
||||
kf->temp_matrix.numRows = kf->Pminus.numRows;
|
||||
kf->temp_matrix.numCols = kf->FT.numCols;
|
||||
/* F·P(k-1)·F^T */
|
||||
kf->mat_status = KF_MatMult(&kf->Pminus, &kf->FT, &kf->temp_matrix);
|
||||
kf->mat_status = KF_MatAdd(&kf->temp_matrix, &kf->Q, &kf->Pminus);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 步骤3:卡尔曼增益 - K = P'(k)·H^T / (H·P'(k)·H^T + R)
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_CalcGain(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
if (!kf->skip_eq3) {
|
||||
kf->mat_status = KF_MatTrans(&kf->H, &kf->HT);
|
||||
kf->temp_matrix.numRows = kf->H.numRows;
|
||||
kf->temp_matrix.numCols = kf->Pminus.numCols;
|
||||
/* H·P'(k) */
|
||||
kf->mat_status = KF_MatMult(&kf->H, &kf->Pminus, &kf->temp_matrix);
|
||||
kf->temp_matrix1.numRows = kf->temp_matrix.numRows;
|
||||
kf->temp_matrix1.numCols = kf->HT.numCols;
|
||||
/* H·P'(k)·H^T */
|
||||
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->HT, &kf->temp_matrix1);
|
||||
kf->S.numRows = kf->R.numRows;
|
||||
kf->S.numCols = kf->R.numCols;
|
||||
/* S = H·P'(k)·H^T + R */
|
||||
kf->mat_status = KF_MatAdd(&kf->temp_matrix1, &kf->R, &kf->S);
|
||||
/* S^-1 */
|
||||
kf->mat_status = KF_MatInv(&kf->S, &kf->temp_matrix1);
|
||||
kf->temp_matrix.numRows = kf->Pminus.numRows;
|
||||
kf->temp_matrix.numCols = kf->HT.numCols;
|
||||
/* P'(k)·H^T */
|
||||
kf->mat_status = KF_MatMult(&kf->Pminus, &kf->HT, &kf->temp_matrix);
|
||||
/* K = P'(k)·H^T·S^-1 */
|
||||
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->temp_matrix1, &kf->K);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 步骤4:状态更新 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k))
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_UpdateState(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
if (!kf->skip_eq4) {
|
||||
kf->temp_vector.numRows = kf->H.numRows;
|
||||
kf->temp_vector.numCols = 1;
|
||||
/* H·xhat'(k) */
|
||||
kf->mat_status = KF_MatMult(&kf->H, &kf->xhatminus, &kf->temp_vector);
|
||||
kf->temp_vector1.numRows = kf->z.numRows;
|
||||
kf->temp_vector1.numCols = 1;
|
||||
/* 新息: z - H·xhat'(k) */
|
||||
kf->mat_status = KF_MatSub(&kf->z, &kf->temp_vector, &kf->temp_vector1);
|
||||
kf->temp_vector.numRows = kf->K.numRows;
|
||||
kf->temp_vector.numCols = 1;
|
||||
/* K·新息 */
|
||||
kf->mat_status = KF_MatMult(&kf->K, &kf->temp_vector1, &kf->temp_vector);
|
||||
/* xhat = xhat' + K·新息 */
|
||||
kf->mat_status = KF_MatAdd(&kf->xhatminus, &kf->temp_vector, &kf->xhat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 步骤5:协方差更新 - P(k) = P'(k) - K·H·P'(k)
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_UpdateCovariance(KF_t *kf) {
|
||||
if (kf == NULL) return -1;
|
||||
|
||||
if (!kf->skip_eq5) {
|
||||
kf->temp_matrix.numRows = kf->K.numRows;
|
||||
kf->temp_matrix.numCols = kf->H.numCols;
|
||||
kf->temp_matrix1.numRows = kf->temp_matrix.numRows;
|
||||
kf->temp_matrix1.numCols = kf->Pminus.numCols;
|
||||
/* K·H */
|
||||
kf->mat_status = KF_MatMult(&kf->K, &kf->H, &kf->temp_matrix);
|
||||
/* K·H·P'(k) */
|
||||
kf->mat_status = KF_MatMult(&kf->temp_matrix, &kf->Pminus, &kf->temp_matrix1);
|
||||
/* P = P' - K·H·P' */
|
||||
kf->mat_status = KF_MatSub(&kf->Pminus, &kf->temp_matrix1, &kf->P);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行完整的卡尔曼滤波周期(五大方程)
|
||||
*
|
||||
* 实现标准KF,并支持用户自定义函数钩子用于扩展(EKF/UKF/ESKF/AUKF)。
|
||||
* 每个步骤都可以通过 User_Func 回调函数替换。
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return float* 滤波后的状态估计值指针
|
||||
*/
|
||||
float *KF_Update(KF_t *kf) {
|
||||
if (kf == NULL) return NULL;
|
||||
|
||||
/* 步骤0: 量测获取和矩阵调整 */
|
||||
KF_Measure(kf);
|
||||
if (kf->User_Func0_f != NULL) kf->User_Func0_f(kf);
|
||||
|
||||
/* 步骤1: 先验状态估计 - xhat'(k) = F·xhat(k-1) + B·u */
|
||||
KF_PredictState(kf);
|
||||
if (kf->User_Func1_f != NULL) kf->User_Func1_f(kf);
|
||||
|
||||
/* 步骤2: 先验协方差 - P'(k) = F·P(k-1)·F^T + Q */
|
||||
KF_PredictCovariance(kf);
|
||||
if (kf->User_Func2_f != NULL) kf->User_Func2_f(kf);
|
||||
|
||||
/* 量测更新(仅在存在有效量测时执行) */
|
||||
if (kf->measurement_valid_num != 0 || kf->use_auto_adjustment == 0) {
|
||||
/* 步骤3: 卡尔曼增益 - K = P'(k)·H^T / (H·P'(k)·H^T + R) */
|
||||
KF_CalcGain(kf);
|
||||
if (kf->User_Func3_f != NULL) kf->User_Func3_f(kf);
|
||||
|
||||
/* 步骤4: 状态更新 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k)) */
|
||||
KF_UpdateState(kf);
|
||||
if (kf->User_Func4_f != NULL) kf->User_Func4_f(kf);
|
||||
|
||||
/* 步骤5: 协方差更新 - P(k) = P'(k) - K·H·P'(k) */
|
||||
KF_UpdateCovariance(kf);
|
||||
} else {
|
||||
/* 无有效量测 - 仅预测 */
|
||||
memcpy(kf->xhat_data, kf->xhatminus_data, sizeof(float) * kf->xhat_size);
|
||||
memcpy(kf->P_data, kf->Pminus_data,
|
||||
sizeof(float) * kf->xhat_size * kf->xhat_size);
|
||||
}
|
||||
|
||||
/* 后处理钩子 */
|
||||
if (kf->User_Func5_f != NULL) kf->User_Func5_f(kf);
|
||||
|
||||
/* 防过度收敛:强制最小方差 */
|
||||
for (uint8_t i = 0; i < kf->xhat_size; i++) {
|
||||
if (kf->P_data[i * kf->xhat_size + i] < kf->state_min_variance[i])
|
||||
kf->P_data[i * kf->xhat_size + i] = kf->state_min_variance[i];
|
||||
}
|
||||
|
||||
/* 复制结果到输出 */
|
||||
memcpy(kf->filtered_value, kf->xhat_data, sizeof(float) * kf->xhat_size);
|
||||
|
||||
/* 附加后处理钩子 */
|
||||
if (kf->User_Func6_f != NULL) kf->User_Func6_f(kf);
|
||||
|
||||
return kf->filtered_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 重置卡尔曼滤波器状态
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
*/
|
||||
void KF_Reset(KF_t *kf) {
|
||||
if (kf == NULL) return;
|
||||
|
||||
memset(kf->xhat_data, 0, sizeof(float) * kf->xhat_size);
|
||||
memset(kf->xhatminus_data, 0, sizeof(float) * kf->xhat_size);
|
||||
memset(kf->filtered_value, 0, sizeof(float) * kf->xhat_size);
|
||||
kf->measurement_valid_num = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据量测有效性动态调整 H, R, K 矩阵
|
||||
*
|
||||
* 该函数根据当前周期中哪些量测有效(非零)来重建量测相关矩阵。
|
||||
* 支持具有不同采样率的异步传感器。
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
*/
|
||||
static void KF_AdjustHKR(KF_t *kf) {
|
||||
kf->measurement_valid_num = 0;
|
||||
|
||||
/* 复制并重置量测向量 */
|
||||
memcpy(kf->z_data, kf->measured_vector, sizeof(float) * kf->z_size);
|
||||
memset(kf->measured_vector, 0, sizeof(float) * kf->z_size);
|
||||
|
||||
/* 清空 H 和 R 矩阵 */
|
||||
memset(kf->R_data, 0, sizeof(float) * kf->z_size * kf->z_size);
|
||||
memset(kf->H_data, 0, sizeof(float) * kf->xhat_size * kf->z_size);
|
||||
|
||||
/* 识别有效量测并重建 z, H */
|
||||
for (uint8_t i = 0; i < kf->z_size; i++) {
|
||||
if (kf->z_data[i] != 0) { /* 非零表示有效量测 */
|
||||
/* 将有效量测压缩到 z */
|
||||
kf->z_data[kf->measurement_valid_num] = kf->z_data[i];
|
||||
kf->temp[kf->measurement_valid_num] = i;
|
||||
|
||||
/* 重建 H 矩阵行 */
|
||||
kf->H_data[kf->xhat_size * kf->measurement_valid_num +
|
||||
kf->measurement_map[i] - 1] = kf->measurement_degree[i];
|
||||
kf->measurement_valid_num++;
|
||||
}
|
||||
}
|
||||
|
||||
/* 用有效量测方差重建 R 矩阵 */
|
||||
for (uint8_t i = 0; i < kf->measurement_valid_num; i++) {
|
||||
kf->R_data[i * kf->measurement_valid_num + i] =
|
||||
kf->mat_r_diagonal_elements[kf->temp[i]];
|
||||
}
|
||||
|
||||
/* 调整矩阵维度以匹配有效量测数量 */
|
||||
kf->H.numRows = kf->measurement_valid_num;
|
||||
kf->H.numCols = kf->xhat_size;
|
||||
kf->HT.numRows = kf->xhat_size;
|
||||
kf->HT.numCols = kf->measurement_valid_num;
|
||||
kf->R.numRows = kf->measurement_valid_num;
|
||||
kf->R.numCols = kf->measurement_valid_num;
|
||||
kf->K.numRows = kf->xhat_size;
|
||||
kf->K.numCols = kf->measurement_valid_num;
|
||||
kf->z.numRows = kf->measurement_valid_num;
|
||||
}
|
||||
|
||||
/* USER FUNCTION BEGIN */
|
||||
|
||||
/* USER FUNCTION END */
|
||||
199
component/kalman_filter/kalman_filter.h
Normal file
199
component/kalman_filter/kalman_filter.h
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
卡尔曼滤波器
|
||||
支持动态量测调整,使用ARM CMSIS DSP优化矩阵运算
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* USER INCLUDE BEGIN */
|
||||
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* USER DEFINE BEGIN */
|
||||
|
||||
/* USER DEFINE END */
|
||||
|
||||
/* 内存分配配置 */
|
||||
#ifndef user_malloc
|
||||
#ifdef _CMSIS_OS_H
|
||||
#define user_malloc pvPortMalloc /* FreeRTOS堆分配 */
|
||||
#else
|
||||
#define user_malloc malloc /* 标准C库分配 */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ARM CMSIS DSP 矩阵运算别名 */
|
||||
#define KF_Mat arm_matrix_instance_f32
|
||||
#define KF_MatInit arm_mat_init_f32
|
||||
#define KF_MatAdd arm_mat_add_f32
|
||||
#define KF_MatSub arm_mat_sub_f32
|
||||
#define KF_MatMult arm_mat_mult_f32
|
||||
#define KF_MatTrans arm_mat_trans_f32
|
||||
#define KF_MatInv arm_mat_inverse_f32
|
||||
|
||||
/* 卡尔曼滤波器主结构体 */
|
||||
typedef struct KF_s {
|
||||
/* 输出和输入向量 */
|
||||
float *filtered_value; /* 滤波后的状态估计输出 */
|
||||
float *measured_vector; /* 量测输入向量 */
|
||||
float *control_vector; /* 控制输入向量 */
|
||||
|
||||
/* 维度 */
|
||||
uint8_t xhat_size; /* 状态向量维度 */
|
||||
uint8_t u_size; /* 控制向量维度 */
|
||||
uint8_t z_size; /* 量测向量维度 */
|
||||
|
||||
/* 自动调整参数 */
|
||||
uint8_t use_auto_adjustment; /* 启用动态 H/R/K 调整 */
|
||||
uint8_t measurement_valid_num; /* 有效量测数量 */
|
||||
|
||||
/* 量测配置 */
|
||||
uint8_t *measurement_map; /* 量测到状态的映射 */
|
||||
float *measurement_degree; /* 每个量测的H矩阵元素值 */
|
||||
float *mat_r_diagonal_elements; /* 量测噪声方差(R对角线) */
|
||||
float *state_min_variance; /* 最小状态方差(防过度收敛) */
|
||||
uint8_t *temp; /* 临时缓冲区 */
|
||||
|
||||
/* 方程跳过标志(用于自定义用户函数) */
|
||||
uint8_t skip_eq1, skip_eq2, skip_eq3, skip_eq4, skip_eq5;
|
||||
|
||||
/* 卡尔曼滤波器矩阵 */
|
||||
KF_Mat xhat; /* 状态估计 x(k|k) */
|
||||
KF_Mat xhatminus; /* 先验状态估计 x(k|k-1) */
|
||||
KF_Mat u; /* 控制向量 */
|
||||
KF_Mat z; /* 量测向量 */
|
||||
KF_Mat P; /* 后验误差协方差 P(k|k) */
|
||||
KF_Mat Pminus; /* 先验误差协方差 P(k|k-1) */
|
||||
KF_Mat F, FT; /* 状态转移矩阵及其转置 */
|
||||
KF_Mat B; /* 控制矩阵 */
|
||||
KF_Mat H, HT; /* 量测矩阵及其转置 */
|
||||
KF_Mat Q; /* 过程噪声协方差 */
|
||||
KF_Mat R; /* 量测噪声协方差 */
|
||||
KF_Mat K; /* 卡尔曼增益 */
|
||||
KF_Mat S; /* 临时矩阵 S */
|
||||
KF_Mat temp_matrix, temp_matrix1; /* 临时矩阵 */
|
||||
KF_Mat temp_vector, temp_vector1; /* 临时向量 */
|
||||
|
||||
int8_t mat_status; /* 矩阵运算状态 */
|
||||
|
||||
/* 用户自定义函数指针(用于EKF/UKF/ESKF扩展) */
|
||||
void (*User_Func0_f)(struct KF_s *kf); /* 自定义量测处理 */
|
||||
void (*User_Func1_f)(struct KF_s *kf); /* 自定义状态预测 */
|
||||
void (*User_Func2_f)(struct KF_s *kf); /* 自定义协方差预测 */
|
||||
void (*User_Func3_f)(struct KF_s *kf); /* 自定义卡尔曼增益计算 */
|
||||
void (*User_Func4_f)(struct KF_s *kf); /* 自定义状态更新 */
|
||||
void (*User_Func5_f)(struct KF_s *kf); /* 自定义后处理 */
|
||||
void (*User_Func6_f)(struct KF_s *kf); /* 附加自定义函数 */
|
||||
|
||||
/* 矩阵数据存储指针 */
|
||||
float *xhat_data, *xhatminus_data;
|
||||
float *u_data;
|
||||
float *z_data;
|
||||
float *P_data, *Pminus_data;
|
||||
float *F_data, *FT_data;
|
||||
float *B_data;
|
||||
float *H_data, *HT_data;
|
||||
float *Q_data;
|
||||
float *R_data;
|
||||
float *K_data;
|
||||
float *S_data;
|
||||
float *temp_matrix_data, *temp_matrix_data1;
|
||||
float *temp_vector_data, *temp_vector_data1;
|
||||
} KF_t;
|
||||
|
||||
/* USER STRUCT BEGIN */
|
||||
|
||||
/* USER STRUCT END */
|
||||
|
||||
/**
|
||||
* @brief 初始化卡尔曼滤波器并分配矩阵内存
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @param xhat_size 状态向量维度
|
||||
* @param u_size 控制向量维度(无控制输入时设为0)
|
||||
* @param z_size 量测向量维度
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_Init(KF_t *kf, uint8_t xhat_size, uint8_t u_size, uint8_t z_size);
|
||||
|
||||
/**
|
||||
* @brief 获取量测并在启用自动调整时调整矩阵
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_Measure(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 步骤1:先验状态估计 - xhat'(k) = F·xhat(k-1) + B·u
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_PredictState(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 步骤2:先验协方差 - P'(k) = F·P(k-1)·F^T + Q
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_PredictCovariance(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 步骤3:卡尔曼增益 - K = P'(k)·H^T / (H·P'(k)·H^T + R)
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_CalcGain(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 步骤4:状态更新 - xhat(k) = xhat'(k) + K·(z - H·xhat'(k))
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_UpdateState(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 步骤5:协方差更新 - P(k) = P'(k) - K·H·P'(k)
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return int8_t 0对应没有错误
|
||||
*/
|
||||
int8_t KF_UpdateCovariance(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 执行完整的卡尔曼滤波周期(五大方程)
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
* @return float* 滤波后的状态估计值指针
|
||||
*/
|
||||
float *KF_Update(KF_t *kf);
|
||||
|
||||
/**
|
||||
* @brief 重置卡尔曼滤波器状态
|
||||
*
|
||||
* @param kf 卡尔曼滤波器结构体指针
|
||||
*/
|
||||
void KF_Reset(KF_t *kf);
|
||||
|
||||
/* USER FUNCTION BEGIN */
|
||||
|
||||
/* USER FUNCTION END */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -1,4 +1,4 @@
|
||||
bsp,can,fdcan,dwt,gpio,i2c,mm,spi,uart,pwm,time,flash
|
||||
component,ahrs,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
|
||||
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver
|
||||
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid,lcd_driver,mrobot
|
||||
module,
|
||||
|
@ -259,4 +259,19 @@ devices:
|
||||
thread_signals: []
|
||||
files:
|
||||
header: "lcd.h"
|
||||
source: "lcd.c"
|
||||
source: "lcd.c"
|
||||
|
||||
mrobot:
|
||||
name: "MRobot CLI"
|
||||
description: "基于 FreeRTOS CLI 的嵌入式调试命令行系统,支持设备注册与监控、类 Unix 文件系统命令、htop 风格任务监控等"
|
||||
dependencies:
|
||||
bsp: ["uart", "mm"]
|
||||
component: ["freertos_cli"]
|
||||
bsp_requirements:
|
||||
- type: "uart"
|
||||
var_name: "BSP_UART_MROBOT"
|
||||
description: "用于 MRobot CLI 命令行交互"
|
||||
thread_signals: []
|
||||
files:
|
||||
header: "mrobot.h"
|
||||
source: "mrobot.c"
|
||||
874
device/mrobot/mrobot.c
Normal file
874
device/mrobot/mrobot.c
Normal file
@ -0,0 +1,874 @@
|
||||
/**
|
||||
* @file mrobot.c
|
||||
* @brief MRobot CLI 实现
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "device/mrobot.h"
|
||||
#include "component/freertos_cli.h"
|
||||
#include "bsp/uart.h"
|
||||
#include "bsp/mm.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <semphr.h>
|
||||
#include <cmsis_os2.h>
|
||||
|
||||
/* Private constants -------------------------------------------------------- */
|
||||
static const char *const CLI_WELCOME_MESSAGE =
|
||||
"\r\n"
|
||||
" __ __ _____ _ _ \r\n"
|
||||
" | \\/ | __ \\ | | | | \r\n"
|
||||
" | \\ / | |__) |___ | |__ ___ | |_ \r\n"
|
||||
" | |\\/| | _ // _ \\| '_ \\ / _ \\| __|\r\n"
|
||||
" | | | | | \\ \\ (_) | |_) | (_) | |_ \r\n"
|
||||
" |_| |_|_| \\_\\___/|_.__/ \\___/ \\__|\r\n"
|
||||
" ------------------------------------\r\n"
|
||||
" Welcome to use MRobot CLI. Type 'help' to view a list of registered commands.\r\n"
|
||||
"\r\n";
|
||||
|
||||
/* ANSI 转义序列 */
|
||||
#define ANSI_CLEAR_SCREEN "\033[2J\033[H"
|
||||
#define ANSI_CURSOR_HOME "\033[H"
|
||||
#define ANSI_BACKSPACE "\b \b"
|
||||
|
||||
/* Private types ------------------------------------------------------------ */
|
||||
/* CLI 上下文结构体 - 封装所有状态 */
|
||||
typedef struct {
|
||||
/* 设备管理 */
|
||||
MRobot_Device_t devices[MROBOT_MAX_DEVICES];
|
||||
uint8_t device_count;
|
||||
|
||||
/* 自定义命令 */
|
||||
CLI_Command_Definition_t *custom_cmds[MROBOT_MAX_CUSTOM_COMMANDS];
|
||||
uint8_t custom_cmd_count;
|
||||
|
||||
/* CLI 状态 */
|
||||
MRobot_State_t state;
|
||||
char current_path[MROBOT_PATH_MAX_LEN];
|
||||
|
||||
/* 命令缓冲区 */
|
||||
uint8_t cmd_buffer[MROBOT_CMD_BUFFER_SIZE];
|
||||
volatile uint8_t cmd_index;
|
||||
volatile bool cmd_ready;
|
||||
|
||||
/* UART 相关 */
|
||||
uint8_t uart_rx_char;
|
||||
volatile bool tx_complete;
|
||||
volatile bool htop_exit;
|
||||
|
||||
/* 输出缓冲区 */
|
||||
char output_buffer[MROBOT_OUTPUT_BUFFER_SIZE];
|
||||
|
||||
/* 初始化标志 */
|
||||
bool initialized;
|
||||
|
||||
/* 互斥锁 */
|
||||
SemaphoreHandle_t mutex;
|
||||
} MRobot_Context_t;
|
||||
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static MRobot_Context_t ctx = {
|
||||
.device_count = 0,
|
||||
.custom_cmd_count = 0,
|
||||
.state = MROBOT_STATE_IDLE,
|
||||
.current_path = "/",
|
||||
.cmd_index = 0,
|
||||
.cmd_ready = false,
|
||||
.tx_complete = true,
|
||||
.htop_exit = false,
|
||||
.initialized = false,
|
||||
.mutex = NULL
|
||||
};
|
||||
|
||||
/* Private function prototypes ---------------------------------------------- */
|
||||
/* 命令处理函数 */
|
||||
static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
|
||||
/* 内部辅助函数 */
|
||||
static void uart_tx_callback(void);
|
||||
static void uart_rx_callback(void);
|
||||
static void send_string(const char *str);
|
||||
static void send_prompt(void);
|
||||
static int format_float_va(char *buf, size_t size, const char *fmt, va_list args);
|
||||
|
||||
/* CLI 命令定义表 */
|
||||
static const CLI_Command_Definition_t builtin_commands[] = {
|
||||
{ "help", " --help: 显示所有可用命令\r\n", cmd_help, 0 },
|
||||
{ "htop", " --htop: 动态显示 FreeRTOS 任务状态 (按 'q' 退出)\r\n", cmd_htop, 0 },
|
||||
{ "cd", " --cd <path>: 切换目录\r\n", cmd_cd, 1 },
|
||||
{ "ls", " --ls: 列出当前目录内容\r\n", cmd_ls, 0 },
|
||||
{ "show", " --show [device] [count]: 显示设备信息\r\n", cmd_show, -1 },
|
||||
};
|
||||
#define BUILTIN_CMD_COUNT (sizeof(builtin_commands) / sizeof(builtin_commands[0]))
|
||||
|
||||
/* ========================================================================== */
|
||||
/* 辅助函数实现 */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief 发送字符串到 UART(阻塞等待完成)
|
||||
*/
|
||||
static void send_string(const char *str) {
|
||||
if (str == NULL || *str == '\0') return;
|
||||
|
||||
ctx.tx_complete = false;
|
||||
BSP_UART_Transmit(MROBOT_UART_PORT, (uint8_t *)str, strlen(str), true);
|
||||
while (!ctx.tx_complete) { osDelay(1); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送命令提示符
|
||||
*/
|
||||
static void send_prompt(void) {
|
||||
char prompt[MROBOT_PATH_MAX_LEN + 32];
|
||||
snprintf(prompt, sizeof(prompt), MROBOT_USER_NAME "@" MROBOT_HOST_NAME ":%s$ ", ctx.current_path);
|
||||
send_string(prompt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART 发送完成回调
|
||||
*/
|
||||
static void uart_tx_callback(void) {
|
||||
ctx.tx_complete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART 接收回调
|
||||
*/
|
||||
static void uart_rx_callback(void) {
|
||||
uint8_t ch = ctx.uart_rx_char;
|
||||
|
||||
/* htop 模式下检查退出键 */
|
||||
if (ctx.state == MROBOT_STATE_HTOP) {
|
||||
if (ch == 'q' || ch == 'Q' || ch == 27) {
|
||||
ctx.htop_exit = true;
|
||||
}
|
||||
BSP_UART_Receive(MROBOT_UART_PORT, &ctx.uart_rx_char, 1, false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 正常命令输入处理 */
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
if (ctx.cmd_index > 0) {
|
||||
ctx.cmd_buffer[ctx.cmd_index] = '\0';
|
||||
ctx.cmd_ready = true;
|
||||
BSP_UART_Transmit(MROBOT_UART_PORT, (uint8_t *)"\r\n", 2, false);
|
||||
}
|
||||
} else if (ch == 127 || ch == 8) { /* 退格键 */
|
||||
if (ctx.cmd_index > 0) {
|
||||
ctx.cmd_index--;
|
||||
BSP_UART_Transmit(MROBOT_UART_PORT, (uint8_t *)ANSI_BACKSPACE, 3, false);
|
||||
}
|
||||
} else if (ch >= 32 && ch < 127 && ctx.cmd_index < sizeof(ctx.cmd_buffer) - 1) {
|
||||
ctx.cmd_buffer[ctx.cmd_index++] = ch;
|
||||
BSP_UART_Transmit(MROBOT_UART_PORT, &ch, 1, false);
|
||||
}
|
||||
|
||||
BSP_UART_Receive(MROBOT_UART_PORT, &ctx.uart_rx_char, 1, false);
|
||||
}
|
||||
|
||||
/* ========================================================================== */
|
||||
/* CLI 命令实现 */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief help 命令 - 显示帮助信息
|
||||
*/
|
||||
static BaseType_t cmd_help(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
|
||||
(void)pcCommandString;
|
||||
|
||||
int offset = snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"MRobot CLI v2.0\r\n"
|
||||
"================\r\n"
|
||||
"Built-in Commands:\r\n");
|
||||
|
||||
for (size_t i = 0; i < BUILTIN_CMD_COUNT && offset < (int)xWriteBufferLen - 50; i++) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" %s", builtin_commands[i].pcHelpString);
|
||||
}
|
||||
|
||||
if (ctx.custom_cmd_count > 0) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
"\r\nCustom Commands:\r\n");
|
||||
for (uint8_t i = 0; i < ctx.custom_cmd_count && offset < (int)xWriteBufferLen - 50; i++) {
|
||||
if (ctx.custom_cmds[i] != NULL) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" %s", ctx.custom_cmds[i]->pcHelpString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief htop 命令 - 设置 htop 模式标志
|
||||
*/
|
||||
static BaseType_t cmd_htop(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
|
||||
(void)pcCommandString;
|
||||
(void)pcWriteBuffer;
|
||||
(void)xWriteBufferLen;
|
||||
/* htop 模式在 MRobot_Run 中处理 */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief cd 命令 - 切换目录
|
||||
*/
|
||||
static BaseType_t cmd_cd(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
|
||||
const char *param;
|
||||
BaseType_t param_len;
|
||||
|
||||
param = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶m_len);
|
||||
|
||||
if (param == NULL) {
|
||||
/* 无参数时切换到根目录 */
|
||||
strcpy(ctx.current_path, "/");
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen, "Changed to: %s\r\n", ctx.current_path);
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
/* 安全复制路径参数 */
|
||||
char path[MROBOT_PATH_MAX_LEN];
|
||||
size_t copy_len = (size_t)param_len < sizeof(path) - 1 ? (size_t)param_len : sizeof(path) - 1;
|
||||
strncpy(path, param, copy_len);
|
||||
path[copy_len] = '\0';
|
||||
|
||||
/* 路径解析 */
|
||||
if (strcmp(path, "/") == 0 || strcmp(path, "..") == 0 || strcmp(path, "~") == 0) {
|
||||
strcpy(ctx.current_path, "/");
|
||||
} else if (strcmp(path, "dev") == 0 || strcmp(path, "/dev") == 0) {
|
||||
strcpy(ctx.current_path, "/dev");
|
||||
} else if (strcmp(path, "modules") == 0 || strcmp(path, "/modules") == 0) {
|
||||
strcpy(ctx.current_path, "/modules");
|
||||
} else {
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen, "Error: Directory '%s' not found\r\n", path);
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen, "Changed to: %s\r\n", ctx.current_path);
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ls 命令 - 列出目录内容
|
||||
*/
|
||||
static BaseType_t cmd_ls(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
|
||||
(void)pcCommandString;
|
||||
int offset = 0;
|
||||
|
||||
if (strcmp(ctx.current_path, "/") == 0) {
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"dev/\r\n"
|
||||
"modules/\r\n");
|
||||
} else if (strcmp(ctx.current_path, "/dev") == 0) {
|
||||
offset = snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"Device List (%d devices)\r\n\r\n",
|
||||
ctx.device_count);
|
||||
|
||||
if (ctx.device_count == 0) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" (No devices)\r\n");
|
||||
} else {
|
||||
/* 直接列出所有设备 */
|
||||
for (uint8_t i = 0; i < ctx.device_count && offset < (int)xWriteBufferLen - 50; i++) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" - %s\r\n", ctx.devices[i].name);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(ctx.current_path, "/modules") == 0) {
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"Module functions not yet implemented\r\n");
|
||||
}
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief show 命令 - 显示设备信息
|
||||
*/
|
||||
static BaseType_t cmd_show(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) {
|
||||
const char *param;
|
||||
const char *count_param;
|
||||
BaseType_t param_len, count_param_len;
|
||||
|
||||
/* 使用局部静态变量跟踪多次打印状态 */
|
||||
static uint32_t print_count = 0;
|
||||
static uint32_t current_iter = 0;
|
||||
static char target_device[MROBOT_DEVICE_NAME_LEN] = {0};
|
||||
|
||||
/* 首次调用时解析参数 */
|
||||
if (current_iter == 0) {
|
||||
/* 检查是否在 /dev 目录 */
|
||||
if (strcmp(ctx.current_path, "/dev") != 0) {
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"Error: 'show' command only works in /dev directory\r\n"
|
||||
"Hint: Use 'cd /dev' to switch to device directory\r\n");
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
param = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶m_len);
|
||||
count_param = FreeRTOS_CLIGetParameter(pcCommandString, 2, &count_param_len);
|
||||
|
||||
/* 解析打印次数 */
|
||||
print_count = 1;
|
||||
if (count_param != NULL) {
|
||||
char count_str[16];
|
||||
size_t copy_len = (size_t)count_param_len < sizeof(count_str) - 1 ?
|
||||
(size_t)count_param_len : sizeof(count_str) - 1;
|
||||
strncpy(count_str, count_param, copy_len);
|
||||
count_str[copy_len] = '\0';
|
||||
int parsed = atoi(count_str);
|
||||
if (parsed > 0 && parsed <= 1000) {
|
||||
print_count = (uint32_t)parsed;
|
||||
}
|
||||
}
|
||||
|
||||
/* 保存目标设备名称 */
|
||||
if (param != NULL) {
|
||||
size_t copy_len = (size_t)param_len < sizeof(target_device) - 1 ?
|
||||
(size_t)param_len : sizeof(target_device) - 1;
|
||||
strncpy(target_device, param, copy_len);
|
||||
target_device[copy_len] = '\0';
|
||||
} else {
|
||||
target_device[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
/* 连续打印模式:清屏 */
|
||||
if (print_count > 1) {
|
||||
offset = snprintf(pcWriteBuffer, xWriteBufferLen, "%s[%lu/%lu]\r\n",
|
||||
ANSI_CLEAR_SCREEN,
|
||||
(unsigned long)(current_iter + 1),
|
||||
(unsigned long)print_count);
|
||||
}
|
||||
|
||||
if (target_device[0] == '\0') {
|
||||
/* 显示所有设备 */
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
"=== All Devices ===\r\n\r\n");
|
||||
|
||||
for (uint8_t i = 0; i < ctx.device_count && offset < (int)xWriteBufferLen - 100; i++) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
"--- %s ---\r\n", ctx.devices[i].name);
|
||||
|
||||
if (ctx.devices[i].print_cb != NULL) {
|
||||
int written = ctx.devices[i].print_cb(ctx.devices[i].data,
|
||||
pcWriteBuffer + offset,
|
||||
xWriteBufferLen - offset);
|
||||
offset += (written > 0) ? written : 0;
|
||||
} else {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" (No print function)\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.device_count == 0) {
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" (No devices registered)\r\n");
|
||||
}
|
||||
} else {
|
||||
/* 显示指定设备 */
|
||||
const MRobot_Device_t *dev = MRobot_FindDevice(target_device);
|
||||
|
||||
if (dev == NULL) {
|
||||
snprintf(pcWriteBuffer, xWriteBufferLen,
|
||||
"Error: Device '%s' not found\r\n",
|
||||
target_device);
|
||||
current_iter = 0;
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
offset += snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
"=== %s ===\r\n", dev->name);
|
||||
|
||||
if (dev->print_cb != NULL) {
|
||||
dev->print_cb(dev->data, pcWriteBuffer + offset, xWriteBufferLen - offset);
|
||||
} else {
|
||||
snprintf(pcWriteBuffer + offset, xWriteBufferLen - offset,
|
||||
" (No print function)\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* 判断是否继续打印 */
|
||||
current_iter++;
|
||||
if (current_iter < print_count) {
|
||||
osDelay(MROBOT_HTOP_REFRESH_MS);
|
||||
return pdTRUE;
|
||||
} else {
|
||||
current_iter = 0;
|
||||
return pdFALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* htop 模式处理
|
||||
* ========================================================================== */
|
||||
static void handle_htop_mode(void) {
|
||||
send_string(ANSI_CLEAR_SCREEN);
|
||||
send_string("=== MRobot Task Monitor (Press 'q' to exit) ===\r\n\r\n");
|
||||
|
||||
/* 获取任务列表 */
|
||||
char task_buffer[1024];
|
||||
char display_line[128];
|
||||
|
||||
vTaskList(task_buffer);
|
||||
|
||||
/* 表头 */
|
||||
send_string("Task Name State Prio Stack Num\r\n");
|
||||
send_string("------------------------------------------------\r\n");
|
||||
|
||||
/* 解析并格式化任务列表 */
|
||||
char *line = strtok(task_buffer, "\r\n");
|
||||
while (line != NULL) {
|
||||
char name[17] = {0};
|
||||
char state_char = '?';
|
||||
int prio = 0, stack = 0, num = 0;
|
||||
|
||||
if (sscanf(line, "%16s %c %d %d %d", name, &state_char, &prio, &stack, &num) == 5) {
|
||||
const char *state_str;
|
||||
switch (state_char) {
|
||||
case 'R': state_str = "Running"; break;
|
||||
case 'B': state_str = "Blocked"; break;
|
||||
case 'S': state_str = "Suspend"; break;
|
||||
case 'D': state_str = "Deleted"; break;
|
||||
case 'X': state_str = "Ready "; break;
|
||||
default: state_str = "Unknown"; break;
|
||||
}
|
||||
|
||||
snprintf(display_line, sizeof(display_line),
|
||||
"%-16s %-8s %-4d %-8d %-4d\r\n",
|
||||
name, state_str, prio, stack, num);
|
||||
send_string(display_line);
|
||||
}
|
||||
line = strtok(NULL, "\r\n");
|
||||
}
|
||||
|
||||
/* 显示系统信息 */
|
||||
snprintf(display_line, sizeof(display_line),
|
||||
"------------------------------------------------\r\n"
|
||||
"System Tick: %lu | Free Heap: %lu bytes\r\n",
|
||||
(unsigned long)xTaskGetTickCount(),
|
||||
(unsigned long)xPortGetFreeHeapSize());
|
||||
send_string(display_line);
|
||||
|
||||
/* 检查退出 */
|
||||
if (ctx.htop_exit) {
|
||||
ctx.state = MROBOT_STATE_IDLE;
|
||||
ctx.htop_exit = false;
|
||||
send_string(ANSI_CLEAR_SCREEN);
|
||||
send_prompt();
|
||||
}
|
||||
|
||||
osDelay(MROBOT_HTOP_REFRESH_MS);
|
||||
}
|
||||
|
||||
/* ========================================================================== */
|
||||
/* 公共 API 实现 */
|
||||
/* ========================================================================== */
|
||||
|
||||
void MRobot_Init(void) {
|
||||
if (ctx.initialized) return;
|
||||
|
||||
/* 创建互斥锁 */
|
||||
ctx.mutex = xSemaphoreCreateMutex();
|
||||
|
||||
/* 初始化状态 */
|
||||
memset(ctx.devices, 0, sizeof(ctx.devices));
|
||||
ctx.device_count = 0;
|
||||
ctx.custom_cmd_count = 0;
|
||||
ctx.state = MROBOT_STATE_IDLE;
|
||||
strcpy(ctx.current_path, "/");
|
||||
ctx.cmd_index = 0;
|
||||
ctx.cmd_ready = false;
|
||||
ctx.tx_complete = true;
|
||||
ctx.htop_exit = false;
|
||||
|
||||
/* 注册内置命令 */
|
||||
for (size_t i = 0; i < BUILTIN_CMD_COUNT; i++) {
|
||||
FreeRTOS_CLIRegisterCommand(&builtin_commands[i]);
|
||||
}
|
||||
|
||||
/* 注册 UART 回调 */
|
||||
BSP_UART_RegisterCallback(MROBOT_UART_PORT, BSP_UART_RX_CPLT_CB, uart_rx_callback);
|
||||
BSP_UART_RegisterCallback(MROBOT_UART_PORT, BSP_UART_TX_CPLT_CB, uart_tx_callback);
|
||||
|
||||
/* 启动 UART 接收 */
|
||||
BSP_UART_Receive(MROBOT_UART_PORT, &ctx.uart_rx_char, 1, false);
|
||||
|
||||
/* 等待用户按下回车 */
|
||||
while (ctx.uart_rx_char != '\r' && ctx.uart_rx_char != '\n') {
|
||||
osDelay(10);
|
||||
}
|
||||
|
||||
/* 发送欢迎消息和提示符 */
|
||||
send_string(CLI_WELCOME_MESSAGE);
|
||||
send_prompt();
|
||||
|
||||
ctx.initialized = true;
|
||||
}
|
||||
|
||||
void MRobot_DeInit(void) {
|
||||
if (!ctx.initialized) return;
|
||||
|
||||
/* 释放自定义命令内存 */
|
||||
for (uint8_t i = 0; i < ctx.custom_cmd_count; i++) {
|
||||
if (ctx.custom_cmds[i] != NULL) {
|
||||
BSP_Free(ctx.custom_cmds[i]);
|
||||
ctx.custom_cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* 删除互斥锁 */
|
||||
if (ctx.mutex != NULL) {
|
||||
vSemaphoreDelete(ctx.mutex);
|
||||
ctx.mutex = NULL;
|
||||
}
|
||||
|
||||
ctx.initialized = false;
|
||||
}
|
||||
|
||||
MRobot_State_t MRobot_GetState(void) {
|
||||
return ctx.state;
|
||||
}
|
||||
|
||||
MRobot_Error_t MRobot_RegisterDevice(const char *name, void *data, MRobot_PrintCallback_t print_cb) {
|
||||
if (name == NULL || data == NULL) {
|
||||
return MROBOT_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
if (ctx.device_count >= MROBOT_MAX_DEVICES) {
|
||||
return MROBOT_ERR_FULL;
|
||||
}
|
||||
|
||||
/* 检查重名 */
|
||||
for (uint8_t i = 0; i < ctx.device_count; i++) {
|
||||
if (strcmp(ctx.devices[i].name, name) == 0) {
|
||||
return MROBOT_ERR_INVALID_ARG; /* 设备名已存在 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 线程安全写入 */
|
||||
if (ctx.mutex != NULL) {
|
||||
xSemaphoreTake(ctx.mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
strncpy(ctx.devices[ctx.device_count].name, name, MROBOT_DEVICE_NAME_LEN - 1);
|
||||
ctx.devices[ctx.device_count].name[MROBOT_DEVICE_NAME_LEN - 1] = '\0';
|
||||
ctx.devices[ctx.device_count].data = data;
|
||||
ctx.devices[ctx.device_count].print_cb = print_cb;
|
||||
ctx.device_count++;
|
||||
|
||||
if (ctx.mutex != NULL) {
|
||||
xSemaphoreGive(ctx.mutex);
|
||||
}
|
||||
|
||||
return MROBOT_OK;
|
||||
}
|
||||
|
||||
MRobot_Error_t MRobot_UnregisterDevice(const char *name) {
|
||||
if (name == NULL) {
|
||||
return MROBOT_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
if (ctx.mutex != NULL) {
|
||||
xSemaphoreTake(ctx.mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < ctx.device_count; i++) {
|
||||
if (strcmp(ctx.devices[i].name, name) == 0) {
|
||||
/* 移动后续设备 */
|
||||
for (uint8_t j = i; j < ctx.device_count - 1; j++) {
|
||||
ctx.devices[j] = ctx.devices[j + 1];
|
||||
}
|
||||
ctx.device_count--;
|
||||
|
||||
if (ctx.mutex != NULL) {
|
||||
xSemaphoreGive(ctx.mutex);
|
||||
}
|
||||
return MROBOT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.mutex != NULL) {
|
||||
xSemaphoreGive(ctx.mutex);
|
||||
}
|
||||
return MROBOT_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
MRobot_Error_t MRobot_RegisterCommand(const char *command, const char *help_text,
|
||||
MRobot_CommandCallback_t callback, int8_t param_count) {
|
||||
if (command == NULL || help_text == NULL || callback == NULL) {
|
||||
return MROBOT_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
if (ctx.custom_cmd_count >= MROBOT_MAX_CUSTOM_COMMANDS) {
|
||||
return MROBOT_ERR_FULL;
|
||||
}
|
||||
|
||||
/* 动态分配命令结构体 */
|
||||
CLI_Command_Definition_t *cmd_def = BSP_Malloc(sizeof(CLI_Command_Definition_t));
|
||||
if (cmd_def == NULL) {
|
||||
return MROBOT_ERR_ALLOC;
|
||||
}
|
||||
|
||||
/* 初始化命令定义 */
|
||||
*(const char **)&cmd_def->pcCommand = command;
|
||||
*(const char **)&cmd_def->pcHelpString = help_text;
|
||||
*(pdCOMMAND_LINE_CALLBACK *)&cmd_def->pxCommandInterpreter = (pdCOMMAND_LINE_CALLBACK)callback;
|
||||
cmd_def->cExpectedNumberOfParameters = param_count;
|
||||
|
||||
/* 注册到 FreeRTOS CLI */
|
||||
FreeRTOS_CLIRegisterCommand(cmd_def);
|
||||
|
||||
ctx.custom_cmds[ctx.custom_cmd_count] = cmd_def;
|
||||
ctx.custom_cmd_count++;
|
||||
|
||||
return MROBOT_OK;
|
||||
}
|
||||
|
||||
uint8_t MRobot_GetDeviceCount(void) {
|
||||
return ctx.device_count;
|
||||
}
|
||||
|
||||
const MRobot_Device_t *MRobot_FindDevice(const char *name) {
|
||||
if (name == NULL) return NULL;
|
||||
|
||||
for (uint8_t i = 0; i < ctx.device_count; i++) {
|
||||
if (strcmp(ctx.devices[i].name, name) == 0) {
|
||||
return &ctx.devices[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int MRobot_Printf(const char *fmt, ...) {
|
||||
if (fmt == NULL || !ctx.initialized) return -1;
|
||||
|
||||
char buffer[MROBOT_OUTPUT_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = format_float_va(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (len > 0) {
|
||||
send_string(buffer);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 内部函数:格式化浮点数到缓冲区(va_list 版本)
|
||||
*/
|
||||
static int format_float_va(char *buf, size_t size, const char *fmt, va_list args) {
|
||||
if (buf == NULL || size == 0 || fmt == NULL) return 0;
|
||||
|
||||
char *buf_ptr = buf;
|
||||
size_t buf_remain = size - 1;
|
||||
|
||||
const char *p = fmt;
|
||||
while (*p && buf_remain > 0) {
|
||||
if (*p != '%') {
|
||||
*buf_ptr++ = *p++;
|
||||
buf_remain--;
|
||||
continue;
|
||||
}
|
||||
|
||||
p++; /* 跳过 '%' */
|
||||
|
||||
/* 处理 %% */
|
||||
if (*p == '%') {
|
||||
*buf_ptr++ = '%';
|
||||
buf_remain--;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 解析精度 %.Nf */
|
||||
int precision = 2; /* 默认精度 */
|
||||
if (*p == '.') {
|
||||
p++;
|
||||
precision = 0;
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
precision = precision * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
if (precision > 6) precision = 6;
|
||||
}
|
||||
|
||||
int written = 0;
|
||||
switch (*p) {
|
||||
case 'f': { /* 浮点数 */
|
||||
double val = va_arg(args, double);
|
||||
written = MRobot_FormatFloat(buf_ptr, buf_remain, (float)val, precision);
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'i': {
|
||||
int val = va_arg(args, int);
|
||||
written = snprintf(buf_ptr, buf_remain, "%d", val);
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
unsigned int val = va_arg(args, unsigned int);
|
||||
written = snprintf(buf_ptr, buf_remain, "%u", val);
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
unsigned int val = va_arg(args, unsigned int);
|
||||
written = snprintf(buf_ptr, buf_remain, "%x", val);
|
||||
break;
|
||||
}
|
||||
case 'X': {
|
||||
unsigned int val = va_arg(args, unsigned int);
|
||||
written = snprintf(buf_ptr, buf_remain, "%X", val);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
const char *str = va_arg(args, const char *);
|
||||
if (str == NULL) str = "(null)";
|
||||
written = snprintf(buf_ptr, buf_remain, "%s", str);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
int ch = va_arg(args, int);
|
||||
*buf_ptr = (char)ch;
|
||||
written = 1;
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
p++;
|
||||
if (*p == 'd' || *p == 'i') {
|
||||
long val = va_arg(args, long);
|
||||
written = snprintf(buf_ptr, buf_remain, "%ld", val);
|
||||
} else if (*p == 'u') {
|
||||
unsigned long val = va_arg(args, unsigned long);
|
||||
written = snprintf(buf_ptr, buf_remain, "%lu", val);
|
||||
} else if (*p == 'x' || *p == 'X') {
|
||||
unsigned long val = va_arg(args, unsigned long);
|
||||
written = snprintf(buf_ptr, buf_remain, *p == 'x' ? "%lx" : "%lX", val);
|
||||
} else {
|
||||
p--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*buf_ptr++ = '%';
|
||||
buf_remain--;
|
||||
if (buf_remain > 0) {
|
||||
*buf_ptr++ = *p;
|
||||
buf_remain--;
|
||||
}
|
||||
written = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (written > 0) {
|
||||
buf_ptr += written;
|
||||
buf_remain -= (size_t)written;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
*buf_ptr = '\0';
|
||||
return (int)(buf_ptr - buf);
|
||||
}
|
||||
|
||||
int MRobot_Snprintf(char *buf, size_t size, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = format_float_va(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int MRobot_FormatFloat(char *buf, size_t size, float val, int precision) {
|
||||
if (buf == NULL || size == 0) return 0;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
/* 处理负数 */
|
||||
if (val < 0) {
|
||||
if (offset < (int)size - 1) buf[offset++] = '-';
|
||||
val = -val;
|
||||
}
|
||||
|
||||
/* 限制精度范围 */
|
||||
if (precision < 0) precision = 0;
|
||||
if (precision > 6) precision = 6;
|
||||
|
||||
/* 计算乘数 */
|
||||
int multiplier = 1;
|
||||
for (int i = 0; i < precision; i++) multiplier *= 10;
|
||||
|
||||
int int_part = (int)val;
|
||||
int frac_part = (int)((val - int_part) * multiplier + 0.5f);
|
||||
|
||||
/* 处理进位 */
|
||||
if (frac_part >= multiplier) {
|
||||
int_part++;
|
||||
frac_part -= multiplier;
|
||||
}
|
||||
|
||||
/* 格式化输出 */
|
||||
int written;
|
||||
if (precision > 0) {
|
||||
written = snprintf(buf + offset, size - offset, "%d.%0*d", int_part, precision, frac_part);
|
||||
} else {
|
||||
written = snprintf(buf + offset, size - offset, "%d", int_part);
|
||||
}
|
||||
return (written > 0) ? (offset + written) : offset;
|
||||
}
|
||||
|
||||
void MRobot_Run(void) {
|
||||
if (!ctx.initialized) return;
|
||||
|
||||
/* htop 模式 */
|
||||
if (ctx.state == MROBOT_STATE_HTOP) {
|
||||
handle_htop_mode();
|
||||
return;
|
||||
}
|
||||
|
||||
/* 处理命令 */
|
||||
if (ctx.cmd_ready) {
|
||||
ctx.state = MROBOT_STATE_PROCESSING;
|
||||
|
||||
/* 检查是否是 htop 命令 */
|
||||
if (strcmp((char *)ctx.cmd_buffer, "htop") == 0) {
|
||||
ctx.state = MROBOT_STATE_HTOP;
|
||||
ctx.htop_exit = false;
|
||||
} else {
|
||||
/* 处理其他命令 */
|
||||
BaseType_t more;
|
||||
do {
|
||||
ctx.output_buffer[0] = '\0';
|
||||
more = FreeRTOS_CLIProcessCommand((char *)ctx.cmd_buffer,
|
||||
ctx.output_buffer,
|
||||
sizeof(ctx.output_buffer));
|
||||
|
||||
if (ctx.output_buffer[0] != '\0') {
|
||||
send_string(ctx.output_buffer);
|
||||
}
|
||||
} while (more != pdFALSE);
|
||||
|
||||
send_prompt();
|
||||
ctx.state = MROBOT_STATE_IDLE;
|
||||
}
|
||||
|
||||
ctx.cmd_index = 0;
|
||||
ctx.cmd_ready = false;
|
||||
}
|
||||
|
||||
osDelay(10);
|
||||
}
|
||||
317
device/mrobot/mrobot.h
Normal file
317
device/mrobot/mrobot.h
Normal file
@ -0,0 +1,317 @@
|
||||
/**
|
||||
* @file mrobot.h
|
||||
* @brief MRobot CLI - 基于 FreeRTOS CLI 的嵌入式调试命令行系统
|
||||
*
|
||||
* 功能特性:
|
||||
* - 设备注册与监控(IMU、电机、传感器等)
|
||||
* - 类 Unix 文件系统命令(cd, ls, pwd)
|
||||
* - htop 风格的任务监控
|
||||
* - 自定义命令扩展
|
||||
* - 线程安全设计
|
||||
*
|
||||
* @example IMU 设备注册示例
|
||||
* @code
|
||||
* // 1. 定义 IMU 数据结构
|
||||
* typedef struct {
|
||||
* bool online;
|
||||
* float accl[3];
|
||||
* float gyro[3];
|
||||
* float euler[3]; // roll, pitch, yaw (deg)
|
||||
* float temp;
|
||||
* } MyIMU_t;
|
||||
*
|
||||
* MyIMU_t my_imu;
|
||||
*
|
||||
* // 2. 实现打印回调
|
||||
* static int print_imu(const void *data, char *buf, size_t size) {
|
||||
* const MyIMU_t *imu = (const MyIMU_t *)data;
|
||||
* return MRobot_Snprintf(buf, size,
|
||||
* " Status: %s\r\n"
|
||||
* " Accel : X=%.3f Y=%.3f Z=%.3f\r\n"
|
||||
* " Euler : R=%.2f P=%.2f Y=%.2f\r\n"
|
||||
* " Temp : %.1f C\r\n",
|
||||
* imu->online ? "Online" : "Offline",
|
||||
* imu->accl[0], imu->accl[1], imu->accl[2],
|
||||
* imu->euler[0], imu->euler[1], imu->euler[2],
|
||||
* imu->temp);
|
||||
* }
|
||||
*
|
||||
* // 3. 注册设备
|
||||
* MRobot_RegisterDevice("imu", &my_imu, print_imu);
|
||||
* @endcode
|
||||
*
|
||||
* @example 电机设备注册示例
|
||||
* @code
|
||||
* typedef struct {
|
||||
* bool online;
|
||||
* float angle; // deg
|
||||
* float speed; // RPM
|
||||
* float current; // A
|
||||
* } MyMotor_t;
|
||||
*
|
||||
* MyMotor_t motor[4];
|
||||
*
|
||||
* static int print_motor(const void *data, char *buf, size_t size) {
|
||||
* const MyMotor_t *m = (const MyMotor_t *)data;
|
||||
* return MRobot_Snprintf(buf, size,
|
||||
* " Status : %s\r\n"
|
||||
* " Angle : %.2f deg\r\n"
|
||||
* " Speed : %.1f RPM\r\n"
|
||||
* " Current: %.3f A\r\n",
|
||||
* m->online ? "Online" : "Offline",
|
||||
* m->angle, m->speed, m->current);
|
||||
* }
|
||||
*
|
||||
* // 注册 4 个电机
|
||||
* MRobot_RegisterDevice("motor0", &motor[0], print_motor);
|
||||
* MRobot_RegisterDevice("motor1", &motor[1], print_motor);
|
||||
* MRobot_RegisterDevice("motor2", &motor[2], print_motor);
|
||||
* MRobot_RegisterDevice("motor3", &motor[3], print_motor);
|
||||
* @endcode
|
||||
*
|
||||
* @example 自定义校准命令示例
|
||||
* @code
|
||||
* // 校准数据
|
||||
* static float gyro_offset[3] = {0};
|
||||
*
|
||||
* // 命令回调: cali gyro / cali accel / cali save
|
||||
* static long cmd_cali(char *buf, size_t size, const char *cmd) {
|
||||
* const char *param = FreeRTOS_CLIGetParameter(cmd, 1, NULL);
|
||||
*
|
||||
* if (param == NULL) {
|
||||
* return MRobot_Snprintf(buf, size, "Usage: cali <gyro|accel|save>\r\n");
|
||||
* }
|
||||
* if (strncmp(param, "gyro", 4) == 0) {
|
||||
* // 采集 1000 次陀螺仪数据求平均
|
||||
* MRobot_Snprintf(buf, size, "Calibrating gyro... keep IMU still!\r\n");
|
||||
* // ... 校准逻辑 ...
|
||||
* return 0;
|
||||
* }
|
||||
* if (strncmp(param, "save", 4) == 0) {
|
||||
* // 保存到 Flash
|
||||
* MRobot_Snprintf(buf, size, "Calibration saved to flash.\r\n");
|
||||
* return 0;
|
||||
* }
|
||||
* return MRobot_Snprintf(buf, size, "Unknown: %s\r\n", param);
|
||||
* }
|
||||
*
|
||||
* // 注册命令
|
||||
* MRobot_RegisterCommand("cali", "cali <gyro|accel|save>: IMU calibration\r\n", cmd_cali, -1);
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "bsp/uart.h"
|
||||
|
||||
/* Configuration ------------------------------------------------------------ */
|
||||
/* 可在编译时通过 -D 选项覆盖这些默认值 */
|
||||
|
||||
#ifndef MROBOT_MAX_DEVICES
|
||||
#define MROBOT_MAX_DEVICES 64 /* 最大设备数 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_MAX_CUSTOM_COMMANDS
|
||||
#define MROBOT_MAX_CUSTOM_COMMANDS 16 /* 最大自定义命令数 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_CMD_BUFFER_SIZE
|
||||
#define MROBOT_CMD_BUFFER_SIZE 128 /* 命令缓冲区大小 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_OUTPUT_BUFFER_SIZE
|
||||
#define MROBOT_OUTPUT_BUFFER_SIZE 512 /* 输出缓冲区大小 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_DEVICE_NAME_LEN
|
||||
#define MROBOT_DEVICE_NAME_LEN 32 /* 设备名最大长度 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_PATH_MAX_LEN
|
||||
#define MROBOT_PATH_MAX_LEN 64 /* 路径最大长度 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_HTOP_REFRESH_MS
|
||||
#define MROBOT_HTOP_REFRESH_MS 200 /* htop 刷新间隔 (ms) */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_UART_PORT
|
||||
#define MROBOT_UART_PORT BSP_UART_VOFA /* 默认 UART 端口 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_USER_NAME
|
||||
#define MROBOT_USER_NAME "root" /* CLI 用户名 */
|
||||
#endif
|
||||
|
||||
#ifndef MROBOT_HOST_NAME
|
||||
#define MROBOT_HOST_NAME "MRobot" /* CLI 主机名 */
|
||||
#endif
|
||||
|
||||
/* Error codes -------------------------------------------------------------- */
|
||||
typedef enum {
|
||||
MROBOT_OK = 0, /* 成功 */
|
||||
MROBOT_ERR_FULL = -1, /* 容量已满 */
|
||||
MROBOT_ERR_NULL_PTR = -2, /* 空指针 */
|
||||
MROBOT_ERR_INVALID_ARG = -3, /* 无效参数 */
|
||||
MROBOT_ERR_NOT_FOUND = -4, /* 未找到 */
|
||||
MROBOT_ERR_ALLOC = -5, /* 内存分配失败 */
|
||||
MROBOT_ERR_BUSY = -6, /* 设备忙 */
|
||||
MROBOT_ERR_NOT_INIT = -7, /* 未初始化 */
|
||||
} MRobot_Error_t;
|
||||
|
||||
/* CLI 运行状态 */
|
||||
typedef enum {
|
||||
MROBOT_STATE_IDLE, /* 空闲状态,等待输入 */
|
||||
MROBOT_STATE_HTOP, /* htop 模式 */
|
||||
MROBOT_STATE_PROCESSING, /* 正在处理命令 */
|
||||
} MRobot_State_t;
|
||||
|
||||
/* Callback types ----------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 设备打印回调函数类型
|
||||
* @param device_data 用户注册时传入的设备数据指针
|
||||
* @param buffer 输出缓冲区
|
||||
* @param buffer_size 缓冲区大小
|
||||
* @return 实际写入的字节数
|
||||
* @note 用户需要自行实现此函数来格式化设备数据
|
||||
*/
|
||||
typedef int (*MRobot_PrintCallback_t)(const void *device_data, char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief 命令处理回调函数类型(与 FreeRTOS CLI 兼容)
|
||||
*/
|
||||
typedef long (*MRobot_CommandCallback_t)(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
|
||||
|
||||
/* Device structure --------------------------------------------------------- */
|
||||
typedef struct {
|
||||
char name[MROBOT_DEVICE_NAME_LEN]; /* 设备名称 */
|
||||
void *data; /* 用户设备数据指针 */
|
||||
MRobot_PrintCallback_t print_cb; /* 用户打印回调函数 */
|
||||
} MRobot_Device_t;
|
||||
|
||||
/* Public API --------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 初始化 MRobot CLI 系统
|
||||
* @note 必须在 FreeRTOS 调度器启动后调用
|
||||
*/
|
||||
void MRobot_Init(void);
|
||||
|
||||
/**
|
||||
* @brief 反初始化 MRobot CLI 系统,释放资源
|
||||
*/
|
||||
void MRobot_DeInit(void);
|
||||
|
||||
/**
|
||||
* @brief 获取当前 CLI 状态
|
||||
* @return MRobot_State_t 当前状态
|
||||
*/
|
||||
MRobot_State_t MRobot_GetState(void);
|
||||
|
||||
/**
|
||||
* @brief 注册设备到 MRobot 系统
|
||||
* @param name 设备名称(会被截断到 MROBOT_DEVICE_NAME_LEN-1)
|
||||
* @param data 设备数据指针(不能为 NULL)
|
||||
* @param print_cb 打印回调函数(可为 NULL,但无法用 show 命令查看)
|
||||
* @return MRobot_Error_t 错误码
|
||||
*/
|
||||
MRobot_Error_t MRobot_RegisterDevice(const char *name, void *data, MRobot_PrintCallback_t print_cb);
|
||||
|
||||
/**
|
||||
* @brief 注销设备
|
||||
* @param name 设备名称
|
||||
* @return MRobot_Error_t 错误码
|
||||
*/
|
||||
MRobot_Error_t MRobot_UnregisterDevice(const char *name);
|
||||
|
||||
/**
|
||||
* @brief 注册自定义命令
|
||||
* @param command 命令名称
|
||||
* @param help_text 帮助文本
|
||||
* @param callback 命令回调函数
|
||||
* @param param_count 参数个数(-1 表示可变参数)
|
||||
* @return MRobot_Error_t 错误码
|
||||
*/
|
||||
MRobot_Error_t MRobot_RegisterCommand(const char *command, const char *help_text,
|
||||
MRobot_CommandCallback_t callback, int8_t param_count);
|
||||
|
||||
/**
|
||||
* @brief 获取已注册设备数量
|
||||
* @return 设备数量
|
||||
*/
|
||||
uint8_t MRobot_GetDeviceCount(void);
|
||||
|
||||
/**
|
||||
* @brief 根据名称查找设备
|
||||
* @param name 设备名称
|
||||
* @return 设备指针,未找到返回 NULL
|
||||
*/
|
||||
const MRobot_Device_t *MRobot_FindDevice(const char *name);
|
||||
|
||||
/**
|
||||
* @brief MRobot 主循环,在 CLI 任务中周期性调用
|
||||
* @note 建议调用周期 10ms
|
||||
*/
|
||||
void MRobot_Run(void);
|
||||
|
||||
/**
|
||||
* @brief 格式化输出到 CLI 终端(线程安全,支持浮点数)
|
||||
* @param fmt 格式字符串
|
||||
* @param ... 可变参数
|
||||
* @return 实际输出的字符数,失败返回负数
|
||||
*
|
||||
* @note 支持的格式说明符:
|
||||
* - %d, %i, %u, %x, %X, %ld, %lu, %lx : 整数
|
||||
* - %s, %c : 字符串/字符
|
||||
* - %f : 浮点数 (默认2位小数)
|
||||
* - %.Nf : 浮点数 (N位小数, N=0-6)
|
||||
* - %% : 百分号
|
||||
*
|
||||
* @example
|
||||
* MRobot_Printf("Euler: R=%.2f P=%.2f Y=%.2f\\r\\n", roll, pitch, yaw);
|
||||
*/
|
||||
int MRobot_Printf(const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief 格式化到缓冲区(用于回调函数,支持浮点数)
|
||||
* @note 格式说明符同 MRobot_Printf
|
||||
*
|
||||
* @example
|
||||
* static int print_imu(const void *data, char *buf, size_t size) {
|
||||
* const BMI088_t *imu = (const BMI088_t *)data;
|
||||
* return MRobot_Snprintf(buf, size,
|
||||
* " Accel: X=%.3f Y=%.3f Z=%.3f\\r\\n",
|
||||
* imu->accl.x, imu->accl.y, imu->accl.z);
|
||||
* }
|
||||
*/
|
||||
int MRobot_Snprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
|
||||
/* Utility functions -------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 格式化浮点数为字符串(嵌入式环境不支持 %f)
|
||||
* @param buf 输出缓冲区
|
||||
* @param size 缓冲区大小
|
||||
* @param val 要格式化的浮点数
|
||||
* @param precision 小数位数 (0-6)
|
||||
* @return 写入的字符数
|
||||
*
|
||||
* @example
|
||||
* char buf[16];
|
||||
* MRobot_FormatFloat(buf, sizeof(buf), 3.14159f, 2); // "3.14"
|
||||
* MRobot_FormatFloat(buf, sizeof(buf), -0.001f, 4); // "-0.0010"
|
||||
*/
|
||||
int MRobot_FormatFloat(char *buf, size_t size, float val, int precision);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
700
ioc/CtrBoard-H7_ALL.ioc
Normal file
700
ioc/CtrBoard-H7_ALL.ioc
Normal file
@ -0,0 +1,700 @@
|
||||
#MicroXplorer Configuration settings - do not modify
|
||||
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_4
|
||||
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_19
|
||||
ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV64
|
||||
ADC1.ContinuousConvMode=ENABLE
|
||||
ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR
|
||||
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,OffsetSignedSaturation-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ClockPrescaler,ContinuousConvMode,ConversionDataManagement,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,OffsetSignedSaturation-1\#ChannelRegularConversion,NbrOfConversion
|
||||
ADC1.NbrOfConversion=2
|
||||
ADC1.NbrOfConversionFlag=1
|
||||
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
|
||||
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
|
||||
ADC1.OffsetSignedSaturation-0\#ChannelRegularConversion=DISABLE
|
||||
ADC1.OffsetSignedSaturation-1\#ChannelRegularConversion=DISABLE
|
||||
ADC1.Rank-0\#ChannelRegularConversion=1
|
||||
ADC1.Rank-1\#ChannelRegularConversion=2
|
||||
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
|
||||
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
|
||||
ADC1.master=1
|
||||
CAD.formats=
|
||||
CAD.pinconfig=
|
||||
CAD.provider=
|
||||
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings=0x24000000
|
||||
CORTEX_M7.CPU_DCache=Disabled
|
||||
CORTEX_M7.CPU_ICache=Disabled
|
||||
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
|
||||
CORTEX_M7.IPParameters=CPU_DCache,CPU_ICache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings
|
||||
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_BUFFERABLE
|
||||
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_CACHEABLE
|
||||
CORTEX_M7.MPU_Control=__NULL
|
||||
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_512B
|
||||
CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_TEX_LEVEL1
|
||||
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.ADC1.0.EventEnable=DISABLE
|
||||
Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.ADC1.0.Instance=DMA1_Stream0
|
||||
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
|
||||
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
|
||||
Dma.ADC1.0.Mode=DMA_CIRCULAR
|
||||
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
|
||||
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
|
||||
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
|
||||
Dma.ADC1.0.RequestNumber=1
|
||||
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
|
||||
Dma.ADC1.0.SignalID=NONE
|
||||
Dma.ADC1.0.SyncEnable=DISABLE
|
||||
Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
|
||||
Dma.ADC1.0.SyncRequestNumber=1
|
||||
Dma.ADC1.0.SyncSignalID=NONE
|
||||
Dma.Request0=ADC1
|
||||
Dma.Request1=SPI2_RX
|
||||
Dma.Request2=SPI2_TX
|
||||
Dma.Request3=UART5_RX
|
||||
Dma.RequestsNb=4
|
||||
Dma.SPI2_RX.1.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.SPI2_RX.1.EventEnable=DISABLE
|
||||
Dma.SPI2_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.SPI2_RX.1.Instance=DMA1_Stream1
|
||||
Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.SPI2_RX.1.MemInc=DMA_MINC_ENABLE
|
||||
Dma.SPI2_RX.1.Mode=DMA_NORMAL
|
||||
Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.SPI2_RX.1.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SPI2_RX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
|
||||
Dma.SPI2_RX.1.Priority=DMA_PRIORITY_LOW
|
||||
Dma.SPI2_RX.1.RequestNumber=1
|
||||
Dma.SPI2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
|
||||
Dma.SPI2_RX.1.SignalID=NONE
|
||||
Dma.SPI2_RX.1.SyncEnable=DISABLE
|
||||
Dma.SPI2_RX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
|
||||
Dma.SPI2_RX.1.SyncRequestNumber=1
|
||||
Dma.SPI2_RX.1.SyncSignalID=NONE
|
||||
Dma.SPI2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.SPI2_TX.2.EventEnable=DISABLE
|
||||
Dma.SPI2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.SPI2_TX.2.Instance=DMA1_Stream2
|
||||
Dma.SPI2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.SPI2_TX.2.MemInc=DMA_MINC_ENABLE
|
||||
Dma.SPI2_TX.2.Mode=DMA_NORMAL
|
||||
Dma.SPI2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.SPI2_TX.2.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SPI2_TX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
|
||||
Dma.SPI2_TX.2.Priority=DMA_PRIORITY_LOW
|
||||
Dma.SPI2_TX.2.RequestNumber=1
|
||||
Dma.SPI2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
|
||||
Dma.SPI2_TX.2.SignalID=NONE
|
||||
Dma.SPI2_TX.2.SyncEnable=DISABLE
|
||||
Dma.SPI2_TX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
|
||||
Dma.SPI2_TX.2.SyncRequestNumber=1
|
||||
Dma.SPI2_TX.2.SyncSignalID=NONE
|
||||
Dma.UART5_RX.3.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.UART5_RX.3.EventEnable=DISABLE
|
||||
Dma.UART5_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.UART5_RX.3.Instance=DMA1_Stream3
|
||||
Dma.UART5_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.UART5_RX.3.MemInc=DMA_MINC_ENABLE
|
||||
Dma.UART5_RX.3.Mode=DMA_NORMAL
|
||||
Dma.UART5_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.UART5_RX.3.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.UART5_RX.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING
|
||||
Dma.UART5_RX.3.Priority=DMA_PRIORITY_LOW
|
||||
Dma.UART5_RX.3.RequestNumber=1
|
||||
Dma.UART5_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
|
||||
Dma.UART5_RX.3.SignalID=NONE
|
||||
Dma.UART5_RX.3.SyncEnable=DISABLE
|
||||
Dma.UART5_RX.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
|
||||
Dma.UART5_RX.3.SyncRequestNumber=1
|
||||
Dma.UART5_RX.3.SyncSignalID=NONE
|
||||
FDCAN1.AutoRetransmission=ENABLE
|
||||
FDCAN1.CalculateBaudRateNominal=1000000
|
||||
FDCAN1.CalculateTimeBitNominal=1000
|
||||
FDCAN1.CalculateTimeQuantumNominal=200.0
|
||||
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission
|
||||
FDCAN1.NominalPrescaler=24
|
||||
FDCAN1.NominalTimeSeg1=3
|
||||
FDCAN1.RxFifo0ElmtsNbr=32
|
||||
FDCAN1.StdFiltersNbr=1
|
||||
FDCAN1.TxFifoQueueElmtsNbr=32
|
||||
FDCAN2.AutoRetransmission=ENABLE
|
||||
FDCAN2.CalculateBaudRateNominal=1000000
|
||||
FDCAN2.CalculateTimeBitNominal=1000
|
||||
FDCAN2.CalculateTimeQuantumNominal=200.0
|
||||
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission,RxFifo1ElmtsNbr
|
||||
FDCAN2.MessageRAMOffset=0x406
|
||||
FDCAN2.NominalPrescaler=24
|
||||
FDCAN2.NominalTimeSeg1=3
|
||||
FDCAN2.RxFifo0ElmtsNbr=32
|
||||
FDCAN2.RxFifo1ElmtsNbr=32
|
||||
FDCAN2.StdFiltersNbr=1
|
||||
FDCAN2.TxFifoQueueElmtsNbr=32
|
||||
FDCAN3.AutoRetransmission=ENABLE
|
||||
FDCAN3.CalculateBaudRateNominal=1000000
|
||||
FDCAN3.CalculateTimeBitNominal=1000
|
||||
FDCAN3.CalculateTimeQuantumNominal=200.0
|
||||
FDCAN3.ExtFiltersNbr=1
|
||||
FDCAN3.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,AutoRetransmission,RxFifo1ElmtsNbr,ExtFiltersNbr
|
||||
FDCAN3.MessageRAMOffset=0x812
|
||||
FDCAN3.NominalPrescaler=24
|
||||
FDCAN3.NominalTimeSeg1=3
|
||||
FDCAN3.RxFifo0ElmtsNbr=32
|
||||
FDCAN3.RxFifo1ElmtsNbr=32
|
||||
FDCAN3.StdFiltersNbr=1
|
||||
FDCAN3.TxFifoQueueElmtsNbr=32
|
||||
FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE
|
||||
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
|
||||
FREERTOS.configTOTAL_HEAP_SIZE=0x10000
|
||||
File.Version=6
|
||||
GPIO.groupedBy=Group By Peripherals
|
||||
KeepUserPlacement=false
|
||||
MMTAppRegionsCount=0
|
||||
MMTConfigApplied=false
|
||||
Mcu.CPN=STM32H723VGT6
|
||||
Mcu.Family=STM32H7
|
||||
Mcu.IP0=ADC1
|
||||
Mcu.IP1=CORTEX_M7
|
||||
Mcu.IP10=OCTOSPI1
|
||||
Mcu.IP11=RCC
|
||||
Mcu.IP12=SPI1
|
||||
Mcu.IP13=SPI2
|
||||
Mcu.IP14=SYS
|
||||
Mcu.IP15=TIM1
|
||||
Mcu.IP16=TIM2
|
||||
Mcu.IP17=TIM3
|
||||
Mcu.IP18=TIM12
|
||||
Mcu.IP19=UART5
|
||||
Mcu.IP2=DEBUG
|
||||
Mcu.IP20=UART7
|
||||
Mcu.IP21=USART1
|
||||
Mcu.IP22=USART2
|
||||
Mcu.IP23=USART3
|
||||
Mcu.IP24=USART10
|
||||
Mcu.IP25=USB_OTG_HS
|
||||
Mcu.IP3=DMA
|
||||
Mcu.IP4=FDCAN1
|
||||
Mcu.IP5=FDCAN2
|
||||
Mcu.IP6=FDCAN3
|
||||
Mcu.IP7=FREERTOS
|
||||
Mcu.IP8=MEMORYMAP
|
||||
Mcu.IP9=NVIC
|
||||
Mcu.IPNb=26
|
||||
Mcu.Name=STM32H723VGTx
|
||||
Mcu.Package=LQFP100
|
||||
Mcu.Pin0=PE2
|
||||
Mcu.Pin1=PE3
|
||||
Mcu.Pin10=PC3_C
|
||||
Mcu.Pin11=PA0
|
||||
Mcu.Pin12=PA1
|
||||
Mcu.Pin13=PA2
|
||||
Mcu.Pin14=PA3
|
||||
Mcu.Pin15=PA5
|
||||
Mcu.Pin16=PA7
|
||||
Mcu.Pin17=PC4
|
||||
Mcu.Pin18=PC5
|
||||
Mcu.Pin19=PB0
|
||||
Mcu.Pin2=PC13
|
||||
Mcu.Pin20=PB1
|
||||
Mcu.Pin21=PB2
|
||||
Mcu.Pin22=PE7
|
||||
Mcu.Pin23=PE8
|
||||
Mcu.Pin24=PE9
|
||||
Mcu.Pin25=PE10
|
||||
Mcu.Pin26=PE11
|
||||
Mcu.Pin27=PE12
|
||||
Mcu.Pin28=PE13
|
||||
Mcu.Pin29=PE15
|
||||
Mcu.Pin3=PC14-OSC32_IN
|
||||
Mcu.Pin30=PB10
|
||||
Mcu.Pin31=PB11
|
||||
Mcu.Pin32=PB12
|
||||
Mcu.Pin33=PB13
|
||||
Mcu.Pin34=PB14
|
||||
Mcu.Pin35=PB15
|
||||
Mcu.Pin36=PD8
|
||||
Mcu.Pin37=PD9
|
||||
Mcu.Pin38=PD10
|
||||
Mcu.Pin39=PD11
|
||||
Mcu.Pin4=PC15-OSC32_OUT
|
||||
Mcu.Pin40=PD12
|
||||
Mcu.Pin41=PD13
|
||||
Mcu.Pin42=PA8
|
||||
Mcu.Pin43=PA9
|
||||
Mcu.Pin44=PA10
|
||||
Mcu.Pin45=PA11
|
||||
Mcu.Pin46=PA12
|
||||
Mcu.Pin47=PA13(JTMS/SWDIO)
|
||||
Mcu.Pin48=PA14(JTCK/SWCLK)
|
||||
Mcu.Pin49=PA15(JTDI)
|
||||
Mcu.Pin5=PH0-OSC_IN
|
||||
Mcu.Pin50=PC12
|
||||
Mcu.Pin51=PD0
|
||||
Mcu.Pin52=PD1
|
||||
Mcu.Pin53=PD2
|
||||
Mcu.Pin54=PD4
|
||||
Mcu.Pin55=PD5
|
||||
Mcu.Pin56=PD6
|
||||
Mcu.Pin57=PD7
|
||||
Mcu.Pin58=PB3(JTDO/TRACESWO)
|
||||
Mcu.Pin59=PB5
|
||||
Mcu.Pin6=PH1-OSC_OUT
|
||||
Mcu.Pin60=PB6
|
||||
Mcu.Pin61=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin62=VP_OCTOSPI1_VS_octo
|
||||
Mcu.Pin63=VP_SYS_VS_tim23
|
||||
Mcu.Pin64=VP_MEMORYMAP_VS_MEMORYMAP
|
||||
Mcu.Pin7=PC0
|
||||
Mcu.Pin8=PC1
|
||||
Mcu.Pin9=PC2_C
|
||||
Mcu.PinsNb=65
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32H723VGTx
|
||||
MxCube.Version=6.15.0
|
||||
MxDb.Version=DB.6.0.150
|
||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.EXTI15_10_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.ForceEnableDMAVector=true
|
||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
|
||||
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
|
||||
NVIC.SPI2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
|
||||
NVIC.SavedPendsvIrqHandlerGenerated=true
|
||||
NVIC.SavedSvcallIrqHandlerGenerated=true
|
||||
NVIC.SavedSystickIrqHandlerGenerated=true
|
||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
|
||||
NVIC.TIM23_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
|
||||
NVIC.TimeBase=TIM23_IRQn
|
||||
NVIC.TimeBaseIP=TIM23
|
||||
NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
PA0.Locked=true
|
||||
PA0.Signal=S_TIM2_CH1_ETR
|
||||
PA1.Locked=true
|
||||
PA1.Mode=OCTOSPI1_IOL_Port1L
|
||||
PA1.Signal=OCTOSPIM_P1_IO3
|
||||
PA10.Locked=true
|
||||
PA10.Mode=Asynchronous
|
||||
PA10.Signal=USART1_RX
|
||||
PA11.Mode=Device_Only_FS
|
||||
PA11.Signal=USB_OTG_HS_DM
|
||||
PA12.Mode=Device_Only_FS
|
||||
PA12.Signal=USB_OTG_HS_DP
|
||||
PA13(JTMS/SWDIO).Locked=true
|
||||
PA13(JTMS/SWDIO).Mode=Serial_Wire
|
||||
PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
|
||||
PA14(JTCK/SWCLK).Locked=true
|
||||
PA14(JTCK/SWCLK).Mode=Serial_Wire
|
||||
PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
|
||||
PA15(JTDI).Locked=true
|
||||
PA15(JTDI).Signal=GPIO_Input
|
||||
PA2.Locked=true
|
||||
PA2.Signal=S_TIM2_CH3
|
||||
PA3.Locked=true
|
||||
PA3.Mode=OCTOSPI1_IOL_Port1L
|
||||
PA3.Signal=OCTOSPIM_P1_IO2
|
||||
PA5.Locked=true
|
||||
PA5.Signal=ADCx_INP19
|
||||
PA7.GPIOParameters=GPIO_Label
|
||||
PA7.GPIO_Label=WS2812
|
||||
PA7.Locked=true
|
||||
PA7.Signal=S_TIM3_CH2
|
||||
PA8.Locked=true
|
||||
PA8.Mode=Clock-out-1
|
||||
PA8.Signal=RCC_MCO_1
|
||||
PA9.Locked=true
|
||||
PA9.Mode=Asynchronous
|
||||
PA9.Signal=USART1_TX
|
||||
PB0.Locked=true
|
||||
PB0.Mode=OCTOSPI1_IOL_Port1L
|
||||
PB0.Signal=OCTOSPIM_P1_IO1
|
||||
PB1.GPIOParameters=GPIO_Label
|
||||
PB1.GPIO_Label=IMU_HEAT
|
||||
PB1.Locked=true
|
||||
PB1.Signal=S_TIM3_CH4
|
||||
PB10.GPIOParameters=GPIO_Label
|
||||
PB10.GPIO_Label=LCD_BLK
|
||||
PB10.Locked=true
|
||||
PB10.Signal=GPIO_Output
|
||||
PB11.GPIOParameters=GPIO_Label
|
||||
PB11.GPIO_Label=LCD_RES
|
||||
PB11.Locked=true
|
||||
PB11.Signal=GPIO_Output
|
||||
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PB12.GPIO_Label=DCMI_REST
|
||||
PB12.GPIO_PuPd=GPIO_PULLUP
|
||||
PB12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PB12.Locked=true
|
||||
PB12.PinState=GPIO_PIN_SET
|
||||
PB12.Signal=GPIO_Output
|
||||
PB13.GPIOParameters=GPIO_Speed
|
||||
PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PB13.Locked=true
|
||||
PB13.Mode=Full_Duplex_Master
|
||||
PB13.Signal=SPI2_SCK
|
||||
PB14.Mode=Hardware Flow Control (RS485)
|
||||
PB14.Signal=USART3_DE
|
||||
PB15.GPIOParameters=GPIO_Label
|
||||
PB15.GPIO_Label=BUZZER
|
||||
PB15.Locked=true
|
||||
PB15.Signal=S_TIM12_CH2
|
||||
PB2.Locked=true
|
||||
PB2.Mode=O1_P1_CLK
|
||||
PB2.Signal=OCTOSPIM_P1_CLK
|
||||
PB3(JTDO/TRACESWO).GPIOParameters=GPIO_Speed
|
||||
PB3(JTDO/TRACESWO).GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PB3(JTDO/TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
|
||||
PB3(JTDO/TRACESWO).Signal=SPI1_SCK
|
||||
PB5.Locked=true
|
||||
PB5.Mode=FDCAN_Activate
|
||||
PB5.Signal=FDCAN2_RX
|
||||
PB6.Locked=true
|
||||
PB6.Mode=FDCAN_Activate
|
||||
PB6.Signal=FDCAN2_TX
|
||||
PC0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
|
||||
PC0.GPIO_Label=ACCL_CS
|
||||
PC0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PC0.Locked=true
|
||||
PC0.PinState=GPIO_PIN_SET
|
||||
PC0.Signal=GPIO_Output
|
||||
PC1.GPIOParameters=GPIO_Speed
|
||||
PC1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PC1.Mode=Full_Duplex_Master
|
||||
PC1.Signal=SPI2_MOSI
|
||||
PC12.Mode=Asynchronous
|
||||
PC12.Signal=UART5_TX
|
||||
PC13.GPIOParameters=PinState,GPIO_Label
|
||||
PC13.GPIO_Label=POWER_24V_2
|
||||
PC13.Locked=true
|
||||
PC13.PinState=GPIO_PIN_SET
|
||||
PC13.Signal=GPIO_Output
|
||||
PC14-OSC32_IN.GPIOParameters=PinState,GPIO_Label
|
||||
PC14-OSC32_IN.GPIO_Label=POWER_24V_1
|
||||
PC14-OSC32_IN.Locked=true
|
||||
PC14-OSC32_IN.PinState=GPIO_PIN_SET
|
||||
PC14-OSC32_IN.Signal=GPIO_Output
|
||||
PC15-OSC32_OUT.GPIOParameters=PinState,GPIO_Label
|
||||
PC15-OSC32_OUT.GPIO_Label=POWER_5V
|
||||
PC15-OSC32_OUT.Locked=true
|
||||
PC15-OSC32_OUT.PinState=GPIO_PIN_SET
|
||||
PC15-OSC32_OUT.Signal=GPIO_Output
|
||||
PC2_C.GPIOParameters=GPIO_Speed
|
||||
PC2_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PC2_C.Mode=Full_Duplex_Master
|
||||
PC2_C.Signal=SPI2_MISO
|
||||
PC3_C.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
|
||||
PC3_C.GPIO_Label=GYRO_CS
|
||||
PC3_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PC3_C.Locked=true
|
||||
PC3_C.PinState=GPIO_PIN_SET
|
||||
PC3_C.Signal=GPIO_Output
|
||||
PC4.Locked=true
|
||||
PC4.Signal=ADCx_INP4
|
||||
PC5.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PC5.GPIO_Label=DCMI_PWDN
|
||||
PC5.GPIO_PuPd=GPIO_NOPULL
|
||||
PC5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PC5.Locked=true
|
||||
PC5.PinState=GPIO_PIN_SET
|
||||
PC5.Signal=GPIO_Output
|
||||
PD0.Mode=FDCAN_Activate
|
||||
PD0.Signal=FDCAN1_RX
|
||||
PD1.Locked=true
|
||||
PD1.Mode=FDCAN_Activate
|
||||
PD1.Signal=FDCAN1_TX
|
||||
PD10.GPIOParameters=GPIO_Label
|
||||
PD10.GPIO_Label=LCD_DC
|
||||
PD10.Locked=true
|
||||
PD10.Signal=GPIO_Output
|
||||
PD11.Locked=true
|
||||
PD11.Mode=OCTOSPI1_IOL_Port1L
|
||||
PD11.Signal=OCTOSPIM_P1_IO0
|
||||
PD12.Mode=FDCAN_Activate
|
||||
PD12.Signal=FDCAN3_RX
|
||||
PD13.Locked=true
|
||||
PD13.Mode=FDCAN_Activate
|
||||
PD13.Signal=FDCAN3_TX
|
||||
PD2.Mode=Asynchronous
|
||||
PD2.Signal=UART5_RX
|
||||
PD4.Locked=true
|
||||
PD4.Mode=Hardware Flow Control (RS485)
|
||||
PD4.Signal=USART2_DE
|
||||
PD5.Locked=true
|
||||
PD5.Mode=Asynchronous
|
||||
PD5.Signal=USART2_TX
|
||||
PD6.Locked=true
|
||||
PD6.Mode=Asynchronous
|
||||
PD6.Signal=USART2_RX
|
||||
PD7.GPIOParameters=GPIO_Speed
|
||||
PD7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PD7.Locked=true
|
||||
PD7.Mode=TX_Only_Simplex_Unidirect_Master
|
||||
PD7.Signal=SPI1_MOSI
|
||||
PD8.Mode=Asynchronous
|
||||
PD8.Signal=USART3_TX
|
||||
PD9.Mode=Asynchronous
|
||||
PD9.Signal=USART3_RX
|
||||
PE10.GPIOParameters=GPIO_Label
|
||||
PE10.GPIO_Label=ACCL_INT
|
||||
PE10.Locked=true
|
||||
PE10.Signal=GPXTI10
|
||||
PE11.Locked=true
|
||||
PE11.Mode=OCTOSPI1_Port1_NCS
|
||||
PE11.Signal=OCTOSPIM_P1_NCS
|
||||
PE12.GPIOParameters=GPIO_Label
|
||||
PE12.GPIO_Label=GYRO_INT
|
||||
PE12.Locked=true
|
||||
PE12.Signal=GPXTI12
|
||||
PE13.Signal=S_TIM1_CH3
|
||||
PE15.GPIOParameters=GPIO_Label
|
||||
PE15.GPIO_Label=LCD_CS
|
||||
PE15.Locked=true
|
||||
PE15.Signal=GPIO_Output
|
||||
PE2.Mode=Asynchronous
|
||||
PE2.Signal=USART10_RX
|
||||
PE3.Mode=Asynchronous
|
||||
PE3.Signal=USART10_TX
|
||||
PE7.Mode=Asynchronous
|
||||
PE7.Signal=UART7_RX
|
||||
PE8.Mode=Asynchronous
|
||||
PE8.Signal=UART7_TX
|
||||
PE9.Locked=true
|
||||
PE9.Signal=S_TIM1_CH1
|
||||
PH0-OSC_IN.Mode=HSE-External-Oscillator
|
||||
PH0-OSC_IN.Signal=RCC_OSC_IN
|
||||
PH1-OSC_OUT.Mode=HSE-External-Oscillator
|
||||
PH1-OSC_OUT.Signal=RCC_OSC_OUT
|
||||
PinOutPanel.RotationAngle=0
|
||||
ProjectManager.AskForMigrate=true
|
||||
ProjectManager.BackupPrevious=false
|
||||
ProjectManager.CompilerLinker=GCC
|
||||
ProjectManager.CompilerOptimize=6
|
||||
ProjectManager.ComputerToolchain=false
|
||||
ProjectManager.CoupleFile=true
|
||||
ProjectManager.CustomerFirmwarePackage=
|
||||
ProjectManager.DefaultFWLocation=true
|
||||
ProjectManager.DeletePrevious=true
|
||||
ProjectManager.DeviceId=STM32H723VGTx
|
||||
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.12.1
|
||||
ProjectManager.FreePins=false
|
||||
ProjectManager.HalAssertFull=false
|
||||
ProjectManager.HeapSize=0x1000
|
||||
ProjectManager.KeepUserCode=true
|
||||
ProjectManager.LastFirmware=true
|
||||
ProjectManager.LibraryCopy=0
|
||||
ProjectManager.MainLocation=Core/Src
|
||||
ProjectManager.NoMain=false
|
||||
ProjectManager.PreviousToolchain=
|
||||
ProjectManager.ProjectBuild=false
|
||||
ProjectManager.ProjectFileName=CtrBoard-H7_ALL.ioc
|
||||
ProjectManager.ProjectName=CtrBoard-H7_ALL
|
||||
ProjectManager.ProjectStructure=
|
||||
ProjectManager.RegisterCallBack=
|
||||
ProjectManager.StackSize=0x2000
|
||||
ProjectManager.TargetToolchain=MDK-ARM V5.32
|
||||
ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
ProjectManager.UAScriptBeforePath=
|
||||
ProjectManager.UnderRoot=false
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM12_Init-TIM12-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_USART1_UART_Init-USART1-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_UART7_Init-UART7-false-HAL-true,13-MX_USART10_UART_Init-USART10-false-HAL-true,14-MX_FDCAN1_Init-FDCAN1-false-HAL-true,15-MX_FDCAN2_Init-FDCAN2-false-HAL-true,16-MX_FDCAN3_Init-FDCAN3-false-HAL-true,17-MX_TIM1_Init-TIM1-false-HAL-true,18-MX_TIM2_Init-TIM2-false-HAL-true,19-MX_OCTOSPI1_Init-OCTOSPI1-false-HAL-true,20-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,21-MX_UART5_Init-UART5-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
|
||||
RCC.ADCFreq_Value=96000000
|
||||
RCC.AHB12Freq_Value=240000000
|
||||
RCC.AHB4Freq_Value=240000000
|
||||
RCC.APB1Freq_Value=120000000
|
||||
RCC.APB2Freq_Value=120000000
|
||||
RCC.APB3Freq_Value=120000000
|
||||
RCC.APB4Freq_Value=120000000
|
||||
RCC.AXIClockFreq_Value=240000000
|
||||
RCC.CECFreq_Value=32000
|
||||
RCC.CKPERFreq_Value=64000000
|
||||
RCC.CortexFreq_Value=480000000
|
||||
RCC.CpuClockFreq_Value=480000000
|
||||
RCC.D1CPREFreq_Value=480000000
|
||||
RCC.D1PPRE=RCC_APB3_DIV2
|
||||
RCC.D2PPRE1=RCC_APB1_DIV2
|
||||
RCC.D2PPRE2=RCC_APB2_DIV2
|
||||
RCC.D3PPRE=RCC_APB4_DIV2
|
||||
RCC.DFSDMACLkFreq_Value=120000000
|
||||
RCC.DFSDMFreq_Value=120000000
|
||||
RCC.DIVM1=2
|
||||
RCC.DIVM2=2
|
||||
RCC.DIVN1=40
|
||||
RCC.DIVN2=16
|
||||
RCC.DIVP1=1
|
||||
RCC.DIVP1Freq_Value=480000000
|
||||
RCC.DIVP2Freq_Value=96000000
|
||||
RCC.DIVP3Freq_Value=48375000
|
||||
RCC.DIVQ1=4
|
||||
RCC.DIVQ1Freq_Value=120000000
|
||||
RCC.DIVQ2Freq_Value=96000000
|
||||
RCC.DIVQ3Freq_Value=48375000
|
||||
RCC.DIVR1Freq_Value=240000000
|
||||
RCC.DIVR2Freq_Value=96000000
|
||||
RCC.DIVR3Freq_Value=48375000
|
||||
RCC.EnbaleCSS=false
|
||||
RCC.FDCANFreq_Value=120000000
|
||||
RCC.FMCFreq_Value=240000000
|
||||
RCC.FamilyName=M
|
||||
RCC.HCLK3ClockFreq_Value=240000000
|
||||
RCC.HCLKFreq_Value=240000000
|
||||
RCC.HPRE=RCC_HCLK_DIV2
|
||||
RCC.HSE_VALUE=24000000
|
||||
RCC.I2C123Freq_Value=120000000
|
||||
RCC.I2C4Freq_Value=120000000
|
||||
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVN1,DIVN2,DIVP1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL2_VCI_Range-AdvancedSettings,PLL2_VCO_SEL-AdvancedSettings,PLL3FRACN,PLL3_VCO_SEL-AdvancedSettings,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6CLockSelection,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
|
||||
RCC.LPTIM1Freq_Value=120000000
|
||||
RCC.LPTIM2Freq_Value=120000000
|
||||
RCC.LPTIM345Freq_Value=120000000
|
||||
RCC.LPUART1Freq_Value=120000000
|
||||
RCC.LTDCFreq_Value=48375000
|
||||
RCC.MCO1PinFreq_Value=64000000
|
||||
RCC.MCO2PinFreq_Value=480000000
|
||||
RCC.PLL2FRACN=0
|
||||
RCC.PLL2_VCI_Range-AdvancedSettings=RCC_PLL2VCIRANGE_0
|
||||
RCC.PLL2_VCO_SEL-AdvancedSettings=RCC_PLL2VCOWIDE
|
||||
RCC.PLL3FRACN=0
|
||||
RCC.PLL3_VCO_SEL-AdvancedSettings=RCC_PLL3VCOMEDIUM
|
||||
RCC.PLLFRACN=0
|
||||
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
|
||||
RCC.QSPIFreq_Value=240000000
|
||||
RCC.RNGFreq_Value=48000000
|
||||
RCC.RTCFreq_Value=32000
|
||||
RCC.SAI1Freq_Value=120000000
|
||||
RCC.SAI4AFreq_Value=120000000
|
||||
RCC.SAI4BFreq_Value=120000000
|
||||
RCC.SDMMCFreq_Value=120000000
|
||||
RCC.SPDIFRXFreq_Value=120000000
|
||||
RCC.SPI123Freq_Value=120000000
|
||||
RCC.SPI45Freq_Value=120000000
|
||||
RCC.SPI6CLockSelection=RCC_SPI6CLKSOURCE_HSE
|
||||
RCC.SPI6Freq_Value=24000000
|
||||
RCC.SWPMI1Freq_Value=120000000
|
||||
RCC.SYSCLKFreq_VALUE=480000000
|
||||
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
|
||||
RCC.Tim1OutputFreq_Value=240000000
|
||||
RCC.Tim2OutputFreq_Value=240000000
|
||||
RCC.TraceFreq_Value=240000000
|
||||
RCC.USART16Freq_Value=120000000
|
||||
RCC.USART234578Freq_Value=120000000
|
||||
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
|
||||
RCC.USBFreq_Value=48000000
|
||||
RCC.VCO1OutputFreq_Value=480000000
|
||||
RCC.VCO2OutputFreq_Value=192000000
|
||||
RCC.VCO3OutputFreq_Value=96750000
|
||||
RCC.VCOInput1Freq_Value=12000000
|
||||
RCC.VCOInput2Freq_Value=12000000
|
||||
RCC.VCOInput3Freq_Value=750000
|
||||
SH.ADCx_INP19.0=ADC1_INP19,IN19-Single-Ended
|
||||
SH.ADCx_INP19.ConfNb=1
|
||||
SH.ADCx_INP4.0=ADC1_INP4,IN4-Single-Ended
|
||||
SH.ADCx_INP4.ConfNb=1
|
||||
SH.GPXTI10.0=GPIO_EXTI10
|
||||
SH.GPXTI10.ConfNb=1
|
||||
SH.GPXTI12.0=GPIO_EXTI12
|
||||
SH.GPXTI12.ConfNb=1
|
||||
SH.S_TIM12_CH2.0=TIM12_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM12_CH2.ConfNb=1
|
||||
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM1_CH1.ConfNb=1
|
||||
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM1_CH3.ConfNb=1
|
||||
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM2_CH1_ETR.ConfNb=1
|
||||
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM2_CH3.ConfNb=1
|
||||
SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM3_CH2.ConfNb=1
|
||||
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
|
||||
SH.S_TIM3_CH4.ConfNb=1
|
||||
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
|
||||
SPI1.CLKPolarity=SPI_POLARITY_HIGH
|
||||
SPI1.CalculateBaudRate=30.0 MBits/s
|
||||
SPI1.DataSize=SPI_DATASIZE_8BIT
|
||||
SPI1.Direction=SPI_DIRECTION_2LINES_TXONLY
|
||||
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity
|
||||
SPI1.Mode=SPI_MODE_MASTER
|
||||
SPI1.VirtualType=VM_MASTER
|
||||
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
|
||||
SPI2.CLKPhase=SPI_PHASE_2EDGE
|
||||
SPI2.CLKPolarity=SPI_POLARITY_HIGH
|
||||
SPI2.CalculateBaudRate=3.75 MBits/s
|
||||
SPI2.DataSize=SPI_DATASIZE_8BIT
|
||||
SPI2.Direction=SPI_DIRECTION_2LINES
|
||||
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity,CLKPhase
|
||||
SPI2.Mode=SPI_MODE_MASTER
|
||||
SPI2.VirtualType=VM_MASTER
|
||||
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM1.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation1 CH1,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
|
||||
TIM1.Period=10000
|
||||
TIM1.Prescaler=24
|
||||
TIM1.Pulse-PWM\ Generation1\ CH1=5000
|
||||
TIM1.Pulse-PWM\ Generation3\ CH3=5000
|
||||
TIM12.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM12.IPParameters=Channel-PWM Generation2 CH2,Prescaler,Period
|
||||
TIM12.Period=2000-1
|
||||
TIM12.Prescaler=24-1
|
||||
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM2.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation3 CH3,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
|
||||
TIM2.Period=10000
|
||||
TIM2.Prescaler=24
|
||||
TIM2.Pulse-PWM\ Generation1\ CH1=5000
|
||||
TIM2.Pulse-PWM\ Generation3\ CH3=5000
|
||||
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
|
||||
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
|
||||
TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload,Channel-PWM Generation2 CH2
|
||||
TIM3.Period=10000-1
|
||||
TIM3.Prescaler=24-1
|
||||
UART5.BaudRate=100000
|
||||
UART5.IPParameters=Mode,WordLength,Parity,BaudRate
|
||||
UART5.Mode=MODE_RX
|
||||
UART5.Parity=PARITY_EVEN
|
||||
UART5.WordLength=WORDLENGTH_9B
|
||||
UART7.BaudRate=921600
|
||||
UART7.IPParameters=BaudRate
|
||||
USART1.BaudRate=921600
|
||||
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
|
||||
USART1.VirtualMode-Asynchronous=VM_ASYNC
|
||||
USART10.BaudRate=921600
|
||||
USART10.IPParameters=VirtualMode,BaudRate
|
||||
USART10.VirtualMode=VM_ASYNC
|
||||
USART2.BaudRate=921600
|
||||
USART2.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
|
||||
USART2.VirtualMode-Asynchronous=VM_ASYNC
|
||||
USART2.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
|
||||
USART3.BaudRate=921600
|
||||
USART3.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
|
||||
USART3.VirtualMode-Asynchronous=VM_ASYNC
|
||||
USART3.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
|
||||
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS
|
||||
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
|
||||
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
||||
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
|
||||
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
|
||||
VP_OCTOSPI1_VS_octo.Mode=octo_mode
|
||||
VP_OCTOSPI1_VS_octo.Signal=OCTOSPI1_VS_octo
|
||||
VP_SYS_VS_tim23.Mode=TIM23
|
||||
VP_SYS_VS_tim23.Signal=SYS_VS_tim23
|
||||
board=custom
|
||||
rtos.0.ip=FREERTOS
|
||||
743
ioc/DevC.ioc
Normal file
743
ioc/DevC.ioc
Normal file
@ -0,0 +1,743 @@
|
||||
#MicroXplorer Configuration settings - do not modify
|
||||
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
|
||||
ADC1.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6
|
||||
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,master,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
|
||||
ADC1.NbrOfConversionFlag=1
|
||||
ADC1.Rank-0\#ChannelRegularConversion=1
|
||||
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
|
||||
ADC1.master=1
|
||||
ADC3.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_8
|
||||
ADC3.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6
|
||||
ADC3.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
|
||||
ADC3.NbrOfConversionFlag=1
|
||||
ADC3.Rank-0\#ChannelRegularConversion=1
|
||||
ADC3.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
|
||||
CAD.formats=
|
||||
CAD.pinconfig=
|
||||
CAD.provider=
|
||||
CAN1.ABOM=DISABLE
|
||||
CAN1.BS1=CAN_BS1_6TQ
|
||||
CAN1.BS2=CAN_BS2_7TQ
|
||||
CAN1.CalculateBaudRate=1000000
|
||||
CAN1.CalculateTimeBit=1000
|
||||
CAN1.CalculateTimeQuantum=71.42857142857143
|
||||
CAN1.IPParameters=CalculateTimeQuantum,BS1,BS2,Prescaler,TXFP,ABOM,CalculateTimeBit,CalculateBaudRate,NART
|
||||
CAN1.NART=ENABLE
|
||||
CAN1.Prescaler=3
|
||||
CAN1.TXFP=ENABLE
|
||||
CAN2.BS1=CAN_BS1_6TQ
|
||||
CAN2.BS2=CAN_BS2_7TQ
|
||||
CAN2.CalculateBaudRate=1000000
|
||||
CAN2.CalculateTimeBit=1000
|
||||
CAN2.CalculateTimeQuantum=71.42857142857143
|
||||
CAN2.IPParameters=CalculateTimeQuantum,BS1,BS2,Prescaler,TXFP,CalculateTimeBit,CalculateBaudRate,NART
|
||||
CAN2.NART=ENABLE
|
||||
CAN2.Prescaler=3
|
||||
CAN2.TXFP=ENABLE
|
||||
Dma.I2C2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.I2C2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.I2C2_TX.2.Instance=DMA1_Stream7
|
||||
Dma.I2C2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.I2C2_TX.2.MemInc=DMA_MINC_ENABLE
|
||||
Dma.I2C2_TX.2.Mode=DMA_NORMAL
|
||||
Dma.I2C2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.I2C2_TX.2.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.I2C2_TX.2.Priority=DMA_PRIORITY_HIGH
|
||||
Dma.I2C2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.I2C3_RX.7.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.I2C3_RX.7.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.I2C3_RX.7.Instance=DMA1_Stream2
|
||||
Dma.I2C3_RX.7.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.I2C3_RX.7.MemInc=DMA_MINC_ENABLE
|
||||
Dma.I2C3_RX.7.Mode=DMA_NORMAL
|
||||
Dma.I2C3_RX.7.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.I2C3_RX.7.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.I2C3_RX.7.Priority=DMA_PRIORITY_LOW
|
||||
Dma.I2C3_RX.7.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.Request0=SPI1_RX
|
||||
Dma.Request1=SPI1_TX
|
||||
Dma.Request2=I2C2_TX
|
||||
Dma.Request3=USART3_RX
|
||||
Dma.Request4=USART6_RX
|
||||
Dma.Request5=USART6_TX
|
||||
Dma.Request6=USART1_TX
|
||||
Dma.Request7=I2C3_RX
|
||||
Dma.Request8=USART1_RX
|
||||
Dma.RequestsNb=9
|
||||
Dma.SPI1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.SPI1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.SPI1_RX.0.Instance=DMA2_Stream2
|
||||
Dma.SPI1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.SPI1_RX.0.MemInc=DMA_MINC_ENABLE
|
||||
Dma.SPI1_RX.0.Mode=DMA_NORMAL
|
||||
Dma.SPI1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.SPI1_RX.0.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SPI1_RX.0.Priority=DMA_PRIORITY_VERY_HIGH
|
||||
Dma.SPI1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.SPI1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.SPI1_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.SPI1_TX.1.Instance=DMA2_Stream3
|
||||
Dma.SPI1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.SPI1_TX.1.MemInc=DMA_MINC_ENABLE
|
||||
Dma.SPI1_TX.1.Mode=DMA_NORMAL
|
||||
Dma.SPI1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.SPI1_TX.1.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SPI1_TX.1.Priority=DMA_PRIORITY_HIGH
|
||||
Dma.SPI1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART1_RX.8.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.USART1_RX.8.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART1_RX.8.Instance=DMA2_Stream5
|
||||
Dma.USART1_RX.8.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART1_RX.8.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART1_RX.8.Mode=DMA_NORMAL
|
||||
Dma.USART1_RX.8.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART1_RX.8.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART1_RX.8.Priority=DMA_PRIORITY_MEDIUM
|
||||
Dma.USART1_RX.8.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART1_TX.6.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.USART1_TX.6.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART1_TX.6.Instance=DMA2_Stream7
|
||||
Dma.USART1_TX.6.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART1_TX.6.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART1_TX.6.Mode=DMA_NORMAL
|
||||
Dma.USART1_TX.6.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART1_TX.6.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART1_TX.6.Priority=DMA_PRIORITY_MEDIUM
|
||||
Dma.USART1_TX.6.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART3_RX.3.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.USART3_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART3_RX.3.Instance=DMA1_Stream1
|
||||
Dma.USART3_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART3_RX.3.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART3_RX.3.Mode=DMA_NORMAL
|
||||
Dma.USART3_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART3_RX.3.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART3_RX.3.Priority=DMA_PRIORITY_HIGH
|
||||
Dma.USART3_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART6_RX.4.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.USART6_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART6_RX.4.Instance=DMA2_Stream1
|
||||
Dma.USART6_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART6_RX.4.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART6_RX.4.Mode=DMA_NORMAL
|
||||
Dma.USART6_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART6_RX.4.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART6_RX.4.Priority=DMA_PRIORITY_MEDIUM
|
||||
Dma.USART6_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART6_TX.5.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.USART6_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART6_TX.5.Instance=DMA2_Stream6
|
||||
Dma.USART6_TX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART6_TX.5.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART6_TX.5.Mode=DMA_NORMAL
|
||||
Dma.USART6_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART6_TX.5.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART6_TX.5.Priority=DMA_PRIORITY_MEDIUM
|
||||
Dma.USART6_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
FREERTOS.FootprintOK=true
|
||||
FREERTOS.INCLUDE_pcTaskGetTaskName=1
|
||||
FREERTOS.INCLUDE_uxTaskGetStackHighWaterMark2=1
|
||||
FREERTOS.INCLUDE_vTaskCleanUpResources=1
|
||||
FREERTOS.INCLUDE_xEventGroupSetBitFromISR=1
|
||||
FREERTOS.INCLUDE_xSemaphoreGetMutexHolder=1
|
||||
FREERTOS.INCLUDE_xTaskAbortDelay=1
|
||||
FREERTOS.INCLUDE_xTaskGetCurrentTaskHandle=1
|
||||
FREERTOS.INCLUDE_xTaskGetHandle=1
|
||||
FREERTOS.IPParameters=Tasks01,FootprintOK,configENABLE_FPU,configENABLE_BACKWARD_COMPATIBILITY,configRECORD_STACK_HIGH_ADDRESS,configCHECK_FOR_STACK_OVERFLOW,configGENERATE_RUN_TIME_STATS,configUSE_STATS_FORMATTING_FUNCTIONS,configTOTAL_HEAP_SIZE,INCLUDE_xTaskGetCurrentTaskHandle,INCLUDE_xTaskGetHandle,INCLUDE_uxTaskGetStackHighWaterMark2,INCLUDE_xEventGroupSetBitFromISR,INCLUDE_xTaskAbortDelay,INCLUDE_pcTaskGetTaskName,INCLUDE_xSemaphoreGetMutexHolder,INCLUDE_vTaskCleanUpResources,configUSE_APPLICATION_TASK_TAG
|
||||
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
|
||||
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
|
||||
FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0
|
||||
FREERTOS.configENABLE_FPU=1
|
||||
FREERTOS.configGENERATE_RUN_TIME_STATS=1
|
||||
FREERTOS.configRECORD_STACK_HIGH_ADDRESS=1
|
||||
FREERTOS.configTOTAL_HEAP_SIZE=0x10000
|
||||
FREERTOS.configUSE_APPLICATION_TASK_TAG=0
|
||||
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
|
||||
File.Version=6
|
||||
GPIO.groupedBy=Group By Peripherals
|
||||
I2C1.I2C_Mode=I2C_Fast
|
||||
I2C1.IPParameters=I2C_Mode
|
||||
I2C2.I2C_Mode=I2C_Fast
|
||||
I2C2.IPParameters=I2C_Mode
|
||||
I2C3.I2C_Mode=I2C_Fast
|
||||
I2C3.IPParameters=I2C_Mode
|
||||
KeepUserPlacement=false
|
||||
Mcu.CPN=STM32F407IGH6
|
||||
Mcu.Family=STM32F4
|
||||
Mcu.IP0=ADC1
|
||||
Mcu.IP1=ADC3
|
||||
Mcu.IP10=NVIC
|
||||
Mcu.IP11=RCC
|
||||
Mcu.IP12=RNG
|
||||
Mcu.IP13=SPI1
|
||||
Mcu.IP14=SPI2
|
||||
Mcu.IP15=SYS
|
||||
Mcu.IP16=TIM1
|
||||
Mcu.IP17=TIM3
|
||||
Mcu.IP18=TIM4
|
||||
Mcu.IP19=TIM5
|
||||
Mcu.IP2=CAN1
|
||||
Mcu.IP20=TIM7
|
||||
Mcu.IP21=TIM8
|
||||
Mcu.IP22=TIM10
|
||||
Mcu.IP23=USART1
|
||||
Mcu.IP24=USART3
|
||||
Mcu.IP25=USART6
|
||||
Mcu.IP26=USB_DEVICE
|
||||
Mcu.IP27=USB_OTG_FS
|
||||
Mcu.IP3=CAN2
|
||||
Mcu.IP4=CRC
|
||||
Mcu.IP5=DMA
|
||||
Mcu.IP6=FREERTOS
|
||||
Mcu.IP7=I2C1
|
||||
Mcu.IP8=I2C2
|
||||
Mcu.IP9=I2C3
|
||||
Mcu.IPNb=28
|
||||
Mcu.Name=STM32F407I(E-G)Hx
|
||||
Mcu.Package=UFBGA176
|
||||
Mcu.Pin0=PB8
|
||||
Mcu.Pin1=PB5
|
||||
Mcu.Pin10=PD0
|
||||
Mcu.Pin11=PC11
|
||||
Mcu.Pin12=PC10
|
||||
Mcu.Pin13=PA12
|
||||
Mcu.Pin14=PI6
|
||||
Mcu.Pin15=PG9
|
||||
Mcu.Pin16=PD1
|
||||
Mcu.Pin17=PA11
|
||||
Mcu.Pin18=PF0
|
||||
Mcu.Pin19=PA9
|
||||
Mcu.Pin2=PG14
|
||||
Mcu.Pin20=PC9
|
||||
Mcu.Pin21=PA8
|
||||
Mcu.Pin22=PH0-OSC_IN
|
||||
Mcu.Pin23=PC8
|
||||
Mcu.Pin24=PH1-OSC_OUT
|
||||
Mcu.Pin25=PF1
|
||||
Mcu.Pin26=PC6
|
||||
Mcu.Pin27=PG6
|
||||
Mcu.Pin28=PF6
|
||||
Mcu.Pin29=PH12
|
||||
Mcu.Pin3=PB4
|
||||
Mcu.Pin30=PG3
|
||||
Mcu.Pin31=PF10
|
||||
Mcu.Pin32=PH11
|
||||
Mcu.Pin33=PH10
|
||||
Mcu.Pin34=PC0
|
||||
Mcu.Pin35=PC1
|
||||
Mcu.Pin36=PC2
|
||||
Mcu.Pin37=PD14
|
||||
Mcu.Pin38=PA0-WKUP
|
||||
Mcu.Pin39=PA4
|
||||
Mcu.Pin4=PB3
|
||||
Mcu.Pin40=PC4
|
||||
Mcu.Pin41=PE13
|
||||
Mcu.Pin42=PC5
|
||||
Mcu.Pin43=PE9
|
||||
Mcu.Pin44=PE11
|
||||
Mcu.Pin45=PE14
|
||||
Mcu.Pin46=PB12
|
||||
Mcu.Pin47=PB13
|
||||
Mcu.Pin48=PA7
|
||||
Mcu.Pin49=PB0
|
||||
Mcu.Pin5=PA14
|
||||
Mcu.Pin50=PB14
|
||||
Mcu.Pin51=PB15
|
||||
Mcu.Pin52=VP_ADC1_TempSens_Input
|
||||
Mcu.Pin53=VP_ADC1_Vref_Input
|
||||
Mcu.Pin54=VP_CRC_VS_CRC
|
||||
Mcu.Pin55=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin56=VP_RNG_VS_RNG
|
||||
Mcu.Pin57=VP_SYS_VS_Systick
|
||||
Mcu.Pin58=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin59=VP_TIM3_VS_ClockSourceINT
|
||||
Mcu.Pin6=PA13
|
||||
Mcu.Pin60=VP_TIM4_VS_ClockSourceINT
|
||||
Mcu.Pin61=VP_TIM5_VS_ClockSourceINT
|
||||
Mcu.Pin62=VP_TIM7_VS_ClockSourceINT
|
||||
Mcu.Pin63=VP_TIM8_VS_ClockSourceINT
|
||||
Mcu.Pin64=VP_TIM10_VS_ClockSourceINT
|
||||
Mcu.Pin65=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin7=PB9
|
||||
Mcu.Pin8=PB7
|
||||
Mcu.Pin9=PB6
|
||||
Mcu.PinsNb=66
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F407IGHx
|
||||
MxCube.Version=6.15.0
|
||||
MxDb.Version=DB.6.0.150
|
||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.CAN1_RX0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.CAN1_RX1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.CAN1_TX_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.CAN2_RX0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.CAN2_RX1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.CAN2_TX_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA1_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream1_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream6_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.EXTI0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.EXTI3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.EXTI4_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.EXTI9_5_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
|
||||
NVIC.ForceEnableDMAVector=true
|
||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.OTG_FS_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
|
||||
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
|
||||
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
|
||||
NVIC.SavedPendsvIrqHandlerGenerated=true
|
||||
NVIC.SavedSvcallIrqHandlerGenerated=true
|
||||
NVIC.SavedSystickIrqHandlerGenerated=true
|
||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:false
|
||||
NVIC.TIM1_BRK_TIM9_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true\:true
|
||||
NVIC.TIM7_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.USART6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||
NVIC.UsageFault_IRQn=true\:0\:0\:true\:false\:true\:false\:false\:false\:false
|
||||
PA0-WKUP.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
|
||||
PA0-WKUP.GPIO_Label=USER_KEY
|
||||
PA0-WKUP.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
|
||||
PA0-WKUP.GPIO_PuPd=GPIO_PULLUP
|
||||
PA0-WKUP.Locked=true
|
||||
PA0-WKUP.Signal=GPXTI0
|
||||
PA11.Mode=Device_Only
|
||||
PA11.Signal=USB_OTG_FS_DM
|
||||
PA12.Mode=Device_Only
|
||||
PA12.Signal=USB_OTG_FS_DP
|
||||
PA13.Mode=Serial_Wire
|
||||
PA13.Signal=SYS_JTMS-SWDIO
|
||||
PA14.Mode=Serial_Wire
|
||||
PA14.Signal=SYS_JTCK-SWCLK
|
||||
PA4.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PA4.GPIO_Label=ACCL_CS
|
||||
PA4.GPIO_PuPd=GPIO_PULLUP
|
||||
PA4.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
|
||||
PA4.Locked=true
|
||||
PA4.PinState=GPIO_PIN_SET
|
||||
PA4.Signal=GPIO_Output
|
||||
PA7.GPIOParameters=GPIO_PuPd
|
||||
PA7.GPIO_PuPd=GPIO_PULLUP
|
||||
PA7.Locked=true
|
||||
PA7.Mode=Full_Duplex_Master
|
||||
PA7.Signal=SPI1_MOSI
|
||||
PA8.GPIOParameters=GPIO_Pu
|
||||
PA8.GPIO_Pu=GPIO_PULLUP
|
||||
PA8.Locked=true
|
||||
PA8.Mode=I2C
|
||||
PA8.Signal=I2C3_SCL
|
||||
PA9.Locked=true
|
||||
PA9.Mode=Asynchronous
|
||||
PA9.Signal=USART1_TX
|
||||
PB0.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PB0.GPIO_Label=GYRO_CS
|
||||
PB0.GPIO_PuPd=GPIO_PULLUP
|
||||
PB0.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
|
||||
PB0.Locked=true
|
||||
PB0.PinState=GPIO_PIN_SET
|
||||
PB0.Signal=GPIO_Output
|
||||
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PB12.GPIO_Label=SPI2_CS
|
||||
PB12.GPIO_PuPd=GPIO_PULLUP
|
||||
PB12.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
|
||||
PB12.Locked=true
|
||||
PB12.PinState=GPIO_PIN_SET
|
||||
PB12.Signal=GPIO_Output
|
||||
PB13.GPIOParameters=GPIO_PuPd
|
||||
PB13.GPIO_PuPd=GPIO_PULLUP
|
||||
PB13.Locked=true
|
||||
PB13.Mode=Full_Duplex_Master
|
||||
PB13.Signal=SPI2_SCK
|
||||
PB14.GPIOParameters=GPIO_PuPd
|
||||
PB14.GPIO_PuPd=GPIO_PULLUP
|
||||
PB14.Locked=true
|
||||
PB14.Mode=Full_Duplex_Master
|
||||
PB14.Signal=SPI2_MISO
|
||||
PB15.GPIOParameters=GPIO_PuPd
|
||||
PB15.GPIO_PuPd=GPIO_PULLUP
|
||||
PB15.Locked=true
|
||||
PB15.Mode=Full_Duplex_Master
|
||||
PB15.Signal=SPI2_MOSI
|
||||
PB3.GPIOParameters=GPIO_PuPd
|
||||
PB3.GPIO_PuPd=GPIO_PULLUP
|
||||
PB3.Locked=true
|
||||
PB3.Mode=Full_Duplex_Master
|
||||
PB3.Signal=SPI1_SCK
|
||||
PB4.GPIOParameters=GPIO_PuPd
|
||||
PB4.GPIO_PuPd=GPIO_PULLUP
|
||||
PB4.Locked=true
|
||||
PB4.Mode=Full_Duplex_Master
|
||||
PB4.Signal=SPI1_MISO
|
||||
PB5.Locked=true
|
||||
PB5.Mode=CAN_Activate
|
||||
PB5.Signal=CAN2_RX
|
||||
PB6.Locked=true
|
||||
PB6.Mode=CAN_Activate
|
||||
PB6.Signal=CAN2_TX
|
||||
PB7.Locked=true
|
||||
PB7.Mode=Asynchronous
|
||||
PB7.Signal=USART1_RX
|
||||
PB8.GPIOParameters=GPIO_Pu
|
||||
PB8.GPIO_Pu=GPIO_PULLUP
|
||||
PB8.Locked=true
|
||||
PB8.Mode=I2C
|
||||
PB8.Signal=I2C1_SCL
|
||||
PB9.GPIOParameters=GPIO_Pu
|
||||
PB9.GPIO_Pu=GPIO_PULLUP
|
||||
PB9.Locked=true
|
||||
PB9.Mode=I2C
|
||||
PB9.Signal=I2C1_SDA
|
||||
PC0.GPIOParameters=GPIO_Label
|
||||
PC0.GPIO_Label=HW0
|
||||
PC0.Locked=true
|
||||
PC0.Signal=GPIO_Input
|
||||
PC1.GPIOParameters=GPIO_Label
|
||||
PC1.GPIO_Label=HW1
|
||||
PC1.Locked=true
|
||||
PC1.Signal=GPIO_Input
|
||||
PC10.Locked=true
|
||||
PC10.Mode=Asynchronous
|
||||
PC10.Signal=USART3_TX
|
||||
PC11.Locked=true
|
||||
PC11.Mode=Asynchronous
|
||||
PC11.Signal=USART3_RX
|
||||
PC2.GPIOParameters=GPIO_Label
|
||||
PC2.GPIO_Label=HW2
|
||||
PC2.Locked=true
|
||||
PC2.Signal=GPIO_Input
|
||||
PC4.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
|
||||
PC4.GPIO_Label=ACCL_INT
|
||||
PC4.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
|
||||
PC4.GPIO_PuPd=GPIO_PULLUP
|
||||
PC4.Locked=true
|
||||
PC4.Signal=GPXTI4
|
||||
PC5.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
|
||||
PC5.GPIO_Label=GYRO_INT
|
||||
PC5.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
|
||||
PC5.GPIO_PuPd=GPIO_PULLUP
|
||||
PC5.Locked=true
|
||||
PC5.Signal=GPXTI5
|
||||
PC6.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PC6.GPIO_PuPd=GPIO_PULLUP
|
||||
PC6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PC6.Locked=true
|
||||
PC6.Signal=S_TIM8_CH1
|
||||
PC8.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PC8.GPIO_Label=LASER
|
||||
PC8.GPIO_PuPd=GPIO_PULLUP
|
||||
PC8.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PC8.Locked=true
|
||||
PC8.Signal=S_TIM3_CH3
|
||||
PC9.GPIOParameters=GPIO_Pu
|
||||
PC9.GPIO_Pu=GPIO_PULLUP
|
||||
PC9.Locked=true
|
||||
PC9.Mode=I2C
|
||||
PC9.Signal=I2C3_SDA
|
||||
PD0.Locked=true
|
||||
PD0.Mode=CAN_Activate
|
||||
PD0.Signal=CAN1_RX
|
||||
PD1.Locked=true
|
||||
PD1.Mode=CAN_Activate
|
||||
PD1.Signal=CAN1_TX
|
||||
PD14.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PD14.GPIO_Label=BUZZER
|
||||
PD14.GPIO_PuPd=GPIO_PULLUP
|
||||
PD14.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PD14.Locked=true
|
||||
PD14.Signal=S_TIM4_CH3
|
||||
PE11.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PE11.GPIO_PuPd=GPIO_PULLUP
|
||||
PE11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PE11.Locked=true
|
||||
PE11.Signal=S_TIM1_CH2
|
||||
PE13.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PE13.GPIO_PuPd=GPIO_PULLUP
|
||||
PE13.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PE13.Locked=true
|
||||
PE13.Signal=S_TIM1_CH3
|
||||
PE14.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PE14.GPIO_PuPd=GPIO_PULLUP
|
||||
PE14.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PE14.Locked=true
|
||||
PE14.Signal=S_TIM1_CH4
|
||||
PE9.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PE9.GPIO_PuPd=GPIO_PULLUP
|
||||
PE9.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PE9.Locked=true
|
||||
PE9.Signal=S_TIM1_CH1
|
||||
PF0.GPIOParameters=GPIO_Pu
|
||||
PF0.GPIO_Pu=GPIO_PULLUP
|
||||
PF0.Locked=true
|
||||
PF0.Mode=I2C
|
||||
PF0.Signal=I2C2_SDA
|
||||
PF1.GPIOParameters=GPIO_Pu
|
||||
PF1.GPIO_Pu=GPIO_PULLUP
|
||||
PF1.Locked=true
|
||||
PF1.Mode=I2C
|
||||
PF1.Signal=I2C2_SCL
|
||||
PF10.GPIOParameters=GPIO_Label
|
||||
PF10.GPIO_Label=ADC_BAT
|
||||
PF10.Locked=true
|
||||
PF10.Mode=IN8
|
||||
PF10.Signal=ADC3_IN8
|
||||
PF6.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PF6.GPIO_Label=IMU_HEAT_PWM
|
||||
PF6.GPIO_PuPd=GPIO_PULLDOWN
|
||||
PF6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PF6.Locked=true
|
||||
PF6.Signal=S_TIM10_CH1
|
||||
PG14.Locked=true
|
||||
PG14.Mode=Asynchronous
|
||||
PG14.Signal=USART6_TX
|
||||
PG3.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
|
||||
PG3.GPIO_Label=CMPS_INT
|
||||
PG3.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
|
||||
PG3.GPIO_PuPd=GPIO_PULLUP
|
||||
PG3.Locked=true
|
||||
PG3.Signal=GPXTI3
|
||||
PG6.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PG6.GPIO_Label=CMPS_RST
|
||||
PG6.GPIO_PuPd=GPIO_PULLUP
|
||||
PG6.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
|
||||
PG6.Locked=true
|
||||
PG6.PinState=GPIO_PIN_RESET
|
||||
PG6.Signal=GPIO_Output
|
||||
PG9.Locked=true
|
||||
PG9.Mode=Asynchronous
|
||||
PG9.Signal=USART6_RX
|
||||
PH0-OSC_IN.Mode=HSE-External-Oscillator
|
||||
PH0-OSC_IN.Signal=RCC_OSC_IN
|
||||
PH1-OSC_OUT.Mode=HSE-External-Oscillator
|
||||
PH1-OSC_OUT.Signal=RCC_OSC_OUT
|
||||
PH10.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PH10.GPIO_Label=LED_B
|
||||
PH10.GPIO_PuPd=GPIO_PULLUP
|
||||
PH10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PH10.Locked=true
|
||||
PH10.Signal=S_TIM5_CH1
|
||||
PH11.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PH11.GPIO_Label=LED_G
|
||||
PH11.GPIO_PuPd=GPIO_PULLUP
|
||||
PH11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PH11.Locked=true
|
||||
PH11.Signal=S_TIM5_CH2
|
||||
PH12.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label
|
||||
PH12.GPIO_Label=LED_R
|
||||
PH12.GPIO_PuPd=GPIO_PULLUP
|
||||
PH12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PH12.Locked=true
|
||||
PH12.Signal=S_TIM5_CH3
|
||||
PI6.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PI6.GPIO_PuPd=GPIO_PULLUP
|
||||
PI6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PI6.Signal=S_TIM8_CH2
|
||||
PinOutPanel.CurrentBGAView=Top
|
||||
PinOutPanel.RotationAngle=0
|
||||
ProjectManager.AskForMigrate=true
|
||||
ProjectManager.BackupPrevious=false
|
||||
ProjectManager.CompilerLinker=GCC
|
||||
ProjectManager.CompilerOptimize=6
|
||||
ProjectManager.ComputerToolchain=false
|
||||
ProjectManager.CoupleFile=true
|
||||
ProjectManager.CustomerFirmwarePackage=
|
||||
ProjectManager.DefaultFWLocation=true
|
||||
ProjectManager.DeletePrevious=true
|
||||
ProjectManager.DeviceId=STM32F407IGHx
|
||||
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.3
|
||||
ProjectManager.FreePins=false
|
||||
ProjectManager.HalAssertFull=true
|
||||
ProjectManager.HeapSize=0x1000
|
||||
ProjectManager.KeepUserCode=true
|
||||
ProjectManager.LastFirmware=true
|
||||
ProjectManager.LibraryCopy=0
|
||||
ProjectManager.MainLocation=Core/Src
|
||||
ProjectManager.NoMain=false
|
||||
ProjectManager.PreviousToolchain=
|
||||
ProjectManager.ProjectBuild=false
|
||||
ProjectManager.ProjectFileName=DevC.ioc
|
||||
ProjectManager.ProjectName=DevC
|
||||
ProjectManager.ProjectStructure=
|
||||
ProjectManager.RegisterCallBack=
|
||||
ProjectManager.StackSize=0x1000
|
||||
ProjectManager.TargetToolchain=CMake
|
||||
ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
ProjectManager.UAScriptBeforePath=
|
||||
ProjectManager.UnderRoot=false
|
||||
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_ADC3_Init-ADC3-false-HAL-true,6-MX_CAN1_Init-CAN1-false-HAL-true,7-MX_CAN2_Init-CAN2-false-HAL-true,8-MX_I2C1_Init-I2C1-false-HAL-true,9-MX_SPI1_Init-SPI1-false-HAL-true,10-MX_TIM4_Init-TIM4-false-HAL-true,11-MX_TIM5_Init-TIM5-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_TIM8_Init-TIM8-false-HAL-true,14-MX_CRC_Init-CRC-false-HAL-true,15-MX_RNG_Init-RNG-false-HAL-true,16-MX_I2C2_Init-I2C2-false-HAL-true,17-MX_I2C3_Init-I2C3-false-HAL-true,18-MX_SPI2_Init-SPI2-false-HAL-true,19-MX_TIM1_Init-TIM1-false-HAL-true,20-MX_TIM3_Init-TIM3-false-HAL-true,21-MX_TIM10_Init-TIM10-false-HAL-true,22-MX_USART1_UART_Init-USART1-false-HAL-true,23-MX_USART6_UART_Init-USART6-false-HAL-true,24-MX_TIM7_Init-TIM7-false-HAL-true,25-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false
|
||||
RCC.48MHZClocksFreq_Value=48000000
|
||||
RCC.AHBFreq_Value=168000000
|
||||
RCC.APB1CLKDivider=RCC_HCLK_DIV4
|
||||
RCC.APB1Freq_Value=42000000
|
||||
RCC.APB1TimFreq_Value=84000000
|
||||
RCC.APB2CLKDivider=RCC_HCLK_DIV2
|
||||
RCC.APB2Freq_Value=84000000
|
||||
RCC.APB2TimFreq_Value=168000000
|
||||
RCC.CortexFreq_Value=168000000
|
||||
RCC.EthernetFreq_Value=168000000
|
||||
RCC.FCLKCortexFreq_Value=168000000
|
||||
RCC.FamilyName=M
|
||||
RCC.HCLKFreq_Value=168000000
|
||||
RCC.HSE_VALUE=12000000
|
||||
RCC.HSI_VALUE=16000000
|
||||
RCC.I2SClocksFreq_Value=192000000
|
||||
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RCC_RTC_Clock_Source_FROM_HSE,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
|
||||
RCC.LSE_VALUE=32768
|
||||
RCC.LSI_VALUE=32000
|
||||
RCC.MCO2PinFreq_Value=168000000
|
||||
RCC.PLLCLKFreq_Value=168000000
|
||||
RCC.PLLM=6
|
||||
RCC.PLLN=168
|
||||
RCC.PLLQ=7
|
||||
RCC.PLLQCLKFreq_Value=48000000
|
||||
RCC.RCC_RTC_Clock_Source=RCC_RTCCLKSOURCE_LSI
|
||||
RCC.RCC_RTC_Clock_SourceVirtual=RCC_RTCCLKSOURCE_HSE_DIV30
|
||||
RCC.RCC_RTC_Clock_Source_FROM_HSE=RCC_RTCCLKSOURCE_HSE_DIV30
|
||||
RCC.RTCFreq_Value=32000
|
||||
RCC.RTCHSEDivFreq_Value=400000
|
||||
RCC.SYSCLKFreq_VALUE=168000000
|
||||
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
|
||||
RCC.VCOI2SOutputFreq_Value=384000000
|
||||
RCC.VCOInputFreq_Value=2000000
|
||||
RCC.VCOOutputFreq_Value=336000000
|
||||
RCC.VcooutputI2S=192000000
|
||||
SH.GPXTI0.0=GPIO_EXTI0
|
||||
SH.GPXTI0.ConfNb=1
|
||||
SH.GPXTI3.0=GPIO_EXTI3
|
||||
SH.GPXTI3.ConfNb=1
|
||||
SH.GPXTI4.0=GPIO_EXTI4
|
||||
SH.GPXTI4.ConfNb=1
|
||||
SH.GPXTI5.0=GPIO_EXTI5
|
||||
SH.GPXTI5.ConfNb=1
|
||||
SH.S_TIM10_CH1.0=TIM10_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM10_CH1.ConfNb=1
|
||||
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM1_CH1.ConfNb=1
|
||||
SH.S_TIM1_CH2.0=TIM1_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM1_CH2.ConfNb=1
|
||||
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM1_CH3.ConfNb=1
|
||||
SH.S_TIM1_CH4.0=TIM1_CH4,PWM Generation4 CH4
|
||||
SH.S_TIM1_CH4.ConfNb=1
|
||||
SH.S_TIM3_CH3.0=TIM3_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM3_CH3.ConfNb=1
|
||||
SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM4_CH3.ConfNb=1
|
||||
SH.S_TIM5_CH1.0=TIM5_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM5_CH1.ConfNb=1
|
||||
SH.S_TIM5_CH2.0=TIM5_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM5_CH2.ConfNb=1
|
||||
SH.S_TIM5_CH3.0=TIM5_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM5_CH3.ConfNb=1
|
||||
SH.S_TIM8_CH1.0=TIM8_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM8_CH1.ConfNb=1
|
||||
SH.S_TIM8_CH2.0=TIM8_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM8_CH2.ConfNb=1
|
||||
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16
|
||||
SPI1.CLKPhase=SPI_PHASE_2EDGE
|
||||
SPI1.CLKPolarity=SPI_POLARITY_HIGH
|
||||
SPI1.CalculateBaudRate=5.25 MBits/s
|
||||
SPI1.Direction=SPI_DIRECTION_2LINES
|
||||
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
|
||||
SPI1.Mode=SPI_MODE_MASTER
|
||||
SPI1.VirtualType=VM_MASTER
|
||||
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64
|
||||
SPI2.CLKPhase=SPI_PHASE_1EDGE
|
||||
SPI2.CLKPolarity=SPI_POLARITY_LOW
|
||||
SPI2.CalculateBaudRate=656.25 KBits/s
|
||||
SPI2.Direction=SPI_DIRECTION_2LINES
|
||||
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
|
||||
SPI2.Mode=SPI_MODE_MASTER
|
||||
SPI2.VirtualType=VM_MASTER
|
||||
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM1.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
|
||||
TIM1.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,Period,Prescaler,Pulse-PWM Generation1 CH1,Pulse-PWM Generation2 CH2,Pulse-PWM Generation3 CH3,Pulse-PWM Generation4 CH4
|
||||
TIM1.Period=19999
|
||||
TIM1.Prescaler=167
|
||||
TIM1.Pulse-PWM\ Generation1\ CH1=0
|
||||
TIM1.Pulse-PWM\ Generation2\ CH2=0
|
||||
TIM1.Pulse-PWM\ Generation3\ CH3=0
|
||||
TIM1.Pulse-PWM\ Generation4\ CH4=1000
|
||||
TIM10.Channel=TIM_CHANNEL_1
|
||||
TIM10.IPParameters=Channel,Period
|
||||
TIM10.Period=4999
|
||||
TIM3.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM3.IPParameters=Channel-PWM Generation3 CH3,Period
|
||||
TIM3.Period=65535
|
||||
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM4.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period
|
||||
TIM4.Period=65535
|
||||
TIM4.Prescaler=167
|
||||
TIM5.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM5.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM5.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
|
||||
TIM5.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Prescaler,Period
|
||||
TIM5.Period=65535
|
||||
TIM5.Prescaler=0
|
||||
TIM7.IPParameters=Period,Prescaler
|
||||
TIM7.Period=9
|
||||
TIM7.Prescaler=83
|
||||
TIM8.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM8.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM8.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Prescaler,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation2 CH2
|
||||
TIM8.Period=19999
|
||||
TIM8.Prescaler=167
|
||||
TIM8.Pulse-PWM\ Generation1\ CH1=1000
|
||||
TIM8.Pulse-PWM\ Generation2\ CH2=1000
|
||||
USART1.IPParameters=VirtualMode
|
||||
USART1.VirtualMode=VM_ASYNC
|
||||
USART3.BaudRate=100000
|
||||
USART3.IPParameters=VirtualMode,BaudRate,Parity,Mode
|
||||
USART3.Mode=MODE_RX
|
||||
USART3.Parity=PARITY_EVEN
|
||||
USART3.VirtualMode=VM_ASYNC
|
||||
USART6.IPParameters=VirtualMode
|
||||
USART6.VirtualMode=VM_ASYNC
|
||||
USB_DEVICE.CLASS_NAME_FS=CDC
|
||||
USB_DEVICE.IPParameters=VirtualMode-CDC_FS,VirtualModeFS,CLASS_NAME_FS
|
||||
USB_DEVICE.VirtualMode-CDC_FS=Cdc
|
||||
USB_DEVICE.VirtualModeFS=Cdc_FS
|
||||
USB_OTG_FS.IPParameters=VirtualMode
|
||||
USB_OTG_FS.VirtualMode=Device_Only
|
||||
VP_ADC1_TempSens_Input.Mode=IN-TempSens
|
||||
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
|
||||
VP_ADC1_Vref_Input.Mode=IN-Vrefint
|
||||
VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
|
||||
VP_CRC_VS_CRC.Mode=CRC_Activate
|
||||
VP_CRC_VS_CRC.Signal=CRC_VS_CRC
|
||||
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
||||
VP_RNG_VS_RNG.Mode=RNG_Activate
|
||||
VP_RNG_VS_RNG.Signal=RNG_VS_RNG
|
||||
VP_SYS_VS_Systick.Mode=SysTick
|
||||
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
||||
VP_TIM10_VS_ClockSourceINT.Mode=Enable_Timer
|
||||
VP_TIM10_VS_ClockSourceINT.Signal=TIM10_VS_ClockSourceINT
|
||||
VP_TIM1_VS_ClockSourceINT.Mode=Internal
|
||||
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
|
||||
VP_TIM3_VS_ClockSourceINT.Mode=Internal
|
||||
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
|
||||
VP_TIM4_VS_ClockSourceINT.Mode=Internal
|
||||
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
|
||||
VP_TIM5_VS_ClockSourceINT.Mode=Internal
|
||||
VP_TIM5_VS_ClockSourceINT.Signal=TIM5_VS_ClockSourceINT
|
||||
VP_TIM7_VS_ClockSourceINT.Mode=Enable_Timer
|
||||
VP_TIM7_VS_ClockSourceINT.Signal=TIM7_VS_ClockSourceINT
|
||||
VP_TIM8_VS_ClockSourceINT.Mode=Internal
|
||||
VP_TIM8_VS_ClockSourceINT.Signal=TIM8_VS_ClockSourceINT
|
||||
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
|
||||
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
board=custom
|
||||
rtos.0.ip=FREERTOS
|
||||
96
task/template_task/atti_esti.c
Normal file
96
task/template_task/atti_esti.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
atti_esti Task
|
||||
带有pwm温控的纯陀螺仪(BMI088)姿态解算任务(无磁力计,赛场环境一般不适用)。
|
||||
控制IMU加热到指定温度防止温漂,收集IMU数据给AHRS算法。
|
||||
收集BMI088的数据,解算后得到四元数,转换为欧拉角之后放到消息队列中,
|
||||
等待其他任务取用。
|
||||
陀螺仪使用前需要校准,校准结果保存在bmi088_cali结构体中,需要自行实现。
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "task/user_task.h"
|
||||
/* USER INCLUDE BEGIN */
|
||||
|
||||
#include "bsp/mm.h"
|
||||
#include "bsp/pwm.h"
|
||||
#include "component/ahrs.h"
|
||||
#include "component/pid.h"
|
||||
#include "device/bmi088.h"
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
/* USER STRUCT BEGIN */
|
||||
BMI088_t bmi088;
|
||||
AHRS_t gimbal_ahrs;
|
||||
AHRS_Magn_t magn;
|
||||
AHRS_Eulr_t eulr_to_send;
|
||||
KPID_t imu_temp_ctrl_pid;
|
||||
|
||||
/*默认校准参数*/
|
||||
BMI088_Cali_t cali_bmi088 = {
|
||||
.gyro_offset = {0.0f, 0.0f, 0.0f},
|
||||
};
|
||||
|
||||
static const KPID_Params_t imu_temp_ctrl_pid_param = {
|
||||
.k = 0.15f,
|
||||
.p = 1.0f,
|
||||
.i = 0.0f,
|
||||
.d = 0.0f,
|
||||
.i_limit = 1.0f,
|
||||
.out_limit = 1.0f,
|
||||
};
|
||||
|
||||
/* USER STRUCT END */
|
||||
|
||||
/* Private function --------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void Task_atti_esti(void *argument) {
|
||||
(void)argument; /* 未使用argument,消除警告 */
|
||||
|
||||
|
||||
osDelay(ATTI_ESTI_INIT_DELAY); /* 延时一段时间再开启任务 */
|
||||
|
||||
/* USER CODE INIT BEGIN */
|
||||
BMI088_Init(&bmi088, &cali_bmi088);
|
||||
AHRS_Init(&gimbal_ahrs, &magn, BMI088_GetUpdateFreq(&bmi088));
|
||||
PID_Init(&imu_temp_ctrl_pid, KPID_MODE_NO_D,
|
||||
1.0f / BMI088_GetUpdateFreq(&bmi088), &imu_temp_ctrl_pid_param);
|
||||
BSP_PWM_Start(BSP_PWM_IMU_HEAT);
|
||||
|
||||
/* USER CODE INIT END */
|
||||
|
||||
while (1) {
|
||||
/* USER CODE BEGIN */
|
||||
BMI088_WaitNew();
|
||||
BMI088_AcclStartDmaRecv();
|
||||
BMI088_AcclWaitDmaCplt();
|
||||
|
||||
BMI088_GyroStartDmaRecv();
|
||||
BMI088_GyroWaitDmaCplt();
|
||||
|
||||
/* 锁住RTOS内核防止数据解析过程中断,造成错误 */
|
||||
osKernelLock();
|
||||
/* 接收完所有数据后,把数据从原始字节加工成方便计算的数据 */
|
||||
BMI088_ParseAccl(&bmi088);
|
||||
BMI088_ParseGyro(&bmi088);
|
||||
|
||||
/* 根据设备接收到的数据进行姿态解析 */
|
||||
AHRS_Update(&gimbal_ahrs, &bmi088.accl, &bmi088.gyro, &magn);
|
||||
|
||||
/* 根据解析出来的四元数计算欧拉角 */
|
||||
AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs);
|
||||
osKernelUnlock();
|
||||
|
||||
/* 在此处用消息队列传递imu数据 */
|
||||
/* osMessageQueuePut( ... ); */
|
||||
|
||||
/* 控制IMU加热器 */
|
||||
BSP_PWM_SetComp(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.5f,
|
||||
bmi088.temp, 0.0f, 0.0f));
|
||||
/* USER CODE END */
|
||||
}
|
||||
|
||||
}
|
||||
18
task/template_task/task.yaml
Normal file
18
task/template_task/task.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
atti_esti:
|
||||
name: "atti_esti"
|
||||
frequency: 1000
|
||||
delay: 100
|
||||
stack: 512
|
||||
freq_control: false
|
||||
description: |
|
||||
带有PWM温控的纯陀螺仪(BMI088)姿态解算任务
|
||||
功能特点:
|
||||
- 控制IMU加热到指定温度防止温漂
|
||||
- 收集BMI088数据给AHRS算法进行姿态解算
|
||||
- 解算后得到四元数,转换为欧拉角放到消息队列
|
||||
- 使用PID控制IMU温度到40.5°C
|
||||
- 运行频率1000Hz,提供高精度姿态信息
|
||||
注意事项:
|
||||
- 陀螺仪使用前需要校准,校准结果保存在bmi088_cali结构体中
|
||||
- 无磁力计版本,适用于干净的电磁环境
|
||||
- 需要配置PWM通道用于IMU加热控制
|
||||
Loading…
Reference in New Issue
Block a user