#include "usartx.h" SEND_DATA Send_Data; RECEIVE_DATA Receive_Data; extern int Time_count; //Sample timestamps written by the acquisition tasks (see usartx.h). //Session ID stays constant for one MCU boot; a fixed nonzero marker is //enough for the host to detect a restart (counter cleared to 0). //�ɲɼ�����д��IJ���ʱ���(�� usartx.h)���ỰID�ڱ���������������䣬 //�̶���0ֵ���ϴ��������ʶ���ػ��� volatile unsigned long long g_speed_sample_time_us = 0; volatile unsigned long long g_imu_sample_time_us = 0; volatile unsigned int g_session_id = 0xA5A5A5A5U; /************************************************************************** Function: Usartx3, Usartx1,Usartx5 and CAN send data task Input : none Output : none �������ܣ�����3������1������5��CAN������������ ��ڲ������� ���� ֵ���� **************************************************************************/ void data_task(void *pvParameters) { u32 lastWakeTime = getSysTickCnt(); while(1) { //The task is run at 200hz. Only ROS (USART3) is sent, via non-blocking DMA. //��������200Hz��Ƶ��������ֻ��ROS(����3)��������DMA���巢�͡� vTaskDelayUntil(&lastWakeTime, F2T(RATE_200_HZ)); //Assign the data to be sent //��Ҫ���з��͵����ݽ��и�ֵ data_transition(); USART3_SEND(); //Serial port 3 (ROS) sends data //����3(ROS)�������� } } /************************************************************************** Function: The data sent by the serial port is assigned Input : none Output : none �������ܣ����ڷ��͵����ݽ��и�ֵ ��ڲ������� ���� ֵ���� **************************************************************************/ void data_transition(void) { Send_Data.Sensor_Str.Frame_Header = FRAME_HEADER; //Frame_header //֡ͷ Send_Data.Sensor_Str.Frame_Tail = FRAME_TAIL; //Frame_tail //֡β //According to different vehicle types, different kinematics algorithms were selected to carry out the forward kinematics solution, //and the three-axis velocity was obtained from each wheel velocity //���ݲ�ͬ����ѡ��ͬ�˶�ѧ�㷨�����˶�ѧ���⣬�Ӹ������ٶ���������ٶ� switch(Car_Mode) { case Mec_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4)*1000; Send_Data.Sensor_Str.Y_speed = ((MOTOR_A.Encoder-MOTOR_B.Encoder+MOTOR_C.Encoder-MOTOR_D.Encoder)/4)*1000; Send_Data.Sensor_Str.Z_speed = ((-MOTOR_A.Encoder-MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4/(Axle_spacing+Wheel_spacing))*1000; break; case Omni_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_C.Encoder-MOTOR_B.Encoder)/2/X_PARAMETER)*1000; Send_Data.Sensor_Str.Y_speed = ((MOTOR_A.Encoder*2-MOTOR_B.Encoder-MOTOR_C.Encoder)/3)*1000; Send_Data.Sensor_Str.Z_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder)/3/Omni_turn_radiaus)*1000; break; case Akm_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000; Send_Data.Sensor_Str.Y_speed = 0; Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/Wheel_spacing)*1000; break; case Diff_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000; Send_Data.Sensor_Str.Y_speed = 0; Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/Wheel_spacing)*1000; break; case FourWheel_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4)*1000; Send_Data.Sensor_Str.Y_speed = 0; Send_Data.Sensor_Str.Z_speed = ((-MOTOR_B.Encoder-MOTOR_A.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/2/(Axle_spacing+Wheel_spacing))*1000; break; case Tank_Car: Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000; Send_Data.Sensor_Str.Y_speed = 0; Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/(Wheel_spacing)*1000); break; } //The acceleration of the triaxial acceleration //���ٶȼ�������ٶ� Send_Data.Sensor_Str.Accelerometer.X_data= accel[1]; //The accelerometer Y-axis is converted to the ros coordinate X axis //���ٶȼ�Y��ת����ROS����X�� Send_Data.Sensor_Str.Accelerometer.Y_data=-accel[0]; //The accelerometer X-axis is converted to the ros coordinate y axis //���ٶȼ�X��ת����ROS����Y�� Send_Data.Sensor_Str.Accelerometer.Z_data= accel[2]; //The accelerometer Z-axis is converted to the ros coordinate Z axis //���ٶȼ�Z��ת����ROS����Z�� //The Angle velocity of the triaxial velocity //���ٶȼ�������ٶ� Send_Data.Sensor_Str.Gyroscope.X_data= gyro[1]; //The Y-axis is converted to the ros coordinate X axis //���ٶȼ�Y��ת����ROS����X�� Send_Data.Sensor_Str.Gyroscope.Y_data=-gyro[0]; //The X-axis is converted to the ros coordinate y axis //���ٶȼ�X��ת����ROS����Y�� if(Flag_Stop==0) //If the motor control bit makes energy state, the z-axis velocity is sent normall //����������λʹ��״̬����ô��������Z����ٶ� Send_Data.Sensor_Str.Gyroscope.Z_data=gyro[2]; else //If the robot is static (motor control dislocation), the z-axis is 0 //����������Ǿ�ֹ�ģ��������λʧ�ܣ�����ô���͵�Z����ٶ�Ϊ0 Send_Data.Sensor_Str.Gyroscope.Z_data=0; //Battery voltage (this is a thousand times larger floating point number, which will be reduced by a thousand times as well as receiving the data). //��ص�ѹ(���ォ�������Ŵ�һǧ�����䣬��Ӧ���ڽ��ն��ڽ��յ����ݺ�Ҳ����Сһǧ��) Send_Data.Sensor_Str.Power_Voltage = Voltage*1000; Send_Data.buffer[0]=Send_Data.Sensor_Str.Frame_Header; //Frame_heade //֡ͷ Send_Data.buffer[1]=Flag_Stop; //Car software loss marker //С������ʧ�ܱ�־λ //The three-axis speed of / / car is split into two eight digit Numbers //С�������ٶ�,���ᶼ���Ϊ����8λ�����ٷ��� Send_Data.buffer[2]=Send_Data.Sensor_Str.X_speed >>8; Send_Data.buffer[3]=Send_Data.Sensor_Str.X_speed ; Send_Data.buffer[4]=Send_Data.Sensor_Str.Y_speed>>8; Send_Data.buffer[5]=Send_Data.Sensor_Str.Y_speed; Send_Data.buffer[6]=Send_Data.Sensor_Str.Z_speed >>8; Send_Data.buffer[7]=Send_Data.Sensor_Str.Z_speed ; //The acceleration of the triaxial axis of / / imu accelerometer is divided into two eight digit reams //IMU���ٶȼ�������ٶ�,���ᶼ���Ϊ����8λ�����ٷ��� Send_Data.buffer[8]=Send_Data.Sensor_Str.Accelerometer.X_data>>8; Send_Data.buffer[9]=Send_Data.Sensor_Str.Accelerometer.X_data; Send_Data.buffer[10]=Send_Data.Sensor_Str.Accelerometer.Y_data>>8; Send_Data.buffer[11]=Send_Data.Sensor_Str.Accelerometer.Y_data; Send_Data.buffer[12]=Send_Data.Sensor_Str.Accelerometer.Z_data>>8; Send_Data.buffer[13]=Send_Data.Sensor_Str.Accelerometer.Z_data; //The axis of the triaxial velocity of the / /imu is divided into two eight digits //IMU���ٶȼ�������ٶ�,���ᶼ���Ϊ����8λ�����ٷ��� Send_Data.buffer[14]=Send_Data.Sensor_Str.Gyroscope.X_data>>8; Send_Data.buffer[15]=Send_Data.Sensor_Str.Gyroscope.X_data; Send_Data.buffer[16]=Send_Data.Sensor_Str.Gyroscope.Y_data>>8; Send_Data.buffer[17]=Send_Data.Sensor_Str.Gyroscope.Y_data; Send_Data.buffer[18]=Send_Data.Sensor_Str.Gyroscope.Z_data>>8; Send_Data.buffer[19]=Send_Data.Sensor_Str.Gyroscope.Z_data; //Battery voltage, split into two 8 digit Numbers //��ص�ѹ,���Ϊ����8λ���ݷ��� Send_Data.buffer[20]=Send_Data.Sensor_Str.Power_Voltage >>8; Send_Data.buffer[21]=Send_Data.Sensor_Str.Power_Voltage; //Snapshot the session ID and the two sample timestamps captured by the //acquisition tasks. All appended fields are big-endian (high byte first) //to match the existing >>8 speed/IMU packing. //�������Բɼ�������¼�ĻỰID��������ʱ�����׷���ֶ��þ���(��λ��ǰ)�� //�����е� >>8 ���/IMU�����ʽһ�¡� Send_Data.Sensor_Str.Session_Id = g_session_id; Send_Data.Sensor_Str.Speed_Time_us = g_speed_sample_time_us; Send_Data.Sensor_Str.Imu_Time_us = g_imu_sample_time_us; //session_id (uint32, big-endian) //�ỰID Send_Data.buffer[22]=(unsigned char)(Send_Data.Sensor_Str.Session_Id>>24); Send_Data.buffer[23]=(unsigned char)(Send_Data.Sensor_Str.Session_Id>>16); Send_Data.buffer[24]=(unsigned char)(Send_Data.Sensor_Str.Session_Id>>8); Send_Data.buffer[25]=(unsigned char)(Send_Data.Sensor_Str.Session_Id); //speed_sample_time_us (uint64, big-endian) //�ٶȲ���ʱ��� Send_Data.buffer[26]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>56); Send_Data.buffer[27]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>48); Send_Data.buffer[28]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>40); Send_Data.buffer[29]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>32); Send_Data.buffer[30]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>24); Send_Data.buffer[31]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>16); Send_Data.buffer[32]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us>>8); Send_Data.buffer[33]=(unsigned char)(Send_Data.Sensor_Str.Speed_Time_us); //imu_sample_time_us (uint64, big-endian) //IMU����ʱ��� Send_Data.buffer[34]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>56); Send_Data.buffer[35]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>48); Send_Data.buffer[36]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>40); Send_Data.buffer[37]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>32); Send_Data.buffer[38]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>24); Send_Data.buffer[39]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>16); Send_Data.buffer[40]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us>>8); Send_Data.buffer[41]=(unsigned char)(Send_Data.Sensor_Str.Imu_Time_us); //Data check digit calculation, Pattern 1 is a data check. Now covers the //42 payload bytes (0..41) preceding the checksum. //����У��λ���㣬ģʽ1�Ƿ�������У�顣����������У��ǰ 42 �ֽ�(0..41)�� Send_Data.buffer[42]=Check_Sum(42,1); Send_Data.buffer[43]=Send_Data.Sensor_Str.Frame_Tail; //Frame_tail //֡β } /************************************************************************** Function: Serial port 1 sends data Input : none Output : none �������ܣ�����1�������� ��ڲ������� ���� ֵ���� **************************************************************************/ void USART1_SEND(void) { unsigned char i = 0; for(i=0; iperipheral, one-shot per frame) �������ܣ�����3����DMA��ʼ�����ڴ�->���裬ÿ֡����һ�Σ� DMA1 Stream3 Channel4 is the TX request line for USART3 on STM32F407. STM32F407 �ϴ���3�ķ���DMA����ΪDMA1_Stream3_Channel4�� **************************************************************************/ void uart3_dma_tx_init(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); DMA_DeInit(DMA1_Stream3); while(DMA_GetCmdStatus(DMA1_Stream3) != DISABLE); DMA_InitStructure.DMA_Channel = DMA_Channel_4; DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR; DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Send_Data.buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = SEND_DATA_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream3, &DMA_InitStructure); USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE); } /************************************************************************** Function: Serial port 5 initialization Input : none Output : none �������ܣ�����5��ʼ�� ��ڲ������� ���� ֵ���� **************************************************************************/ void uart5_init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //PC12 TX RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //Enable the gpio clock //ʹ��GPIOʱ�� //PD2 RX RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Enable the gpio clock //ʹ��GPIOʱ�� RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); //Enable the Usart clock //ʹ��USARTʱ�� GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_UART5); GPIO_PinAFConfig(GPIOD,GPIO_PinSource2 ,GPIO_AF_UART5); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //���ģʽ GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //������� GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //����50MHZ GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //���� GPIO_Init(GPIOC, &GPIO_InitStructure); //��ʼ�� GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //���ģʽ GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //������� GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //����50MHZ GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //���� GPIO_Init(GPIOD, &GPIO_InitStructure); //��ʼ�� //UsartNVIC configuration //UsartNVIC���� NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; //Preempt priority //��ռ���ȼ� NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ; //Preempt priority //��ռ���ȼ� NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Enable the IRQ channel //IRQͨ��ʹ�� NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Initialize the VIC register with the specified parameters //����ָ���IJ�����ʼ��VIC�Ĵ��� NVIC_Init(&NVIC_InitStructure); //USART Initialization Settings ��ʼ������ USART_InitStructure.USART_BaudRate = bound; //Port rate //���ڲ����� USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //�ֳ�Ϊ8λ���ݸ�ʽ USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //һ��ֹͣ USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //����żУ��λ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //��Ӳ������������ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //�շ�ģʽ USART_Init(UART5, &USART_InitStructure); //Initialize serial port 5 //��ʼ������5 USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //�������ڽ����ж� USART_Cmd(UART5, ENABLE); //Enable serial port 5 //ʹ�ܴ���5 } /************************************************************************** Function: Serial port 1 receives interrupted Input : none Output : none �������ܣ�����1�����ж� ��ڲ������� �� �� ֵ���� **************************************************************************/ int USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //Check if data is received //�ж��Ƿ���յ����� { u8 Usart_Receive; static u8 Count; static u8 rxbuf[11]; int check=0,error=1,i; Usart_Receive = USART_ReceiveData(USART1); //Read the data //��ȡ���� if(Time_count0) Count++; else Count=0; if (Count == 11) //Verify the length of the packet //��֤���ݰ��ij��� { Count=0; //Prepare for the serial port data to be refill into the array //Ϊ����������������������׼�� if(rxbuf[10] == FRAME_TAIL) //Verify the frame tail of the packet //��֤���ݰ���֡β { for(i=0; i<9; i++) { //XOR bit check, used to detect data error //���λУ�飬���ڼ�������Ƿ���� check=rxbuf[i]^check; } if(check==rxbuf[9]) //XOR bit check successful //���λУ��ɹ� error=0; if(error==0) { float Vz; if(Usart1_ON_Flag==0) { //Serial port 1 controls flag position 1, other flag position 0 //����1���Ʊ�־λ��1��������־λ��0 //Usart_ON_Flag=1; Usart1_ON_Flag=1; APP_ON_Flag=0; PS2_ON_Flag=0; Remote_ON_Flag=0; CAN_ON_Flag=0; } command_lost_count=0; //CAN/���ڿ������ʧ�������� //Calculate the 3-axis target velocity from the serial data, which is divided into 8-bit high and 8-bit low units mm/s //�Ӵ�������������Ŀ���ٶȣ��ָ�8λ�͵�8λ ��λmm/s Move_X=XYZ_Target_Speed_transition(rxbuf[3],rxbuf[4]); Move_Y=XYZ_Target_Speed_transition(rxbuf[5],rxbuf[6]); Vz =XYZ_Target_Speed_transition(rxbuf[7],rxbuf[8]); // Ackermann: pass the raw rotation speed wz [rad/s] straight // through. Drive_Motor derives curvature kappa = wz/v itself, // so no front-wheel-angle pre-conversion here. Move_Z=Vz; } } } } return 0; } /************************************************************************** Function: Refresh the OLED screen Input : none Output : none �������ܣ�����2�����ж� ��ڲ������� ���� ֵ���� **************************************************************************/ int USART2_IRQHandler(void) { int Usart_Receive; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //Check if data is received //�ж��Ƿ���յ����� { static u8 Flag_PID,i,j,Receive[50],Last_Usart_Receive; static float Data; Usart_Receive=USART2->DR; //Read the data //��ȡ���� if(Deviation_Count=0x41&&Usart_Receive<=0x48) { Flag_Direction=Usart_Receive-0x40; } else if(Usart_Receive<=8) { Flag_Direction=Usart_Receive; } else Flag_Direction=0; } else if(Turn_Flag==1) { //APP steering control interface command //APPת����ƽ������� if (Usart_Receive==0x43) Flag_Left=0,Flag_Right=1; //Right rotation //����ת else if(Usart_Receive==0x47) Flag_Left=1,Flag_Right=0; //Left rotation //����ת else Flag_Left=0,Flag_Right=0; if (Usart_Receive==0x41||Usart_Receive==0x45) Flag_Direction=Usart_Receive-0x40; else Flag_Direction=0; } if(Usart_Receive==0x58) RC_Velocity=RC_Velocity+100; //Accelerate the keys, +100mm/s //���ٰ�����+100mm/s if(Usart_Receive==0x59) RC_Velocity=RC_Velocity-100; //Slow down buttons, -100mm/s //���ٰ�����-100mm/s // The following is the communication with the APP debugging interface //��������APP���Խ���ͨѶ if(Usart_Receive==0x7B) Flag_PID=1; //The start bit of the APP parameter instruction //APP����ָ����ʼλ if(Usart_Receive==0x7D) Flag_PID=2; //The APP parameter instruction stops the bit //APP����ָ��ֹͣλ if(Flag_PID==1) //Collect data //�ɼ����� { Receive[i]=Usart_Receive; i++; } if(Flag_PID==2) //Analyze the data //�������� { if(Receive[3]==0x50) PID_Send=1; else if(Receive[1]!=0x23) { for(j=i;j>=4;j--) { Data+=(Receive[j-1]-48)*pow(10,i-j); } switch(Receive[1]) { case 0x30: RC_Velocity=Data;break; case 0x31: Velocity_KP=Data;break; case 0x32: Velocity_KI=Data;break; case 0x33: break; case 0x34: break; case 0x35: break; case 0x36: break; case 0x37: break; case 0x38: break; } } //Relevant flag position is cleared //��ر�־λ���� Flag_PID=0; i=0; j=0; Data=0; memset(Receive, 0, sizeof(u8)*50); //Clear the array to zero//�������� } if(RC_Velocity<0) RC_Velocity=0; } return 0; } /************************************************************************** Function: Serial port 3 receives interrupted Input : none Output : none �������ܣ�����3�����ж� ��ڲ������� ���� ֵ���� **************************************************************************/ float test_movz = 0; int USART3_IRQHandler(void) { static u8 Count=0; u8 Usart_Receive; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //Check if data is received //�ж��Ƿ���յ����� { Usart_Receive = USART_ReceiveData(USART3);//Read the data //��ȡ���� if(Time_count0) Count++; else Count=0; if (Count == 11) //Verify the length of the packet //��֤���ݰ��ij��� { Count=0; //Prepare for the serial port data to be refill into the array //Ϊ����������������������׼�� if(Receive_Data.buffer[10] == FRAME_TAIL) //Verify the frame tail of the packet //��֤���ݰ���֡β { //Data exclusionary or bit check calculation, mode 0 is sent data check //�������λУ����㣬ģʽ0�Ƿ�������У�� if(Receive_Data.buffer[9] ==Check_Sum(9,0)) { float Vz; //All modes flag position 0, USART3 control mode //����ģʽ��־λ��0��ΪUsart3����ģʽ PS2_ON_Flag=0; Remote_ON_Flag=0; APP_ON_Flag=0; CAN_ON_Flag=0; Usart1_ON_Flag=0; Usart5_ON_Flag=0; command_lost_count=0; //CAN/���ڿ������ʧ�������� //Calculate the target speed of three axis from serial data, unit m/s //�Ӵ�������������Ŀ���ٶȣ� ��λm/s Move_X=XYZ_Target_Speed_transition(Receive_Data.buffer[3],Receive_Data.buffer[4]); Move_Y=XYZ_Target_Speed_transition(Receive_Data.buffer[5],Receive_Data.buffer[6]); Vz =XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]); test_movz = Vz; // Ackermann: pass the raw rotation speed wz [rad/s] straight // through; Drive_Motor derives curvature kappa = wz/v itself. Move_Z=Vz; } } } } return 0; } /************************************************************************** Function: Serial port 5 receives interrupted Input : none Output : none �������ܣ�����5�����ж� ��ڲ������� ���� ֵ���� **************************************************************************/ int UART5_IRQHandler(void) { static u8 Count=0; u8 Usart_Receive; if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //Check if data is received //�ж��Ƿ���յ����� { Usart_Receive = USART_ReceiveData(UART5);//Read the data //��ȡ���� if(Time_count0) Count++; else Count=0; if (Count == 11) //Verify the length of the packet //��֤���ݰ��ij��� { Count=0; //Prepare for the serial port data to be refill into the array //Ϊ����������������������׼�� if(Receive_Data.buffer[10] == FRAME_TAIL) //Verify the frame tail of the packet //��֤���ݰ���֡β { //Data exclusionary or bit check calculation, mode 0 is sent data check //�������λУ����㣬ģʽ0�Ƿ�������У�� if(Receive_Data.buffer[9] ==Check_Sum(9,0)) { float Vz; //All modes flag position 0, USART3 control mode //����ģʽ��־λ��0��ΪUsart5����ģʽ PS2_ON_Flag=0; Remote_ON_Flag=0; APP_ON_Flag=0; CAN_ON_Flag=0; Usart5_ON_Flag=0; command_lost_count=0; //CAN/���ڿ������ʧ�������� //Calculate the target speed of three axis from serial data, unit m/s //�Ӵ�������������Ŀ���ٶȣ� ��λm/s Move_X=XYZ_Target_Speed_transition(Receive_Data.buffer[3],Receive_Data.buffer[4]); Move_Y=XYZ_Target_Speed_transition(Receive_Data.buffer[5],Receive_Data.buffer[6]); Vz =XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]); // Ackermann: pass the raw rotation speed wz [rad/s] straight // through; Drive_Motor derives curvature kappa = wz/v itself. Move_Z=Vz; } } } } return 0; } /************************************************************************** Function: After the top 8 and low 8 figures are integrated into a short type data, the unit reduction is converted Input : 8 bits high, 8 bits low Output : The target velocity of the robot on the X/Y/Z axis �������ܣ�����λ��������Ŀ��ǰ���ٶ�Vx��Ŀ����ٶ�Vz��ת��Ϊ������С������ǰ��ת�� ��ڲ�����Ŀ��ǰ���ٶ�Vx��Ŀ����ٶ�Vz����λ��m/s��rad/s ���� ֵ��������С������ǰ��ת�ǣ���λ��rad **************************************************************************/ float test_z=0; float Vz_to_Akm_Angle(float Vx, float Vz) { float R, CenterAngle; /* Move_Z is the vehicle center steering angle in radians. */ if(Vz!=0 && Vx!=0) { /* R is the turning radius of the vehicle centerline. */ /* Vx sets radius magnitude only; Vz owns the steering direction. */ R=float_abs(Vx)/float_abs(Vz); CenterAngle=(Vz >= 0.0f ? 1.0f : -1.0f) * atan(Axle_spacing/R); } else { CenterAngle=0; } test_z = CenterAngle; return CenterAngle; } /************************************************************************** Function: After the top 8 and low 8 figures are integrated into a short type data, the unit reduction is converted Input : 8 bits high, 8 bits low Output : The target velocity of the robot on the X/Y/Z axis �������ܣ�����λ���������ĸ�8λ�͵�8λ�������ϳ�һ��short�����ݺ�������λ��ԭ���� ��ڲ�������8λ����8λ ���� ֵ��������X/Y/Z���Ŀ���ٶ� **************************************************************************/ float XYZ_Target_Speed_transition(u8 High,u8 Low) { //Data conversion intermediate variable //����ת�����м���� short transition; //����8λ�͵�8λ���ϳ�һ��16λ��short������ //The high 8 and low 8 bits are integrated into a 16-bit short data transition=((High<<8)+Low); return transition/1000+(transition%1000)*0.001; //Unit conversion, mm/s->m/s //��λת��, mm/s->m/s } /************************************************************************** Function: Serial port 1 sends data Input : The data to send Output : none �������ܣ�����1�������� ��ڲ�����Ҫ���͵����� ���� ֵ���� **************************************************************************/ void usart1_send(u8 data) { USART1->DR = data; while((USART1->SR&0x40)==0); } /************************************************************************** Function: Serial port 2 sends data Input : The data to send Output : none �������ܣ�����2�������� ��ڲ�����Ҫ���͵����� ���� ֵ���� **************************************************************************/ void usart2_send(u8 data) { USART2->DR = data; while((USART2->SR&0x40)==0); } /************************************************************************** Function: Serial port 3 sends data Input : The data to send Output : none �������ܣ�����3�������� ��ڲ�����Ҫ���͵����� ���� ֵ���� **************************************************************************/ void usart3_send(u8 data) { USART3->DR = data; while((USART3->SR&0x40)==0); } /************************************************************************** Function: Serial port 5 sends data Input : The data to send Output : none �������ܣ�����5�������� ��ڲ�����Ҫ���͵����� ���� ֵ���� **************************************************************************/ void usart5_send(u8 data) { UART5->DR = data; while((UART5->SR&0x40)==0); } /************************************************************************** Function: Calculates the check bits of data to be sent/received Input : Count_Number: The first few digits of a check; Mode: 0-Verify the received data, 1-Validate the sent data Output : Check result �������ܣ�����Ҫ����/���յ�����У���� ��ڲ�����Count_Number��У���ǰ��λ����Mode��0-�Խ������ݽ���У�飬1-�Է������ݽ���У�� ���� ֵ��У���� **************************************************************************/ u8 Check_Sum(unsigned char Count_Number,unsigned char Mode) { unsigned char check_sum=0,k; //Validate the data to be sent //��Ҫ���͵����ݽ���У�� if(Mode==1) for(k=0;k