/* 包含必要的头文件 */
#include "project.h" // PSoC Creator生成的项目头文件
#include <stdio.h> // 标准输入输出,用于sprintf等函数
#include <stdint.h> // 标准整数类型定义
#include <string.h> // 字符串操作函数
/* 指令帧头定义 */
#define CMD_HEADER_1 0x42 // 指令帧第一个特征字节
#define CMD_HEADER_2 0x4D // 指令帧第二个特征字节
#define CMD_STANDBY_CTRL 0xF4 // 待机控制指令码
#define STANDBY_CMD_LEN 7 // 待机指令总长度(字节数)
/* 系统参数配置 */
#define STANDBY_PACKET_SIZE 24 // 预期的待机响应数据包大小
#define CMD_RETRY_INTERVAL 220 // 指令重试间隔时间(毫秒)
#define STANDBY_TIMEOUT 3000 // 等待待机确认的超时时间(毫秒)
#define MAX_RETRY_COUNT 15 // 最大重试次数
/* 系统时间变量(毫秒计时)*/
volatile uint32_t systemtime = 0; // 使用volatile防止编译器优化
/* 待机控制状态结构体 */
typedef struct {
volatile uint8_t standbyCmdSent; // 1=已发送待机指令
volatile uint8_t standbyConfirmed; // 1=收到待机确认
volatile uint8_t retryCount; // 当前重试次数计数
uint32_t lastStandbyCmdTime; // 最后一次发送指令的时间戳
} STANDBY_CTRL;
/* 全局待机控制状态实例 */
STANDBY_CTRL standbyCtrl;
/* 待机指令数据包(固定格式)*/
const uint8_t standbyCmd[STANDBY_CMD_LEN] = {
CMD_HEADER_1, // 帧头字节1
CMD_HEADER_2, // 帧头字节2
CMD_STANDBY_CTRL, // 指令码(待机控制)
0x00, // 数据高字节(00=待机)
0x00, // 数据低字节
0x01, // 校验字节1(固定值)
0x83 }; // 校验字节2(校验和)
/* 发送待机指令函数 /
void SendStandbyCommand(void) {
/ 通过UART发送指令数据 */
PM_UART_PutArray(standbyCmd, STANDBY_CMD_LEN);
/* 更新发送状态 */
standbyCtrl.standbyCmdSent = 1; // 设置已发送标志
standbyCtrl.lastStandbyCmdTime = systemtime; // 记录发送时间
standbyCtrl.retryCount++; // 增加重试计数器
/* 打印调试信息 */
UART_PutString("CMD["); // 输出指令前缀
char info[10]; // 临时缓冲区
sprintf(info, "%d/%d]: ", // 格式化重试信息
standbyCtrl.retryCount,
MAX_RETRY_COUNT);
UART_PutString(info); // 输出重试次数
/* 打印完整指令内容(十六进制) */
for (uint8_t i = 0; i < STANDBY_CMD_LEN; i++) {
char hex[4]; // 临时存储十六进制字符串
sprintf(hex, "%02X ", standbyCmd[i]);// 格式化字节为十六进制
UART_PutString(hex); // 输出字节
}
UART_PutString("\n"); // 换行
}
/* 进入待机模式流程控制 /
void EnterStandbyMode(void) {
/ 重置所有状态标志 */
standbyCtrl.standbyCmdSent = 0; // 清除发送标志
standbyCtrl.standbyConfirmed = 0; // 清除确认标志
standbyCtrl.retryCount = 0; // 重置重试计数器
/* 发送第一条待机指令 */
SendStandbyCommand();
}
/* 系统滴答定时器中断回调函数 */
void SysTickISRCallback(void) {
systemtime++; // 每毫秒递增系统时间计数器
}
/* UART接收中断服务程序 /
CY_ISR(UART_Sensor_Rx_Isr) {
/ 读取接收到的数据字节 */
uint8_t rxData = PM_UART_ReadRxData();
/* 简化处理:仅检测响应帧头0x42 */
if(rxData == CMD_HEADER_1) {
standbyCtrl.standbyConfirmed = 1; // 设置确认标志
UART_PutString("ACK received\n"); // 打印确认信息
}
}
/* 主程序入口 /
int main(void) {
/ 硬件初始化 */
CyGlobalIntEnable; // 开启全局中断
UART_Start(); // 初始化调试UART
PM_UART_Start(); // 初始化传感器UART
/* 中断配置 */
PM_UART_SetRxInterruptMode(PM_UART_RX_STS_FIFO_NOTEMPTY); // 设置接收中断模式
PM_ISR_StartEx(UART_Sensor_Rx_Isr); // 注册UART中断服务程序
/* 系统时间初始化 */
CySysTickStart(); // 启动系统滴答定时器
CySysTickSetCallback(0, SysTickISRCallback); // 注册定时器回调
/* 打印启动信息 */
UART_PutString("System Ready - Max Retry="); // 输出前缀
char maxRetry[3]; // 临时缓冲区
sprintf(maxRetry, "%d", MAX_RETRY_COUNT); // 格式化最大重试次数
UART_PutString(maxRetry); // 输出次数
UART_PutString("\n"); // 换行
/* 开始待机流程 */
EnterStandbyMode(); // 首次进入待机模式
/* 主循环 */
for(;;) {
/* 检查指令已发送但未确认的情况 */
if(standbyCtrl.standbyCmdSent && !standbyCtrl.standbyConfirmed) {
/* 检测是否超时 */
if((systemtime - standbyCtrl.lastStandbyCmdTime) > STANDBY_TIMEOUT) {
/* 判断是否达到最大重试次数 */
if(standbyCtrl.retryCount < MAX_RETRY_COUNT) {
/* 未达最大次数,继续重试 */
UART_PutString("Timeout - "); // 打印超时信息
SendStandbyCommand(); // 重发指令
} else {
/* 已达最大重试次数 */
UART_PutString("Max retry reached. "); // 打印错误信息
UART_PutString("Last try delay:"); // 打印延迟信息
char delay[10]; // 临时缓冲区
sprintf(delay,"%lums\n", // 格式化延迟时间
systemtime - standbyCtrl.lastStandbyCmdTime);
UART_PutString(delay); // 输出延迟时间
/* 重置状态,5秒后重新尝试 */
standbyCtrl.standbyCmdSent = 0; // 清除发送标志
CyDelay(5000); // 延时5秒
EnterStandbyMode(); // 重新开始流程
}
}
}
/* 检查是否收到确认 */
if(standbyCtrl.standbyConfirmed) {
/* 打印成功信息 */
UART_PutString("Standby confirmed. Total tries:");
char tries[4]; // 临时缓冲区
sprintf(tries, "%d\n", standbyCtrl.retryCount); // 格式化尝试次数
UART_PutString(tries); // 输出次数
/* 待机确认后的永久循环 */
while(1) {
CyDelay(1000); // 可在此处添加低功耗处理
}
}
/* 主循环延迟(降低CPU占用率) */
CyDelay(100);
}
更多回帖