.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);
}