通過 USB,我將以下內容發送到我的 QT C 應用程式。如您所見,我們總共向我的 QT C 應用程式發送了 5 個位元組的資料。
/* Create array of prescalers */
uint8_t send_data_array[5] = {0};
uint8_t index = 0;
/* Fill the array */
send_data_array[index ] = SEND_BACK_PWM_PRESCALERS_MESSAGE_TYPE;
send_data_array[index ] = STM32_PLC_PWM0_To_PWM3_Get_Prescaler() >> 8;
send_data_array[index ] = STM32_PLC_PWM0_To_PWM3_Get_Prescaler();
send_data_array[index ] = STM32_PLC_PWM4_To_PWM7_Get_Prescaler() >> 8;
send_data_array[index ] = STM32_PLC_PWM4_To_PWM7_Get_Prescaler();
/* Send the data via USB */
CDC_Transmit_FS(send_data_array, index);
當我發送資料時,它看起來像這樣:

所以當我在我的 QT C 應用程式中接收資料時,它看起來像這樣:
uint32_t MessageServiceThread::readPWMPrescalersFromSTM32PLC(QByteArray usbDataRaw, uint32_t byteIndex){
pwmPrescaler[0] = (usbDataRaw.at(byteIndex) << 8) | usbDataRaw.at(byteIndex 1);
byteIndex = 2;
pwmPrescaler[1] = (usbDataRaw.at(byteIndex) << 8) | usbDataRaw.at(byteIndex 1);
byteIndex = 2;
uint16_t p0 = pwmPrescaler[0];
uint16_t p1 = pwmPrescaler[1];
其中usbDataRaw包含資料。的第一個索引usbDataRaw包含message type描述它是什么型別的訊息。所以上面的代碼從 index 開始1,而不是 index 0。
讓我們專注于
pwmPrescaler[0] = (usbDataRaw.at(byteIndex) << 8) | usbDataRaw.at(byteIndex 1);
這里pwmPrescaler被宣告為uint16_t pwmPrescaler[2];and
usbDataRaw.at(byteIndex) = 0和usbDataRaw.at(byteIndex 1) = 250。
但是當我將它們組合起來時,你可以看到,我得到了數字65530!

這很有趣,因為-6/250is 0xFAor 250。這意味著0必須成為0xFF正確的?為什么 else 會250變成65530?

uj5u.com熱心網友回復:
char是signed還是未指定unsigned。
usbDataRaw.at(byteIndex 1)導致char打算存盤值的 a 250。看起來在你的平臺上char是這樣的signed,所以這個值實際上是-6。
對小于在執行操作之前int提升到的整數型別的算術運算int。來自整數提升的 cppreference :
小整數型別(例如
char)的純右值可以轉換為較大整數型別(例如int)的純右值。特別是,算術運算子不接受小于int作為引數的型別,并且在左值到右值轉換后會自動應用整數提升(如果適用)。此轉換始終保留該值。
請注意最后一句話:“此轉換始終保留值”。在這種情況下保留的值-6不是250。char被提升為具有結果的int值-6(假設為 32 位int)0xFFFFFFFA。左運算元也會發生同樣的事情,但保留的值是0,位移不會改變它。然后執行按位 OR 得到0xFFFFFFFA,然后截斷為uint16_tfor0xFFFA或65530。
在這種情況下,一種解決方案是先將 to 轉換char為unsigned char允許促銷保留預期值。250
現場示例:https ://godbolt.org/z/PP8rKqab7
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/448145.html
上一篇:將Qt與OpenGL結合:不編譯
