发送步骤


  • 导入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;
}