利用串口上位机对直流电机进行调速。
这里选用到的芯片是STM32F407VET6,直流电机为TT马达,还有L298N驱动板。
我们需要明白,L298N的工作原理是:给定一个工作电压,再提供占空比不同的PWM波,就可以产生不同大小的电压来控制电机的旋转。所以我们需要让STM32芯片生成可调占空比的PWM波,而调整占空比的方式就是通过串口收发数据来修改。
那么先进行配置:
下面分别为RCC与SYS,还有TIM1的配置。
打开TIM1的两处通道设置为pwm是因为需要控制正反转。
还需要打开串口一并开启中断。
时钟树配置则168Hz拉满,这里就不放图了。值得注意的是,需要看清自己的晶振大小,cube初始生成25Hz的晶振,而实际上很多开发板都只有8Hz。
下面进行程序的编译。
首先为了方便,我们先对printf与scanf进行重定向,具体方式请参考我之前的随笔。
变量的定义(其中as为pwm波的初始占空比预设):
/* USER CODE BEGIN PV */
uint8_t Receive_date;
uint16_t as=60;
int x=1,y=0;
/* USER CODE END PV */
打开串口接收中断并给初始占空比输出pwm波:
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,&Receive_date,1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
/* USER CODE END 2 */
在下方编写串口中断回调部分的程序:
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(Receive_date=='N')
{
if((as-3)>=45)
{
as=as-3;
if(y==0)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,as);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
}
if(y==1)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,as);
}
}
}
if(Receive_date=='M')
{
if((as+3)<=75)
{
as=as+3;
if(y==0)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,as);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
}
if(y==1)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,as);
}
}
}
if(Receive_date=='S')
{
if(y==0)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,as);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
}
if(y==1)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,as);
}
}
if(Receive_date=='P')
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
}
if(Receive_date=='K')
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
x=1;
}
}
HAL_UART_Receive_IT(&huart1,&Receive_date,1);
}
/* USER CODE END 4 */
其中“N”为减速,“M”为加速,“S”为启动,“P”为停止,“K”为反转。变量x用作标志位,返回到while中进行反转程序,而变量y则是为了记住正反转状态。
下面是主函数while中的反转程序:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(x==1)
{
HAL_Delay(500);
if(y==0)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,as);
y=1;
}
else if(y==1)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,as);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
y=0;
}
x=0;
}
}
/* USER CODE END 3 */
反转前先给半秒钟的延时,因为突然反转可能会烧坏驱动板,所以需要一个停滞,而中断中切不可延时,所以这也是将反转程序写在while的原因。
接下来,连接串口,打开调试工具,选对波特率,即可输入上述字符(大写)来对电机进行控制。
注:这里写的内容都十分简单,主要是为了体现控制逻辑,并非适用于电机与电机驱动板。