.h文件

#ifndef VOFA_H
#define VOFA_H
 
#include "usart.h"
#include <string.h>
 
/*在接收空闲中断里接收不定长VOFA指令,再调用VOFA数据解析函数即可*/
 
/********************************************
函数功能:将接收到的ASCII编码数据转化成double类型
参数:1.存放VOFA指令的数组的指针
	 2.一个double类型的指针,用于存放解析好的数据
返回值:用于区分数据类型 如:1-Kp 2-Ki 3-Kd 4-TargetSpeed
*********************************************/
int VOFA_Data_to_double(char *arr_Data,double *Data);
 
//用于处理小数点后的数字
float Pow_invert(uint8_t X,uint8_t n);
 
#endif
 

.c文件

#include "VOFA.h"
 
//用于处理小数点后的数字
float Pow_invert(uint8_t X,uint8_t n)//x除以n次10
{
    float result=X;
    while(n--)
	{
		result/=10;
	}
	return result;
}
 
// 解析数据 P1-Kp P2-Ki P3-Kd P4-TargetSpeed   格式:#P1=%f!  
int VOFA_Data_to_double(char *arr_Data,double *Data)
{
	// 状态机,用于记录当前进程
    int State = 0;
    // 小数点标志,用于开启小数处理
    int dot_Flag = 0;
    int dot_after_num=0;
    // 标记接收到的数据类型,是P是I还是D......
    int PID_Flag=0;
    
    *Data = 0;//使用前先初始化为0,避免上次的数据堆积
    for(int index=0;index<strlen(arr_Data);index++)
    {
        if(State == 0&&arr_Data[index]==0x23) //帧起始位‘#’:0x23
        {
            State = 1;
        }
        else if(State == 1&&arr_Data[index]==0x50)//‘P’:0x50
        {
            State = 2;
        }
        else if(State == 2)
        {
            PID_Flag = arr_Data[index]-48; //减48转换成int,标记数据类型
            State = 3;
        }
        else if(State == 3&&arr_Data[index]==0x3D)// 数据起始位“=”:0x3D
        {
            State = 4;
        }
        else if(State==4&&arr_Data[index]!=0x21)
        {
            if(dot_Flag==0)
            {
              if(arr_Data[index]==0x2E)//如果识别到小数点,则将dot_Flag置1
              {
                dot_Flag=1;
              }
              else//还没遇到小数点前的运算
              {
                *Data = *Data*10 + arr_Data[index]-48;
              }
            }
            else//遇到小数点后的运算
            {
              *Data = *Data + Pow_invert(arr_Data[index]-48,dot_after_num);
              dot_after_num++;
            }
        }
        else if(State==4&&arr_Data[index]==0x21)//读到数据截止位!:0x21
        {
            State = 0;
            return PID_Flag;
        }
    }
    return PID_Flag;
}
 

main.c

//关闭接收过半中断需要
extern DMA_HandleTypeDef hdma_usart2_rx;
 
 
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart == &huart2)
    {
        int PID_Flag;
        double PID_Data;
        PID_Flag=VOFA_Data_to_double(arr_vofa,&PID_Data);
        
        //1-Kp 2-Ki 3-Kd 4-TargetSpeed
        if(PID_Flag==1)
        {
            DCMOTOR_A.Kp=PID_Data;
        }
        else if(PID_Flag==2)
        {
            DCMOTOR_A.Ki=PID_Date;
        }
        else if(PID_Flag==3)
        {
            DCMOTOR_A.Kd=PID_Date;
        }
        else if(PID_Flag==4)
        {
            DCMOTOR_A.Target=PID_Date;
        }
    }
        
    // 开启下一次数据接收
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2,(uint8_t *)arr_vofa,sizeof(arr_vofa));
    // 关闭接收过半中断
    __HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
}