feat: 添加RC522站点匹配逻辑及到站提示功能
This commit is contained in:
@@ -1,25 +1,4 @@
|
|||||||
#include "bsp_rc522.h"
|
#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 "spi.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -630,3 +609,24 @@ void rc522_irq_callback(uint16_t GPIO_Pin)
|
|||||||
g_irq_pending = 1U;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include "bsp_hall.h"
|
#include "bsp_hall.h"
|
||||||
#include "bsp_pid.h"
|
#include "bsp_pid.h"
|
||||||
#include "bsp_uart.h"
|
#include "bsp_uart.h"
|
||||||
|
#include "bsp_rc522.h"
|
||||||
|
#include "bsp_beep.h"
|
||||||
#include "checksum.h"
|
#include "checksum.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "elog.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_running = 0; // 小车运行状态(1=运行,0=停止)
|
||||||
static uint8_t car_speed_percent = 0; // 当前整体速度百分比(0~100)
|
static uint8_t car_speed_percent = 0; // 当前整体速度百分比(0~100)
|
||||||
static uint16_t car_target_station = 0; // 目标站点编号
|
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 控制器 */
|
/* 4个电机的 PID 控制器 */
|
||||||
static PID_TypeDef motor_pid[MOTOR_COUNT];
|
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 设置所有电机速度
|
* @brief 按当前 car_speed_percent 设置所有电机速度
|
||||||
*/
|
*/
|
||||||
@@ -184,11 +230,30 @@ static void CarCtrl_HandleCommand(const char *cmd_payload)
|
|||||||
// 启动/停止命令(仅作为自动循迹任务的启动/暂停信号,不直接控制电机)
|
// 启动/停止命令(仅作为自动循迹任务的启动/暂停信号,不直接控制电机)
|
||||||
if (strncmp(cmd_payload, "ST", 2) == 0) {
|
if (strncmp(cmd_payload, "ST", 2) == 0) {
|
||||||
if (strcmp(arg + 1, "RUN") == 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_running = 1;
|
||||||
|
car_target_reached = 0;
|
||||||
elog_i(Protocol_TAG, "小车自动循迹启动, speed=%u%%, station=%u", car_speed_percent,
|
elog_i(Protocol_TAG, "小车自动循迹启动, speed=%u%%, station=%u", car_speed_percent,
|
||||||
car_target_station);
|
car_target_station);
|
||||||
} else if (strcmp(arg + 1, "STOP") == 0) {
|
} else if (strcmp(arg + 1, "STOP") == 0) {
|
||||||
car_running = 0;
|
car_running = 0;
|
||||||
|
car_target_reached = 0;
|
||||||
|
CarCtrl_StopAll();
|
||||||
elog_i(Protocol_TAG, "小车自动循迹暂停");
|
elog_i(Protocol_TAG, "小车自动循迹暂停");
|
||||||
} else {
|
} else {
|
||||||
elog_w(Protocol_TAG, "未知启动/停止命令: %s", cmd_payload);
|
elog_w(Protocol_TAG, "未知启动/停止命令: %s", cmd_payload);
|
||||||
@@ -225,12 +290,17 @@ static void CarCtrl_HandleCommand(const char *cmd_payload)
|
|||||||
|
|
||||||
// 解析站点编号(0~999)
|
// 解析站点编号(0~999)
|
||||||
if (sscanf(arg + 1, "%u", &station) == 1) {
|
if (sscanf(arg + 1, "%u", &station) == 1) {
|
||||||
if (station > 999U) {
|
if (station < CAR_STATION_MIN || station > CAR_STATION_MAX) {
|
||||||
station = 999U;
|
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_station = (uint16_t)station;
|
||||||
|
car_target_reached = 0;
|
||||||
elog_i(Protocol_TAG, "设置目标站点: %03u", car_target_station);
|
elog_i(Protocol_TAG, "设置目标站点: %03u", car_target_station);
|
||||||
|
CarCtrl_BeepTimes(1U);
|
||||||
} else {
|
} else {
|
||||||
elog_w(Protocol_TAG, "站点参数解析失败: %s", cmd_payload);
|
elog_w(Protocol_TAG, "站点参数解析失败: %s", cmd_payload);
|
||||||
}
|
}
|
||||||
@@ -345,6 +415,9 @@ void CarCtrl_Task(void *argument) {
|
|||||||
CarCtrl_HandleCommand(cmd_payload);
|
CarCtrl_HandleCommand(cmd_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 1.1 运行中检查 RFID 是否到达目标站点 */
|
||||||
|
CarCtrl_CheckTargetStation();
|
||||||
|
|
||||||
/* 2. 执行 PID 闭环控制更新 */
|
/* 2. 执行 PID 闭环控制更新 */
|
||||||
CarCtrl_UpdateClosedLoop();
|
CarCtrl_UpdateClosedLoop();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user