[野火]电机应用开发实战指南 — [野火]电机应用开发实战指南—基于STM32 文档 (embedfire.com)Embedfire-motor: 野火电机项目组 (gitee.com) 野火pid助手协议的源代码
一、源代码的移植与使用
1.在移植之前首先拥有一个写好pid的电机调速代码,想要使用野火多功能pid调式助手,需要在写好的工程里面添加“下位机与上位机通信的协议”
2.①需要将【野火pid助手协议的源代码】中的protocol文件夹移植到你自己写好的工程里面,然后再需要修改其中的两个函数,因为函数调用了一些其他我们自己工程里面没有的函数
分别是这两个函数receiving_process(void)、
set_computer_value(uint8_t cmd, uint8_t ch, void *data, uint8_t num)
其他protocol文件里面的函数不用修改
在修改set_computer_value(uint8_t cmd, uint8_t ch, void *data, uint8_t num)
这个函数时,将里面的这三行:
HAL_UART_Transmit(&UartHandle, (uint8_t *)&set_packet, sizeof(set_packet), 0xFFFFF); // 发送数据头
HAL_UART_Transmit(&UartHandle, (uint8_t *)data, num, 0xFFFFF); // 发送参数
HAL_UART_Transmit(&UartHandle, (uint8_t *)&sum, sizeof(sum), 0xFFFFF); // 发送校验和
变成了这:
usart1_send((uint8_t *)&set_packet, sizeof(set_packet)); // 发送数据头
usart1_send((uint8_t *)data, num); // 发送参数
usart1_send((uint8_t *)&sum, sizeof(sum)); // 发送校验和
void usart1_send(u8*data, u8 len)
{
u8 i;
for(i=0;i<len;i++)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
USART_SendData(USART1,data[i]);
}
}
receiving_process这个函数修改了每个case下对应的操作,如SET_P_I_D_CMD,你要改成你自己的存pid的变量mypid,目标值你要对应你自己的目标值存储变量Target_Pulse
int8_t receiving_process(void)
{
uint8_t frame_data[128]; // 要能放下最长的帧
uint16_t frame_len = 0; // 帧长度
uint8_t cmd_type = CMD_NONE; // 命令类型
while(1)
{
cmd_type = protocol_frame_parse(frame_data, &frame_len);
switch (cmd_type)
{
case CMD_NONE:
{
return -1;
}
case SET_P_I_D_CMD:
{
uint32_t temp0 = COMPOUND_32BIT(&frame_data[13]);
uint32_t temp1 = COMPOUND_32BIT(&frame_data[17]);
uint32_t temp2 = COMPOUND_32BIT(&frame_data[21]);
float p_temp, i_temp, d_temp;
p_temp = *(float *)&temp0;
i_temp = *(float *)&temp1;
d_temp = *(float *)&temp2;
// 设置 P I D
mypid.kp=p_temp;
mypid.ki=i_temp;
mypid.kd=d_temp;
}
break;
case SET_TARGET_CMD:
{
int actual_temp = COMPOUND_32BIT(&frame_data[13]); // 得到数据
// 设置目标值
Target_Pulse=actual_temp;
}
break;
case START_CMD:
{
TIM_Cmd(TIM4, ENABLE); // 启动电机
}
break;
case STOP_CMD:
{
TIM_Cmd(TIM4, DISABLE); // 停止电机
}
break;
case RESET_CMD:
{
NVIC_SystemReset(); // 复位系统
}
break;
case SET_PERIOD_CMD:
{
// uint32_t temp = COMPOUND_32BIT(&frame_data[13]); // 周期数
// TIM2->ARR=temp*100;// 设置定时器周期1~1000ms
}
break;
default:
return -1;
}
}
}
②按照【野火pid助手协议的源代码】修改串口中断函数
uint8_t a=USART1->DR;
protocol_data_recv(&a, 1);
③在负责定时采集编码器数据的定时器中断函数与主函数中的while(1)中添加
while (1)
{
receiving_process();
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update))
{
gspeed=Read_EncoderB()*60/(SampleCircle_100*0.01*4*50);
PID_Calc(&mypid,TargetVelocity,gspeed);
carry_pid(mypid.output);
set_computer_value(SEND_FACT_CMD, CURVES_CH1, &gspeed, 1);
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
【发现:减小采样时间,可以加快响应时间!!!】 如下图“100倍采样时间”由45变成20