串口通信中的三种数据表示形式
一、简介
串口通信是一种常见的硬件通信方式,可以实现设备之间的数据传输。
在串口通信中,数据的表示形式有很多种,本文介绍串口通信中的三种常见数据表示形式:ASCII码(字符)、十六进制、二进制。
1、ASCII码(字符)
ASCII码是一种字符编码标准,使用7位或8位二进制数表示128或256个字符。
在串口通信中,ASCII码通常用于传输字符数据,比如字母、数字、符号等。
ASCII码的优点是易于阅读和调试,缺点是占用的空间较大。
2、十六进制
十六进制是一种数制,使用16个数字(0-9、A-F)表示数值。
在串口通信中,十六进制通常用于传输二进制数据,比如传感器数据、控制指令等。
十六进制的优点是占用的空间较小,缺点是不易阅读。
3、二进制
二进制是一种数制,使用0和1表示数值。
二、下位机中的串口通信
以ESP32为例,下位机中的串口通信通常使用C语言编写。
ESP32中蓝牙串口使用char receivedChar = SerialBT.read()
读取数据,读取到的数据形式为ASCII码(字符)。
下面是ESP32中读取ASCII码(字符)数据的示例代码:
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int trigger;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
pinMode(23, OUTPUT);
digitalWrite(23, 1);
Serial.begin(115200);
SerialBT.begin("ESP32ArmMagnetic"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
while (SerialBT.available() > 0) { // 当串口收到字符数大于零时
char receivedChar = SerialBT.read(); // 读取串口接收缓冲区中的下一个字符
SerialBT.write(receivedChar); // 将刚刚接收到的字符发送回到串口
// 判断接收到的字符是否等于 '1' 或 '0'
if (receivedChar == '1') {
digitalWrite(23, HIGH); // 设置 pin 23 输出为 HIGH
} else if (receivedChar == '0') {
digitalWrite(23, LOW); // 设置 pin 23 输出为 LOW
}
}
}
三、串口调试助手中的串口通信
在串口调试助手中,数据一般是表示为字符类型和十六进制类型,在发送的时候会被自动转化为二进制数据。
在串口调试助手中,可以通过设置发送数据的格式来选择发送数据的表示形式。默认是字符形式,也可以选择十六进制形式。
四、Python上位机中的串口通信
以Python为例,上位机中的串口通信通常使用PySerial库。
PySerial库中的serial.Serial
类可以用于打开串口,serial.Serial.write()
方法可以用于向串口写入数据。
下面是Python中向串口写入数据的示例代码:
import serial
# 打开串口
ser = serial.Serial('COM1', 9600) # 根据实际情况修改串口名称和波特率
try:
# 发送字符类型数据
data_char = 'Hello, Arduino!\n' # 要发送的字符数据
ser.write(data_char.encode()) # 使用 encode() 方法将字符串转换为字节流并发送
print("Sent char data:", data_char)
# 发送十六进制类型数据
data_hex = bytes.fromhex('01 02 03 04') # 要发送的十六进制数据,以字节流的形式表示
ser.write(data_hex) # 直接发送十六进制数据
print("Sent hex data:", data_hex.hex())
# 发送二进制类型数据
data_bin = bytes([0b00000001, 0b00000010, 0b00000011, 0b00000100]) # 要发送的二进制数据,以字节流的形式表示
ser.write(data_bin) # 直接发送二进制数据
print("Sent binary data:", ' '.join(format(byte, '08b') for byte in data_bin))
finally:
# 关闭串口
ser.close()
下面是Python中读取串口数据的示例代码:
一般使用serial.Serial.read()
方法读取所有数据,读取到的数据形式为二进制数据,Python会默认将其转换为字符类型。
import serial
# 打开串口
ser = serial.Serial('COM1', 9600) # 根据实际情况修改串口名称和波特率
try:
# 接收所有缓冲区的数据
while True:
if ser.in_waiting > 0: # 如果串口接收缓冲区中有数据
received_data = ser.read(ser.in_waiting).decode().strip() # 读取所有可用数据
print("Received data:", received_data)
break # 退出循环
# 接收字符类型数据
while True:
if ser.in_waiting > 0: # 如果串口接收缓冲区中有数据
data_char = ser.readline().decode().strip() # 读取一行数据并转换为字符串
print("Received char data:", data_char)
break # 退出循环
# 接收十六进制类型数据
while True:
data_hex = ser.read(4) # 从串口接收缓冲区中读取指定长度的字节
if data_hex:
print("Received hex data:", data_hex.hex())
break # 退出循环
# 接收二进制类型数据
while True:
data_bin = ser.read(4) # 从串口接收缓冲区中读取指定长度的字节
if data_bin:
print("Received binary data:", ' '.join(format(byte, '08b') for byte in data_bin))
break # 退出循环
finally:
# 关闭串口
ser.close()
五、总结
ASCII码(字符)、十六进制均要转换为二进制数据才能在串口通信中传输。