feat: 添加RC522站点匹配逻辑及到站提示功能

This commit is contained in:
2026-04-15 00:06:45 +08:00
parent a6359364fd
commit 9313675630
2 changed files with 98 additions and 25 deletions

View File

@@ -1,25 +1,4 @@
#include "bsp_rc522.h"
#include <string.h>
// 站点UID白名单可扩展
static const uint8_t g_station_1_uid[] = STATION_1_UID;
static const uint8_t g_station_2_uid[] = STATION_2_UID;
station_id_t rc522_match_station(const uint8_t *uid, uint8_t uid_len)
{
if (uid == NULL || uid_len == 0) return STATION_NONE;
// 匹配站点1
if (uid_len == sizeof(g_station_1_uid) && memcmp(uid, g_station_1_uid, uid_len) == 0) {
return STATION_1;
}
// 匹配站点2
if (uid_len == sizeof(g_station_2_uid) && memcmp(uid, g_station_2_uid, uid_len) == 0) {
return STATION_2;
}
// 可继续添加更多站点匹配
return STATION_NONE;
}
#include "bsp_rc522.h"
#include "spi.h"
#include <string.h>
@@ -630,3 +609,24 @@ void rc522_irq_callback(uint16_t GPIO_Pin)
g_irq_pending = 1U;
}
}
/* 站点UID白名单可扩展 */
static const uint8_t g_station_1_uid[] = STATION_1_UID;
static const uint8_t g_station_2_uid[] = STATION_2_UID;
station_id_t rc522_match_station(const uint8_t *uid, uint8_t uid_len)
{
if (uid == NULL || uid_len == 0U) {
return STATION_NONE;
}
if (uid_len == sizeof(g_station_1_uid) && memcmp(uid, g_station_1_uid, uid_len) == 0) {
return STATION_1;
}
if (uid_len == sizeof(g_station_2_uid) && memcmp(uid, g_station_2_uid, uid_len) == 0) {
return STATION_2;
}
return STATION_NONE;
}

View File

@@ -12,6 +12,8 @@
#include "bsp_hall.h"
#include "bsp_pid.h"
#include "bsp_uart.h"
#include "bsp_rc522.h"
#include "bsp_beep.h"
#include "checksum.h"
#include "cmsis_os.h"
#include "elog.h"
@@ -46,6 +48,10 @@ static float target_v_w = 0; // 原地旋转分量
static uint8_t car_running = 0; // 小车运行状态1=运行0=停止)
static uint8_t car_speed_percent = 0; // 当前整体速度百分比0~100
static uint16_t car_target_station = 0; // 目标站点编号
static uint8_t car_target_reached = 0; // 到站锁存,避免重复触发
#define CAR_STATION_MIN ((uint16_t)STATION_1)
#define CAR_STATION_MAX ((uint16_t)STATION_2)
/* 4个电机的 PID 控制器 */
static PID_TypeDef motor_pid[MOTOR_COUNT];
@@ -85,6 +91,46 @@ static void CarCtrl_StopAll(void)
}
}
/**
* @brief 到站蜂鸣提示
* @param times 蜂鸣次数
*/
static void CarCtrl_BeepTimes(uint8_t times)
{
for (uint8_t i = 0; i < times; i++) {
BEEP_On();
osDelay(120);
BEEP_Off();
osDelay(120);
}
}
/**
* @brief 运行期间检测是否到达目标站点
*/
static void CarCtrl_CheckTargetStation(void)
{
rc522_card_info_t card;
station_id_t station;
if (car_running == 0U || car_target_reached != 0U || car_target_station == 0U) {
return;
}
if (rc522_get_new_card(&card) == 0U) {
return;
}
station = rc522_match_station(card.uid, card.uid_len);
if ((uint16_t)station == car_target_station) {
car_running = 0U;
car_target_reached = 1U;
CarCtrl_StopAll();
elog_i(Protocol_TAG, "到达目标站点%u停车并蜂鸣", car_target_station);
CarCtrl_BeepTimes(3U);
}
}
/**
* @brief 按当前 car_speed_percent 设置所有电机速度
*/
@@ -155,8 +201,8 @@ void CarCtrl_UpdateClosedLoop(void)
const char* motor_names[] = {"LR", "LF", "RF", "RR"};
static uint32_t last_log_time = 0;
if (HAL_GetTick() - last_log_time > 500) {
elog_d(Protocol_TAG, "M[%s] T:%.1f A:%.1f Pw:%d",
motor_names[i], target_rpms[i], actual_rpm, (int16_t)final_pwm);
elog_d(Protocol_TAG, "M[%s] T:%.1f A:%.1f Pw:%d",
motor_names[i], target_rpms[i], actual_rpm, (int16_t)final_pwm);
if (i == MOTOR_COUNT - 1) last_log_time = HAL_GetTick();
}
}
@@ -184,11 +230,30 @@ static void CarCtrl_HandleCommand(const char *cmd_payload)
// 启动/停止命令(仅作为自动循迹任务的启动/暂停信号,不直接控制电机)
if (strncmp(cmd_payload, "ST", 2) == 0) {
if (strcmp(arg + 1, "RUN") == 0) {
if (car_target_reached != 0U) {
car_running = 0U;
CarCtrl_StopAll();
elog_w(Protocol_TAG, "已到达站点,请先重新设置目标站点 (GS:xxx) 之后再启动");
CarCtrl_BeepTimes(2U);
return;
}
if (car_target_station < CAR_STATION_MIN || car_target_station > CAR_STATION_MAX) {
car_running = 0U;
CarCtrl_StopAll();
elog_w(Protocol_TAG, "未设置有效站点,拒绝启动。请先下发 GS:001 或 GS:002");
CarCtrl_BeepTimes(2U);
return;
}
car_running = 1;
car_target_reached = 0;
elog_i(Protocol_TAG, "小车自动循迹启动, speed=%u%%, station=%u", car_speed_percent,
car_target_station);
} else if (strcmp(arg + 1, "STOP") == 0) {
car_running = 0;
car_target_reached = 0;
CarCtrl_StopAll();
elog_i(Protocol_TAG, "小车自动循迹暂停");
} else {
elog_w(Protocol_TAG, "未知启动/停止命令: %s", cmd_payload);
@@ -225,12 +290,17 @@ static void CarCtrl_HandleCommand(const char *cmd_payload)
// 解析站点编号0~999
if (sscanf(arg + 1, "%u", &station) == 1) {
if (station > 999U) {
station = 999U;
if (station < CAR_STATION_MIN || station > CAR_STATION_MAX) {
elog_w(Protocol_TAG, "站点%03u未配置目前仅支持 %03u~%03u", station,
CAR_STATION_MIN, CAR_STATION_MAX);
CarCtrl_BeepTimes(2U);
return;
}
car_target_station = (uint16_t)station;
car_target_reached = 0;
elog_i(Protocol_TAG, "设置目标站点: %03u", car_target_station);
CarCtrl_BeepTimes(1U);
} else {
elog_w(Protocol_TAG, "站点参数解析失败: %s", cmd_payload);
}
@@ -345,6 +415,9 @@ void CarCtrl_Task(void *argument) {
CarCtrl_HandleCommand(cmd_payload);
}
/* 1.1 运行中检查 RFID 是否到达目标站点 */
CarCtrl_CheckTargetStation();
/* 2. 执行 PID 闭环控制更新 */
CarCtrl_UpdateClosedLoop();