python3串口通信16进制_STM32串口通信——16进制数形式
一.為什么采用16進制數(shù)形式?
首先,需要解釋一下串口發(fā)送的數(shù)據(jù)都是unsigned char類型的,說成字符和16進制形式,只是我們采用何種方式展示這些數(shù)據(jù)。字符形式就是把16進制數(shù)通過ASCII表一個一個轉(zhuǎn)成字符的。
一開始接觸到的串口程序,就是字符形式的,尤其是STM32中被重構(gòu)的printf()函數(shù),我就先入為主地選擇了字符形式。這樣比較人性化,因為啥數(shù)據(jù)都是平時看到的字符,很直觀,但是大大降低了通信效率!比如要發(fā)送一個數(shù)85,字符形式需要發(fā)送’8’+‘5’,而16進制只需要發(fā)送0x55。還有一點是負數(shù),字符形式多加了一個’-'號,16進制直接發(fā)送有符號數(shù)就行了。如果要傳輸大量的數(shù)據(jù),應該采用16進制形式。
我在調(diào)試STM32與PC(采用Python3編寫)串口通信過程中,二者之間需要發(fā)送各種類型的數(shù)據(jù),uint_8、int16_t、float等等,要將所有類型的數(shù)據(jù)轉(zhuǎn)換成uint_8類型發(fā)送,同時上位機要能轉(zhuǎn)換回來。總之就是拆開發(fā)送,接收重組。
二.下位機
uint_8 型
發(fā)送:直接利用USART_SendData函數(shù),通常配合檢測發(fā)送結(jié)束位使用,如下:
void usart1_send_data(uint8_t num){
USART_SendData(USART1, num);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
接收:很簡單,直接賦值即可。
int16_t型
發(fā)送:int16_t型涉及到補碼,但是可以留到上位機解決,只要分別發(fā)送高低8位數(shù)就可以。
void send_int16_t(int16_t num){
uint8_t high_8, low_8;
low_8 = num & 0x00FF;
high_8 = (num>>8) & 0x00FF;
usart1_send_data(high_8);
usart1_send_data(low_8);
}
接收:定義一個int16_t類型的數(shù),將接收到高低八位分別移位即可,貼的代碼中的LOW和HIGH變量只是一個例子,參考這個代碼改就行。
int16_t temp = 0;
temp |= (int16_t)LOW[4]&0x00FF;
temp |= ((int16_t)HIGH<<8)&0xFF00;
float型
發(fā)送:雖然float型比較復雜,但是由于我用到的數(shù)都比較小,而且精度不高,所以可以把float分整數(shù)、小數(shù)發(fā)送出去。如果需要發(fā)送大數(shù),可以把下面代碼中的interger和decimal改成16位類型。
void send_float(float num){
uint8_t integer, decimal;? // 限制在uint8_t型
integer = (uint8_t)num;
decimal = (uint8_t)(( num-(uint8_t)num )*100); // 取兩位小數(shù)
usart1_send_data(integer);
usart1_send_data(decimal);
}
接收:定義一個float型數(shù),將小數(shù)部分*100加上整數(shù)部分即可,如下:
float num_f;
num_f = interger + decimal/100.0f;
三.上位機(Python)
uint8_t型
發(fā)送:比如要發(fā)送16進制的23(10進制35),直接通過pyserial的write函數(shù),發(fā)送b"x23"或者bytes([35])。
ser.write(b"x23")? // ser.write(bytes([35]))
接收:調(diào)用pyserial的read讀取的bytes型,直接取數(shù)即可,例如:
response = ser.read(1)
num = response[0]
int16_t型
發(fā)送:由于要考慮補碼問題,但是可以通過ctypes的c_short(16位有符號整型)解決,不需要自己從補碼解到原碼,如下:
_num = c_short(num)
high_8 = (_num.value & 0xff00)>>8
low_8 = _num.value & 0x00ff
ser.write(bytes([high_8, low_8]))
接收:
num = c_short(0)
num.value |= high_8 << 8
num.value |= low_8
float型
發(fā)送:和下位機一樣,分開發(fā)送整數(shù)和小數(shù)即可,如下:
my_byte = bytes([int(num_f), int(100 * (num_f - int(num_f)))])
ser_write(my_byte)
接收:同下位機,如下:
num_f = round(interger + decimal[2]/100, 1)
與50位技術專家面對面20年技術見證,附贈技術全景圖總結(jié)
以上是生活随笔為你收集整理的python3串口通信16进制_STM32串口通信——16进制数形式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: practical python and
- 下一篇: sql left join用法_一张图看