使用设备:正点原子 STM32 F407 IGT6 开发板,现在已通过 CubeMX 配置 PA11、PA12 对应的 USB 接口为USB 设备模式(模拟 UPS 电池设备)。
目前现象:台式机设备管理器可以识别出 USB HID UPS电池、控制面板内出现有电源选项有菜单、但是任务栏出电池图标灰色、电量显示 100% 却配个“空电池”视觉图,上传报文电量无变化。
现状:
通信层(底层): 正常。USBlyzer工具抓到的 01 02 02 27 00 64 00 64 00 0A 05 说明 STM32 已经按照指令发出了数据。
驱动层(中层): 正常。Windows 已加载 hidups.sys,在电源选项里可以看到“关键电池电量操作”。
应用层(视觉层): 异常。
灰色图标:表示 Windows 认为当前处于“放电状态”(Discharging),但因为它不确定电池的“健康度”或“满充参考值”,所以不敢点亮图标。
我的代码
USP HID:
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
0x05, 0x84, // Usage Page (Power Device)
0x09, 0x04, // Usage (UPS)
0xa1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
// --- 1. 电源状态 ---
0x05, 0x84, // Usage Page (Power Device)
0x09, 0x3d, // Usage (AC Present) - Bit 0
0x09, 0x45, // Usage (Discharging) - Bit 1
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x02,
0x81, 0x02, // Input (Data,Var,Abs)
0x95, 0x06,
0x81, 0x03, // Padding (6 bits)
// --- 2. 相对电量百分比 ---
0x05, 0x85, // Usage Page (Battery System)
0x09, 0x6d, // Usage (Relative State of Charge)
0x15, 0x00,
0x25, 0x64, // Logical Max: 100
0x75, 0x08,
0x95, 0x01,
0x81, 0x02, // Input (Data,Var,Abs)
/* USER CODE END 0 */
0xC0 // End Collection
};
Main.c
main(){
初始化();
while(1){
sync_report[0] = 0x01; // Report ID
sync_report[2] = 0x02; //百分比模式
USB_Send_Retry(sync_report, 2)
}
}
uint8_t USB_Send_Retry(uint8_t *report, uint16_t len) {
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;
for (uint8_t retry = 0; retry < 10; retry++) {
// 关键点:不仅看返回值,还要看 HID 状态机是否为空闲
if (hhid->state == CUSTOM_HID_IDLE) {
if (USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len) == USBD_OK) {
return 0;
}
}
HAL_Delay(5);
}
return 1;
}
请教一下大家,我使用USBlyzer抓到怎么样的数据是正确。
我尝试过的报文如下:
01 64 (ID 01) 和 02 00 01 (ID 02)。分开报
01 02 4D。合并报
01 02 02 27 00 64 00。使用16位精度
01 02 02 47 00 64 00 64 00 0A 05。网上找的全功能UPS报文
使用这些报文都无法实现Windows系统下电池电量的修改,依旧是100%,就像是系统下没有处理这些报文。