STM32CubeMX-----配置带编码器电机的测速
前言
提示:带编码器的电机很常用,用电机肯定需要测速测速,再搞搞pid啥的,最近刚上手STM32CubeMX,在这里做个记录。
我用的是STM32F103ZET6
一、STM32CubeMX环境配置
1.配置定时器TIM3为编码器模式
2.配置基本定时器TIM6为定时器
Tclk就是你的时钟频率,我的是用PLL达到了72Mhz,所以Tclk=72M
5.配置串口1
我要用串口一发送数据给上位机,看电机的波形,所以要配置串口
4.开启TIM6中断
因为我是50ms采样一次速度值,如果一直采样的话对cpu负担挺重,而等间隔采用不仅准确(意外波动小)还能减少cpu负担,从而处理更多事件。配置中断当然在NVIC里面配置
这里有个注意的地方就是,中断的开启需要你自己去开启,CUBeMX做的只是帮我们初始化。
__HAL_TIM_CLEAR_FLAG(&htim6,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim6);
二、代码
1.读取单位时间内脉冲变化值
s16 getTIMx_DetaCnt(TIM_TypeDef * TIMx) //读取单位时间内脉冲变化值
{
s16 cnt;
cnt = TIMx->CNT-0x7fff;
TIMx->CNT = 0x7fff;
return cnt;
}
2.通过计算得到速度数据
void Get_Motor_Speed(int *leftSpeed)
{
*leftSpeed = getTIMx_DetaCnt(TIM3)*X;
}
X就是你要怎么算,按照你想要的结果来写入,因为getTIMx_DetaCnt(TIM3)已经是单位时间内的脉冲数了,相当于已经得到一个初始速度数据。
3.通过中断采样50ms一次
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&htim6))//因为我采用的是定时器6
{
Get_Motor_Speed(&leftSpeedNow);
//Test_Send_User(leftSpeedNow,0,0,0,0,0,0,0,0,0);
}
}
STM32CubeMX的定时器中断里面不是用的中断函数句柄,而是采用一个回调函数,所有定时器都在一个定时器里面,通过软件if(htim==(&htim6))才是判断是哪个定时器。
4.主函数
u8 speed=0;
uint8_t testdatatosend[50];
int leftSpeedNow =0;
int rightSpeedNow =0;
s16 getTIMx_DetaCnt(TIM_TypeDef * TIMx) //读取单位时间内脉冲变化值
{
s16 cnt;
cnt = TIMx->CNT-0x7fff;
TIMx->CNT = 0x7fff;
return cnt;
}
void Get_Motor_Speed(int *leftSpeed)
{
*leftSpeed = getTIMx_DetaCnt(TIM3)*1000*200;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&htim6))
{
Get_Motor_Speed(&leftSpeedNow);
//Test_Send_User(leftSpeedNow,0,0,0,0,0,0,0,0,0);
}
}
/* USER CODE END 0 */
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
delay_init(72);
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
__HAL_TIM_CLEAR_FLAG(&htim6,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim6);
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
delay_ms(50);
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
delay_ms(50);
Test_Send_User(leftSpeedNow,0,0,0,0,0,0,0,0,0);//我用的是匿名上位机,所以采用这个格式,大家可以就用串口助手看数据也行
}
/* USER CODE END 3 */
}
Test_Send_User(leftSpeedNow,0,0,0,0,0,0,0,0,0);
//我用的是匿名上位机,所以采用这个格式,大家可以就用串口助手看数据也行
4.结果图
总结
STM32CubeMX的HAL库和标准库有很多不一样的地方,按照标准库的习惯去配置HAL库往往是错的,刚上手肯定不太习惯。