feat(CAN): 添加静默模式支持并优化节点ID处理
- 添加静默模式功能,在接收到base_id=0x0000消息时停止发送10秒 - 修正节点ID加载逻辑,区分有效节点ID(0-65534)和Flash擦除状态(0xFFFF) - 添加静默模式相关的状态检查和时间管理功能 - 在CAN通信检查中集成静默模式处理流程 fix(FOC): 修复速度控制中的方向参数应用 - 在velocity_control、angle_control_with_velocity_limit和MIT_Mode函数中 正确应用DIR参数调整速度误差的符号 - 添加详细注释说明DIR参数对速度误差计算的影响 refactor(systick): 添加毫秒级系统时间功能 - 实现get_systick_ms()函数提供毫秒级系统时间 - 添加SysTick中断处理程序更新系统时间计数器 chore(init): 调整初始化顺序优化系统启动流程 - 将EEPROM初始化移至CAN初始化之前,确保正确的依赖关系
This commit is contained in:
@@ -367,8 +367,10 @@ float FOC_Controller::angle_control() {
|
|||||||
* @return float: 当前速度
|
* @return float: 当前速度
|
||||||
*/
|
*/
|
||||||
float FOC_Controller::velocity_control() {
|
float FOC_Controller::velocity_control() {
|
||||||
// PID 控制计算
|
// PID 控制计算,使用 DIR 参数调整速度误差的符号
|
||||||
float Uq = vel_loop((target_velocity - rt_velocity) * REDUCTION_RATIO);
|
// DIR = -1.0f 时:速度误差 = -(target_velocity - rt_velocity) = rt_velocity - target_velocity
|
||||||
|
// DIR = 1.0f 时:速度误差 = target_velocity - rt_velocity
|
||||||
|
float Uq = vel_loop((target_velocity - rt_velocity) * DIR * REDUCTION_RATIO);
|
||||||
CAN0_transmiter.testfloat_union.f = Uq;
|
CAN0_transmiter.testfloat_union.f = Uq;
|
||||||
|
|
||||||
// 获取电机轴角度
|
// 获取电机轴角度
|
||||||
@@ -424,7 +426,7 @@ float FOC_Controller::angle_control_with_velocity_limit() {
|
|||||||
} else {
|
} else {
|
||||||
vel_inVelAngloop.set_P(vel_angloop_p);
|
vel_inVelAngloop.set_P(vel_angloop_p);
|
||||||
}
|
}
|
||||||
float Uq = vel_inVelAngloop(target_velocity - rt_velocity);
|
float Uq = vel_inVelAngloop(target_velocity - rt_velocity)* DIR;
|
||||||
CAN0_transmiter.testfloat_union.f = Uq;
|
CAN0_transmiter.testfloat_union.f = Uq;
|
||||||
|
|
||||||
// // 实现力度控制:如果电流超过目标电流,则限制输出
|
// // 实现力度控制:如果电流超过目标电流,则限制输出
|
||||||
@@ -465,7 +467,7 @@ float FOC_Controller::MIT_Mode() {
|
|||||||
|
|
||||||
// 第二层:速度环(中环)
|
// 第二层:速度环(中环)
|
||||||
// 根据目标速度和实际速度的差值,通过速度环PID控制器计算目标电流
|
// 根据目标速度和实际速度的差值,通过速度环PID控制器计算目标电流
|
||||||
float velocity_error = (rt_velocity - target_velocity);
|
float velocity_error = (target_velocity - rt_velocity)* DIR;
|
||||||
vel_inMITloop.set_P(vel_MIT_p);
|
vel_inMITloop.set_P(vel_MIT_p);
|
||||||
float target_current = vel_inMITloop(velocity_error);
|
float target_current = vel_inMITloop(velocity_error);
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void adc_config(void) {
|
|||||||
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 6);
|
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 6);
|
||||||
/* 配置ADC规则通道 */
|
/* 配置ADC规则通道 */
|
||||||
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16,
|
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16,
|
||||||
ADC_SAMPLETIME_55POINT5);
|
ADC_SAMPLETIME_41POINT5);
|
||||||
adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_28POINT5);
|
adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_28POINT5);
|
||||||
adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_28POINT5);
|
adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_28POINT5);
|
||||||
adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_28POINT5);
|
adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_28POINT5);
|
||||||
|
|||||||
+79
-22
@@ -33,6 +33,7 @@ extern EncoderAngleKalman Angle_kalman; // 角度滤波
|
|||||||
extern EncoderVelocityKalman Vel_kalman; // 速度滤波
|
extern EncoderVelocityKalman Vel_kalman; // 速度滤波
|
||||||
extern FlashEEPROM flashEEP;
|
extern FlashEEPROM flashEEP;
|
||||||
extern VersionManager Version; // 声明外部版本管理器实例
|
extern VersionManager Version; // 声明外部版本管理器实例
|
||||||
|
extern u32 motor_runtime_50us; // 电机驱动计算轮次(用于静默模式计时)
|
||||||
|
|
||||||
// 添加 DMA 相关变量
|
// 添加 DMA 相关变量
|
||||||
dma_parameter_struct dma_rx_parameter;
|
dma_parameter_struct dma_rx_parameter;
|
||||||
@@ -105,16 +106,17 @@ void CAN_transmiter::set_node_id(u16 new_id) {
|
|||||||
\retval FLASH_EEPROM_OK: 加载成功
|
\retval FLASH_EEPROM_OK: 加载成功
|
||||||
其他:加载失败,使用默认值
|
其他:加载失败,使用默认值
|
||||||
\note Flash 擦除状态为 0xFFFF,需要特殊处理避免误判
|
\note Flash 擦除状态为 0xFFFF,需要特殊处理避免误判
|
||||||
|
注意:0 是有效的节点 ID,不应被视为无效值
|
||||||
*/
|
*/
|
||||||
u8 CAN_transmiter::load_node_id_from_flash() {
|
u8 CAN_transmiter::load_node_id_from_flash() {
|
||||||
u16 node_id_temp = 0xFFFF; // 初始化为 Flash 擦除值
|
u16 node_id_temp = 0xFFFF; // 初始化为 Flash 擦除值
|
||||||
FlashEepromStatus status =
|
FlashEepromStatus status =
|
||||||
flashEEP.read(FlashEEPROM::ADDR_NODE_ID, &node_id_temp);
|
flashEEP.read(FlashEEPROM::ADDR_NODE_ID, &node_id_temp);
|
||||||
|
|
||||||
// 检查 Flash 是否为擦除状态 (0xFFFF 或 0) 或读取失败
|
// 检查 Flash 是否为擦除状态 (0xFFFF) 或读取失败
|
||||||
// 注意:Flash 未写入时读到的值是 0xFFFF,但有些情况可能读到 0
|
// 注意:Flash 未写入时读到的值是 0xFFFF
|
||||||
if (status != FLASH_EEPROM_OK || node_id_temp == 0xFFFF ||
|
// 0 是有效的节点 ID,不应被视为无效值
|
||||||
node_id_temp == 0) {
|
if (status != FLASH_EEPROM_OK || node_id_temp == 0xFFFF) {
|
||||||
node_id = DEFAULT_NODE_ID;
|
node_id = DEFAULT_NODE_ID;
|
||||||
CAN_DEBUG_PRINT(
|
CAN_DEBUG_PRINT(
|
||||||
"Node ID not found in Flash (status=%d, val=0x%04X), using "
|
"Node ID not found in Flash (status=%d, val=0x%04X), using "
|
||||||
@@ -123,7 +125,7 @@ u8 CAN_transmiter::load_node_id_from_flash() {
|
|||||||
return FLASH_EEPROM_DATA_NOT_FOUND;
|
return FLASH_EEPROM_DATA_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查节点 ID 是否有效
|
// 检查节点 ID 是否有效 (0-65534 都是有效值)
|
||||||
if (node_id_temp <= MAX_NODE_ID) {
|
if (node_id_temp <= MAX_NODE_ID) {
|
||||||
node_id = node_id_temp;
|
node_id = node_id_temp;
|
||||||
CAN_DEBUG_PRINT("Node ID loaded from Flash: %d\r\n", node_id);
|
CAN_DEBUG_PRINT("Node ID loaded from Flash: %d\r\n", node_id);
|
||||||
@@ -203,6 +205,37 @@ bool CAN_transmiter::dequeue_rx_message(can_receive_message_struct &message) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 静默模式相关函数实现
|
||||||
|
// 使用 systick 获取系统时间(ms)
|
||||||
|
extern u32 get_systick_ms(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief 进入静默模式(停发 10 秒)
|
||||||
|
*/
|
||||||
|
void CAN_transmiter::enter_silent_mode() {
|
||||||
|
is_silent = true;
|
||||||
|
silent_start_time = get_systick_ms(); // 记录当前时间(ms)
|
||||||
|
CAN_DEBUG_PRINT("Enter silent mode for %d ms, start_time=%d\r\n", CAN_SILENT_DURATION_MS, silent_start_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief 检查是否在静默模式中
|
||||||
|
*/
|
||||||
|
bool CAN_transmiter::is_in_silent_mode() { return is_silent; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief 检查静默模式是否结束
|
||||||
|
*/
|
||||||
|
void CAN_transmiter::check_silent_mode() {
|
||||||
|
if (is_silent) {
|
||||||
|
u32 current_time = get_systick_ms(); // 当前时间(ms)
|
||||||
|
if (current_time - silent_start_time >= CAN_SILENT_DURATION_MS) {
|
||||||
|
is_silent = false;
|
||||||
|
CAN_DEBUG_PRINT("Exit silent mode, elapsed=%d ms\r\n", current_time - silent_start_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief initialize CAN GPIO
|
\brief initialize CAN GPIO
|
||||||
\param[in] none
|
\param[in] none
|
||||||
@@ -645,10 +678,16 @@ void CAN_transmiter::update(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CANFD 发送函数
|
* @brief CANFD 发送函数
|
||||||
* @retval 0: 发送失败
|
* @retval 0: 发送失败(或处于静默模式)
|
||||||
* 1: 发送成功
|
* 1: 发送成功
|
||||||
*/
|
*/
|
||||||
u8 CAN_transmiter::CANFD_all_Send() {
|
u8 CAN_transmiter::CANFD_all_Send() {
|
||||||
|
// 检查是否在静默模式中,如果是则不发送
|
||||||
|
if (is_in_silent_mode()) {
|
||||||
|
check_silent_mode(); // 检查是否已退出静默
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
u32 success_flag = 0;
|
u32 success_flag = 0;
|
||||||
|
|
||||||
// 打包 status 数据 - 只清零实际使用的 32 字节
|
// 打包 status 数据 - 只清零实际使用的 32 字节
|
||||||
@@ -694,11 +733,13 @@ u8 CAN_transmiter::CANFD_all_Send() {
|
|||||||
void CAN_transmiter::communication_check() {
|
void CAN_transmiter::communication_check() {
|
||||||
// CAN0 发送数据标志
|
// CAN0 发送数据标志
|
||||||
if (SET == can0_send_flag) {
|
if (SET == can0_send_flag) {
|
||||||
// CAN_DEBUG_PRINT("\r\n can0 %X receive data:",
|
// 检查是否在静默模式中
|
||||||
// receive_message.rx_efid);
|
if (!is_in_silent_mode()) {
|
||||||
update();
|
update();
|
||||||
// CAN0_transmiter.CAN_all_Send();
|
CANFD_all_Send();
|
||||||
CANFD_all_Send();
|
} else {
|
||||||
|
check_silent_mode(); // 检查静默是否结束
|
||||||
|
}
|
||||||
can0_send_flag = RESET;
|
can0_send_flag = RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,14 +750,37 @@ void CAN_transmiter::communication_check() {
|
|||||||
// current_message.rx_efid); for (i = 0; i < current_message.rx_dlen;
|
// current_message.rx_efid); for (i = 0; i < current_message.rx_dlen;
|
||||||
// i++) { CAN_DEBUG_PRINT(" %02x", current_message.rx_data[i]);
|
// i++) { CAN_DEBUG_PRINT(" %02x", current_message.rx_data[i]);
|
||||||
// }
|
// }
|
||||||
// 检查消息是否是发给本节点的 (检查高 16 位)
|
// 提取基础 ID (低 16 位,去除高 16 位节点 ID 部分)
|
||||||
|
u32 base_id = current_message.rx_efid & 0xFFFF;
|
||||||
|
|
||||||
|
// 提取发送方的节点 ID
|
||||||
|
u16 sender_node_id = (u16)((current_message.rx_efid >> 16) & 0xFFFF);
|
||||||
|
|
||||||
|
// 特殊处理 base_id=0x0000(BOOT 命令):即使是其他节点的广播消息也要处理
|
||||||
|
if (base_id == CANFD_BOOT_ID) {
|
||||||
|
// 判断是广播消息还是其他节点的命令
|
||||||
|
if (sender_node_id == BROADCAST_NODE_ID || sender_node_id != node_id) {
|
||||||
|
// 广播消息或其他节点的命令 → 进入静默模式(停发 10 秒)
|
||||||
|
CAN_DEBUG_PRINT("Received base_id=0x0000 from node %d, entering silent mode for 10s\r\n", sender_node_id);
|
||||||
|
enter_silent_mode();
|
||||||
|
} else {
|
||||||
|
// 自己节点的命令 → 执行 BOOT 功能
|
||||||
|
CAN_DEBUG_PRINT("Received base_id=0x0000 from self, jumping to BOOT\r\n");
|
||||||
|
motor_sleep();
|
||||||
|
flashEEP.save_system_config(false);
|
||||||
|
fmc_unlock();
|
||||||
|
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_NOT_AVAL); // 设置 APP 为不激活
|
||||||
|
fmc_lock();
|
||||||
|
jumpToBOOT();
|
||||||
|
}
|
||||||
|
continue; // BOOT 命令处理完跳过后续逻辑
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他 base_id 的消息,检查是否是发给本节点的
|
||||||
if (!is_message_for_me(current_message.rx_efid)) {
|
if (!is_message_for_me(current_message.rx_efid)) {
|
||||||
continue; // 不是发给本节点的消息,跳过
|
continue; // 不是发给本节点的消息,跳过
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提取基础 ID (低 16 位,去除高 16 位节点 ID 部分)
|
|
||||||
u32 base_id = current_message.rx_efid & 0xFFFF;
|
|
||||||
|
|
||||||
if (base_id == CANFD_CMD_ID) {
|
if (base_id == CANFD_CMD_ID) {
|
||||||
// 控制模式
|
// 控制模式
|
||||||
FOC.control_mode = current_message.rx_data[0];
|
FOC.control_mode = current_message.rx_data[0];
|
||||||
@@ -787,13 +851,6 @@ void CAN_transmiter::communication_check() {
|
|||||||
} else if (base_id == CANFD_VERSION_ID) {
|
} else if (base_id == CANFD_VERSION_ID) {
|
||||||
// 处理版本号请求,发送当前系统版本信息
|
// 处理版本号请求,发送当前系统版本信息
|
||||||
Version.sendVersionInfoViaCan();
|
Version.sendVersionInfoViaCan();
|
||||||
} else if (base_id == CANFD_BOOT_ID) {
|
|
||||||
motor_sleep();
|
|
||||||
flashEEP.save_system_config(false);
|
|
||||||
fmc_unlock();
|
|
||||||
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_NOT_AVAL); // 设置 APP 为不激活
|
|
||||||
fmc_lock();
|
|
||||||
jumpToBOOT();
|
|
||||||
} else if (base_id == CANFD_OTA_ACK_ID) {
|
} else if (base_id == CANFD_OTA_ACK_ID) {
|
||||||
volatile u32 *flash_ptr = (volatile u32 *)n_APP_LATEST_EN_ADDR;
|
volatile u32 *flash_ptr = (volatile u32 *)n_APP_LATEST_EN_ADDR;
|
||||||
u32 app_enable = *flash_ptr;
|
u32 app_enable = *flash_ptr;
|
||||||
|
|||||||
@@ -73,8 +73,11 @@ class CAN_transmiter {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t CAN_RX_BUFFER_SIZE = 8; // CAN 接收缓冲区大小
|
static const uint8_t CAN_RX_BUFFER_SIZE = 8; // CAN 接收缓冲区大小
|
||||||
|
static const u32 CAN_SILENT_DURATION_MS = 10000; // CAN 静默时长 10 秒
|
||||||
|
|
||||||
bool is_sleep = false; // 是否休眠
|
bool is_sleep = false; // 是否休眠
|
||||||
|
bool is_silent = false; // 是否静默(收到 base_id=0x0000 后进入静默)
|
||||||
|
u32 silent_start_time = 0; // 静默开始时间(ms)
|
||||||
|
|
||||||
u16 node_id; // 本节点 ID(0-254),使用 CAN ID 高 8 位存储 (在 init() 中初始化为 DEFAULT_NODE_ID)
|
u16 node_id; // 本节点 ID(0-254),使用 CAN ID 高 8 位存储 (在 init() 中初始化为 DEFAULT_NODE_ID)
|
||||||
u8 Target_Control_Mode = 0; // 目标控制模式
|
u8 Target_Control_Mode = 0; // 目标控制模式
|
||||||
@@ -115,6 +118,7 @@ class CAN_transmiter {
|
|||||||
bool is_rx_buffer_full();
|
bool is_rx_buffer_full();
|
||||||
bool is_rx_buffer_empty();
|
bool is_rx_buffer_empty();
|
||||||
bool dequeue_rx_message(can_receive_message_struct& message);
|
bool dequeue_rx_message(can_receive_message_struct& message);
|
||||||
|
void check_silent_mode(); // 检查静默模式是否结束
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 节点 ID 相关辅助函数 (使用高 16 位存储节点 ID)
|
// 节点 ID 相关辅助函数 (使用高 16 位存储节点 ID)
|
||||||
@@ -139,6 +143,8 @@ class CAN_transmiter {
|
|||||||
u8 CANFD_AsyncSend(u32 ID, u8 length, u8 *data); // CANFD 异步发送 (使用 DMA)
|
u8 CANFD_AsyncSend(u32 ID, u8 length, u8 *data); // CANFD 异步发送 (使用 DMA)
|
||||||
u8 CAN_all_Send(); // CAN 发送
|
u8 CAN_all_Send(); // CAN 发送
|
||||||
u8 CANFD_all_Send(); // CANFD 发送
|
u8 CANFD_all_Send(); // CANFD 发送
|
||||||
|
void enter_silent_mode(); // 进入静默模式(停发 10 秒)
|
||||||
|
bool is_in_silent_mode(); // 检查是否在静默模式中
|
||||||
|
|
||||||
// 节点 ID 管理接口
|
// 节点 ID 管理接口
|
||||||
u16 get_node_id(); // 获取当前节点 ID
|
u16 get_node_id(); // 获取当前节点 ID
|
||||||
|
|||||||
+4
-5
@@ -78,13 +78,12 @@ u8 hardware_init(void) {
|
|||||||
init_status += KTH7823.init(); // 角度传感器初始化
|
init_status += KTH7823.init(); // 角度传感器初始化
|
||||||
init_status += sampler.init(); // 采样器初始化
|
init_status += sampler.init(); // 采样器初始化
|
||||||
|
|
||||||
// 先初始化 CAN,确保节点 ID 被正确设置
|
// EEPROM 初始化 (必须在 CAN 初始化之前,因为 CAN 会从 Flash 读取节点 ID)
|
||||||
// CAN 初始化会先设置默认节点 ID,然后从 Flash 加载
|
|
||||||
init_status += CAN0_transmiter.init(); // CAN 初始化
|
|
||||||
|
|
||||||
// EEPROM 初始化 (必须在 CAN 初始化之后,因为会读取节点 ID)
|
|
||||||
flashEEP.init(); // EEPROM 初始化
|
flashEEP.init(); // EEPROM 初始化
|
||||||
|
|
||||||
|
// CAN 初始化 (会先设置默认节点 ID,然后从 Flash 加载已保存的节点 ID)
|
||||||
|
init_status += CAN0_transmiter.init(); // CAN 初始化
|
||||||
|
|
||||||
init_status += Angle_kalman.init(KTH7823.getAngle()); // 角度滤波初始化
|
init_status += Angle_kalman.init(KTH7823.getAngle()); // 角度滤波初始化
|
||||||
init_status += Vel_kalman.init(0.0f); // 速度滤波初始化
|
init_status += Vel_kalman.init(0.0f); // 速度滤波初始化
|
||||||
init_status += FOC.init(); // FOC 初始化
|
init_status += FOC.init(); // FOC 初始化
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
// 版本号定义 - 可根据实际项目进行调整
|
// 版本号定义 - 可根据实际项目进行调整
|
||||||
constexpr u16 SOFTWARE_VERSION_MAJOR = 26;
|
constexpr u16 SOFTWARE_VERSION_MAJOR = 26;
|
||||||
constexpr u16 SOFTWARE_VERSION_MINOR = 3;
|
constexpr u16 SOFTWARE_VERSION_MINOR = 3;
|
||||||
constexpr u16 SOFTWARE_VERSION_PATCH = 15;
|
constexpr u16 SOFTWARE_VERSION_PATCH = 16;
|
||||||
constexpr u16 SOFTWARE_VERSION_BUILD = 4;
|
constexpr u16 SOFTWARE_VERSION_BUILD = 2;
|
||||||
|
|
||||||
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
|
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
|
||||||
constexpr u16 HARDWARE_VERSION_MINOR = 12;
|
constexpr u16 HARDWARE_VERSION_MINOR = 12;
|
||||||
@@ -64,7 +64,7 @@ constexpr u32 OTA_AVAL = 0x00000000; // 全零表示可用
|
|||||||
|
|
||||||
// 参数配置
|
// 参数配置
|
||||||
constexpr u8 PP = 11;
|
constexpr u8 PP = 11;
|
||||||
constexpr float DIR = -1.0f;
|
constexpr float DIR = 1.0f; // 默认方向:-1.0f 反转,1.0f 正转
|
||||||
constexpr u16 REDUCTION_RATIO = 25;
|
constexpr u16 REDUCTION_RATIO = 25;
|
||||||
constexpr float CURRENT_OFFSET = -3.31f / 2.0f; // 当前电流传感器的零点偏移
|
constexpr float CURRENT_OFFSET = -3.31f / 2.0f; // 当前电流传感器的零点偏移
|
||||||
constexpr float HOLD_PWM_DUTY = 0.1f;
|
constexpr float HOLD_PWM_DUTY = 0.1f;
|
||||||
|
|||||||
@@ -165,7 +165,9 @@ FlashEepromStatus FlashEEPROM::read(u8 virtualAddr, u16 *data) const {
|
|||||||
u8 addr = (u8)(data_word & DATA_ADDR_MASK);
|
u8 addr = (u8)(data_word & DATA_ADDR_MASK);
|
||||||
// 找到匹配的虚拟地址
|
// 找到匹配的虚拟地址
|
||||||
if (addr == virtualAddr) {
|
if (addr == virtualAddr) {
|
||||||
*data = (u16)(data_word & DATA_U16_MASK);
|
// 右移 16 位以提取高 16 位的 u16 数据
|
||||||
|
*data = (u16)((data_word & DATA_U16_MASK) >> 16);
|
||||||
|
EEP_DEBUG_PRINT("read u16: addr=0x%x, val=%d\r\n", address, *data);
|
||||||
return FLASH_EEPROM_OK;
|
return FLASH_EEPROM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile static uint32_t delay;
|
volatile static uint32_t delay;
|
||||||
|
volatile static uint32_t systick_ms = 0; // 系统运行时间(毫秒)
|
||||||
extern CAN_transmiter CAN0_transmiter;
|
extern CAN_transmiter CAN0_transmiter;
|
||||||
extern FlashEEPROM flashEEP;
|
extern FlashEEPROM flashEEP;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief get system tick time in milliseconds
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval system time in ms
|
||||||
|
*/
|
||||||
|
uint32_t get_systick_ms(void) {
|
||||||
|
return systick_ms;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief configure systick
|
\brief configure systick
|
||||||
\param[in] none
|
\param[in] none
|
||||||
@@ -71,6 +82,17 @@ void systick_config(void) {
|
|||||||
/* configure the systick handler priority */
|
/* configure the systick handler priority */
|
||||||
NVIC_SetPriority(SysTick_IRQn, 0x00U);
|
NVIC_SetPriority(SysTick_IRQn, 0x00U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief SysTick handler - increment millisecond counter
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
extern "C" void SysTick_Handler(void) {
|
||||||
|
systick_ms++; // 递增系统时间
|
||||||
|
delay_decrement(); // 递减延时计数器
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
\brief delay a time in seconds
|
\brief delay a time in seconds
|
||||||
\param[in] count: count in seconds
|
\param[in] count: count in seconds
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* configure systick */
|
/* configure systick */
|
||||||
void systick_config(void);
|
void systick_config(void);
|
||||||
|
/* get system tick time in milliseconds */
|
||||||
|
uint32_t get_systick_ms(void);
|
||||||
/* delay a time in milliseconds */
|
/* delay a time in milliseconds */
|
||||||
void delay_1ms(uint32_t count);
|
void delay_1ms(uint32_t count);
|
||||||
/* delay a time in seconds */
|
/* delay a time in seconds */
|
||||||
|
|||||||
Reference in New Issue
Block a user