单片机/MCU论坛
直播中

失无

未满1年用户 6经验值
擅长:嵌入式技术 接口/总线/驱动 控制/MCU
私信 关注
[问答]

为什么给传感器发送命令,同样的代码有时候秒回应,之后就不回应了(⊙o⊙)?

/* 包含必要的头文件 */
#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);
}

}*附件:PTQS1005A-N 多合一传感器中文规格书 V1.0.pdf

奖励20积分

更多回帖

发帖
×
20
完善资料,
赚取积分