stm32与python端进行串口收发

发布时间:2024年01月09日

1-1 串口发送端(stm32)

1字符串发送

/************状态:电机速度、位置和角位移传感器的速度、位置*****************/	 
//  字符串收发:已调试成功
    motor_position = Read_Encoder_Angle(Encoder);
    sensor_position = Get_Adc_Average_Angle(Adc);
    motor_velocity = Read_Encoder_Speed(Encoder);
    sensor_velocity = Get_Adc_Average_Speed();
    pc_fil = LPF(motor_position, pc_fil,0.2f);
    vc_fil = LPF(motor_velocity, vc_fil,0.2f);
    ec_fil = LPF(sensor_position,ec_fil,0.2f);
    wc_fil = LPF(sensor_velocity,wc_fil,0.2f);
		 
/************** 串口发送数据方式一:使用字符串传输数据(整型和浮点型) **********************/				 
    sprintf(data_str, "%-8.4f, %-8.4f, %-8.4f, %-8.4f\n", pc_fil, ec_fil, vc_fil, wc_fil);
    Usart_SendString(USART1, data_str);
    motor_velocity = 0.123;

2 16进制传输(整型)

/************** 串口发送数据方式二:传输数据打包-16进制传输(整型) **********************/		
    data_array[0] =  0x12;
    data_array[1] =  0x34;
    data_array[2] = (int)Encoder & 0xFF;
    data_array[3] = ((int)Encoder >> 8) & 0xFF;
    data_array[4] = (int)Adc & 0xFF;
    data_array[5] = ((int)Adc >> 8) & 0xFF;
    data_array[6] =  0x56;
    data_array[7] =  0x78;
    for(uint8_t  i = 0 ; i < 8; i++)
    {
        USART_SendData(USART1, *(data_array + i));
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  
    }
	

3 16进制传输(整型和浮点型)


/************** 串口发送数据方式三: 串口传输数据打包-16进制传输(整型和浮点型) **********************/		
 //函数功能:将一个浮点数转换为字节数组   倒序  大小端的问题
//入口参数:浮点数   字节数组
void FloatToByte(float floatNum, unsigned char* byteArry) {
    char* pchar = (char*)&floatNum;
    for (int i = 0; i < sizeof(float); i++) {
        *byteArry = *pchar;
        pchar++;
        byteArry++;
    }
}
    FloatToByte(motor_velocity, byteArry); // 8个字节数据
		data_array[0] =  0x12;  // 帧头1
		data_array[1] =  0x34;  // 帧头2
		data_array[2] = (int)motor_position & 0xFF;          // 电机位置低字节
		data_array[3] = ((int)motor_position >> 8) & 0xFF;   // 电机位置高字节
		/*电机速度为浮点型数据,将其十进制数转换为单精度浮点数是4个字节(32位),转换网站:http://www.styb.cn/cms/ieee_754.php*/
		data_array[4] = byteArry[0];							// 电机速度低字节		
		data_array[5] = byteArry[1];				// 电机速度高字节	
		data_array[6] = byteArry[2];							// 电机速度低字节		
		data_array[7] = byteArry[3];				// 电机速度高字节	
		data_array[8] =  0x56;  // 帧尾1
		data_array[9] =  0x78;  // 帧尾2
		for(uint8_t  i = 0 ; i < sizeof(data_array); i++)
			{
				USART_SendData(USART1, *(data_array + i));
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  
			}

4 仅发送浮点型小数

/**************串口发送数据方式四: 仅发送浮点型小数 **********************/

 //函数功能:将一个浮点数转换为字节数组   倒序  大小端的问题
//入口参数:浮点数   字节数组
void FloatToByte(float floatNum, unsigned char* byteArry) {
    char* pchar = (char*)&floatNum;
    for (int i = 0; i < sizeof(float); i++) {
        *byteArry = *pchar;
        pchar++;
        byteArry++;
    }
}
FloatToByte(motor_velocity, byteArry); // 8个字节数据
for(uint8_t  i = 0 ; i < sizeof(float); i++)
{
    USART_SendData(USART1, *(byteArry + i));
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  
}

1-2 串口接收端-python

接收数据:编码器(整型)、角位移传感器(整型)
# 从串口接收的数据为:编码器(整型)、角位移传感器(整型)
def read_serial_one_data_encoder_adc(ser):
    global receive_result
    BUF_SIZE = 8
    buf = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x56, 0x78])
    c1 = ib = flag = 0

    while True:
        R = ser.read(1)
        # print("data", R)
        if R == b'':
            print("Read Fail")
            ser.close()
            break
        c = int.from_bytes(R, byteorder='big')
        # print("data", c)
        if flag > 0:
            if ib < BUF_SIZE:
                buf[ib] = c
                ib += 1
            if ib == 8:
                if buf[6] == 0x56 and buf[7] == 0x78:
                    Encoder = (buf[3] << 8) + buf[2]
                    Adc= (buf[5] << 8) + buf[4]
                    receive_result = [Encoder, Adc]
                    break
                else:
                    print("CRC Fail")
                flag = 0
        if flag == 0:
            if c1 == 0x12 and c == 0x34:
                flag = 1
                ib = 2
        c1 = c
    return receive_result
接收数据:编码器(整型)、角位移传感器(浮点型)
# 从串口接收的数据为:电机位置(整型)、电机速度(浮点型)
def read_serial_one_data_motor_position_velocity(ser):
    global receive_result
    BUF_SIZE = 10
    buf = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x78])
    c1 = c2 = ib = flag = 0

    while True:
        R = ser.read(1)
        # print("data", R)
        if R == b'':
            print("Read Fail")
            ser.close()
            break
        c = int.from_bytes(R, byteorder='big')
        # print("data", c)
        if flag > 0:
            if ib < BUF_SIZE:
                buf[ib] = c
                ib += 1
            if ib == 8:
                if buf[8] == 0x56 and buf[9] == 0x78:
                    motor_position = (buf[3] << 8) + buf[2]
                    # motor_veclocity = (buf[7] << 24) +(buf[6] << 16) +(buf[5] << 8) + buf[4]
                    motor_veclocity = Byte2Float(buf[4:8])
                    receive_result = [motor_position, motor_veclocity]
                    break
                else:
                    print("CRC Fail")
                flag = 0
        if flag == 0:
            if c1 == 0x12 and c == 0x34:
                flag = 1
                ib = 2
        c1 = c
    return receive_result

2-1 串口发送端python

action = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x56, 0x78])
action_ = int(control_motor(result[0], result[1]))
print("action_", action_)
# 将action转化成字符串
action[0] = 0x2D   # 帧头
action[1] = 0x01   # 校验位,具体未实现,用0x01替代
if action_ < 0:
    action[2] = 0x45   # 符号位
    action[3] = action_  & 0xFF    # 数据位
    action[4] = (action_ >>8) & 0xFF  # 数据位
    action[5] = 0x0d   # 0x56是十六进制表示法,表示的是十进制数值86。而V是英文字母,它在ASCII码中的十进制表示是86。所以,0x56和V表示的是同一个字符。
    action[6] = 0x0a   # 0x78是十六进制表示法,表示的是十进制数值120。而x是英文字母,它在ASCII码中的十进制表示是120。所以,0x78和x表示的是同一个字符。

    for byte in action: # 一个一个字节发送 ,一次发送多个字节容易出错
        ser.write(byte.to_bytes(1, 'big'))

2-2 串口接收端stm32

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res = USART_ReceiveData(USART1);	//读取接收到的数据 0x2D,0x01,0x30,0x30,0x30,0x0D,0x0A
		printf("%02X", Res);
				if((USART_RX_STA&0x8000)==0)//接收未完成
					{
					if(USART_RX_STA&0x4000)//接收到了0x0D
						{
							if(Res!=0x0A){
								USART_RX_STA=0;//接收错误,重新开始
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA|=0x8000;	//接收完成了
								
//								check_flag = count_odd_numbers();
//								USART_RX_BUF[1] = USART_RX_BUF[1] - '0';
								if(USART_RX_BUF[0] == 0x2D && USART_RX_BUF[1] == 0x01 ) // 判断帧头是否正确、判断奇偶校验位是否正确 || USART_RX_BUF[1] == check_flag
								{
									float value = 0;
									int16_t sign = 1;
										if(USART_RX_BUF[2] == 0x45)
										{
											sign = -1;
										}

										  value = (USART_RX_BUF[4] << 8) + USART_RX_BUF[3];	
			
											action = sign * value;
											USART_RX_STA = 0;	
											memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA = 0;	
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
						}								
						}
					else //还没收到0X0D
						{	
							if(Res==0x0D)
								USART_RX_STA|=0x4000;
							else
								{					
										USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
										USART_RX_STA++;
										if(USART_RX_STA>(USART_REC_LEN-1))
										{
											USART_RX_STA=0;//接收数据错误,重新开始接收
											memset(USART_RX_BUF,0,USART_REC_LEN);
										}					
								}		 
						}
					}

				 } 
}
	
文章来源:https://blog.csdn.net/shouchen1/article/details/132092367
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。