中级会员
 
- 积分
- 487
- 金钱
- 487
- 注册时间
- 2026-1-29
- 在线时间
- 29 小时
|
发表于 2026-7-6 17:55:06
|
显示全部楼层
本帖最后由 664929323 于 2026-7-6 17:56 编辑
针对您的问题,我将分三个部分解答:判断串口助手开闭状态、解决数据堆积问题、以及相关代码优化建议。
一、判断串口助手打开/关闭状态
方法1:监听DTR信号(推荐)
虚拟串口的DTR(Data Terminal Ready)信号可以反映PC端状态:
// 在USB回调函数中检测DTR状态
void USB_CDC_Handler(void)
{
if (pProperty->USB_IsConnected)
{
if (pProperty->USB_DtrStatus) // DTR=1 表示串口助手已打开
{
// 串口助手打开处理
}
else // DTR=0 表示串口助手关闭
{
// 串口助手关闭处理
}
}
}
方法2:监控USB总线活动
通过检测USB端点的活跃状态间接判断:
// 在USB发送完成回调中判断
void USB_TxCompleteCallback(void)
{
if (/* 连续多次发送无响应 */)
{
// 判定为串口助手已关闭
}
}
二、解决数据堆积问题
方案A:立即清空发送队列
void FlushTxBuffer(void)
{
// 清空您的发送队列
QUEUE_Reset(&m_QueueUsbComTx);
// 同时清空USB硬件FIFO(如有必要)
// 需查阅具体USB外设寄存器手册
}
方案B:智能发送控制(推荐)
// 修改发送函数
uint32_t USB_TxWrite(uint8_t *buffter, uint32_t writeLen)
{
// 只在USB在线时发送
if (pProperty->USB_IsConnected && pProperty->USB_DtrStatus)
{
return QUEUE_PacketIn(&m_QueueUsbComTx, buffter, writeLen);
}
return 0; // 丢弃数据
}
三、完整解决方案示例
1. 初始化检测
// 系统启动时立即清空缓冲区
FlushTxBuffer();
2. 状态监测任务
void USB_MonitorTask(void *argument)
{
uint8_t lastDtrState = 0;
while(1)
{
uint8_t currentDtr = pProperty->USB_DtrStatus;
// 状态变化检测
if (lastDtrState != currentDtr)
{
if (currentDtr)
{
FlushTxBuffer(); // 新打开时清空旧数据
}
lastDtrState = currentDtr;
}
vTaskDelay(pdMS_TO_TICKS(100)); // 100ms检测周期
}
}
3. 发送策略优化
// 带超时机制的发送函数
uint32_t USB_SmartTxWrite(uint8_t *buffer, uint32_t length)
{
static uint32_t failCount = 0;
if (!pProperty->USB_IsConnected || !pProperty->USB_DtrStatus)
{
failCount++;
if (failCount > 10) // 连续10次失败认为离线
{
FlushTxBuffer();
failCount = 0;
}
return 0;
}
failCount = 0;
return USB_TxWrite(buffer, length);
}
四、关键注意事项
端点配置:确认使用了正确的端点配置(通常批量传输端点EP1):
#define EP1_TX_SIZE 64 // 确保端点大小足够
中断优先级:USB中断应设置为最高优先级:
NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0);
队列管理:建议采用环形队列:
typedef struct {
uint8_t buffer[512];
volatile uint16_t head, tail;
} RingBuffer;
五、调试建议
观察LED指示:
#define LED_ON() GPIO_SetBits(GPIOC, GPIO_Pin_13)
#define LED_OFF() GPIO_ResetBits(GPIOC, GPIO_Pin_13)
使用逻辑分析仪:监测USB D+/D-信号质量
PC端验证:使用Tera Term等工具测试各种插拔场景
这种方案能有效解决您遇到的三个问题:实时检测串口状态、防止数据堆积、确保重连后数据同步。实际部署时建议先通过示波器观察USB总线活动验证检测逻辑的可靠性。 |
|