发送步骤
- 导入pyserial库——import serial 用于操作串口(详情见serial简介)
- 初始化串口——serial.Serial
portx = "/dev/ttyUSB0" #端口(此处为Unix下的端口号,Windows下为portx = “com3”形式
bps = 115200 #波特率
timex = 0.5 #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
MySerial = serial.Serial(portx, int(bps), timeout=timex) # 打开串口,并得到串口对象
- 导入struct库——import struct 用于将浮点型数据转换为字符串,该字符串为字节流,浮点型数据为四字节流(详情见struct库简介)
- 将浮点型数据转化为字节流——struct.pack
分析
>>> import struct
>>> F =12.34
>>> B =struct.pack('f',F) #‘f'表示以浮点型格式进行转化
>>> type(B)
<class 'bytes'> #bytes 类型用来表示一个字节串,记录内存中的原始数据
>>> print(B)
b'\xa3pEA' #默认以'UTF-8'的形式进行编码,对于非ASCII字符,打印输出的是十六进制形式,因此前面输出了个’\xa3'
>>> type(B[0])
<class 'int'>
>>> print(B[0])
164 #164是16进制数\xa4的10进制形式,这说明浮点数据的低字节位存放在低地址处
#十进制(12.34)的单精度浮点数值:414570A4,(01000001010001010111000010100100)
bytes数据类型简介:bytes数据类型简介 大小端模式:大小端模式简介
eg:电机转速浮点型数据转换为bytes数据类型
left_front = -float(speeds[0]);
right_front = float(speeds[1]);
left_rear = -float(speeds[2]);
right_rear = float(speeds[3]);
data_motor_fl = struct.pack('f', left_front) #低位字节放在最前面,总共四个字节
data_motor_fr = struct.pack('f', right_front) #十进制(12.345)的单精度浮点数值:4145851E,(01000001010001011000010100011110)
data_motor_bl = struct.pack('f', left_rear) #字节流顺序为"0x1E","0x85","0x45","0x41"
data_motor_br = struct.pack('f', right_rear) #小端模式存放数据
- 向下位机发送数据
comma_head = 'H'; #首校验位
comma_trail = 'T'; #尾校验位
comma_Motor_FL = 0x01; #指令(左前方电机)
comma_Motor_FR = 0x02; #指令(右前方电机)
comma_Motor_BL = 0x03;
comma_Motor_BR = 0x04;
send_data_fl_motor = comma_head + comma_Motor_FL + data_motor_fl + comma_trail #首校验位+指令+数据+尾校验位
send_data_fr_motor = comma_head + comma_Motor_FR + data_motor_fr + comma_trail
send_data_bl_motor = comma_head + comma_Motor_BL + data_motor_bl + comma_trail
send_data_br_motor = comma_head + comma_Motor_BR + data_motor_br + comma_trail
MySerial.wtrite(send_data_fl_motor )
MySerial.wtrite(send_data_fl_motor )
MySerial.wtrite(send_data_fl_motor )
MySerial.wtrite(send_data_fl_motor )
- 下位机接收数据(C语言环境)
typedef union
{
uint_8 CharNum[4];
float FloatNum;
}DataUnion;
DataUnion UartData;
void Uart_getchar (UART_Type *base, uint8_t *ch)//读串口寄存器数据函数,参数依次为串口号,读数变量地址
void main(void)
{
temp = (uint8_t*)malloc(1);
order = (uint8_t*)malloc(1);
while(1)
{
Uart_getchar(UART1, temp); //读进首校验字符
if(*temp == head)//当第一个字符是首校验字符时开始读进指令,否则跳过
{
Uart_getchar(UART1, order); //读进指令字符
Uart_getchar(UART1, UartData.CharNum); //读进数据字符,上位机发送的第一个数据位是最低字节位,这里也让低地址位接收其低字节位
Uart_getchar(UART1, UartData.CharNum+1);//单片机为小端模式
Uart_getchar(UART1, UartData.CharNum+2);
Uart_getchar(UART1, UartData.CharNum+3);
Uart_getchar(UART1, temp); //读进尾校验字符
if(*temp == tail)
{
switch(*order)
{
case 0x01: //左前电机赋值
Motor_FL = UartData.FloatNum
break;
case 0x02: //右前电机赋值
Motor_FR = UartData.FloatNum
break;
case 0x03: //左后电机赋值
Motor_BL = UartData.FloatNum
break;
case 0x04: //右后电机赋值
Motor_BR = UartData.FloatNum
break;
}
}
}
}
}
void Uart_getchar (UART_Type *base, uint8_t *ch) //uart接收一个字符
{
while(!(base->S1 & UART_S1_RDRF_MASK));
*ch = base->D;
}