用STM32玩L298N(正反轉、調速)
開發板:STM32F103ZET6(正點原子F103核心板)/STM32F103C8T6小板
硬件:L298N,網上一搜就有
軟件:Keil MDK5.29
買L298N回來的時候,給的例程是51的,我手上又沒有這種板子,解決方法就是自己在網上找別人怎么做,找不到就去找原理圖,慢慢來,肯定會有收獲的!
開發板圖片(正點原子F103核心板)
Gitee項目已發布,需要源碼請自助下載
STM32F103ZET6:地址(gitee)
STM32F103C8T6:地址(gitee)
控制直流電機正反轉
相信你們買回來L298N的時候,樣子基本都是這樣的
引腳圖如下:
可以看到六個引腳引出來,分別是ENA、IN1/2/3/4、ENB
ENA就是用於使能IN1和IN2的引腳,蓋上跳線帽,就是直接使能,拔掉跳線帽就要用pwm來控制電機,ENB同理
OUT1和OUT2就是接第一個直流電機的,OUT3和OUT4同理
控制電機正反轉就只需要給數字電壓,不需要調速,所以我沒有把改線帽拔掉
隨便找四個引腳,我這里圖方便找了PA4/5/6/7
控制程序如下
#define M1_P PAout(4)
#define M1_N PAout(5)
#define M2_P PAout(6)
#define M2_N PAout(7)
void Motor_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口時鍾
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根據設定參數初始化PA4/5/6/7
}
void Motor_Stop(void)
{
M1_P = 0;
M1_N = 0;
M2_P = 0;
M2_N = 0;
}
void Motor_Forward(void)
{
M1_P = 1;
M1_N = 0;
M2_P = 1;
M2_N = 0;
}
示例程序如下:
#include "delay.h"
#include "l298n.h"
int main(void)
{
delay_init(); //延時函數初始化
Motor_Init();
while(1)
{
Motor_Forward();
delay_ms(1500);
Motor_Stop();
delay_ms(1500);
}
}
接線圖如下:
效果如下:
視頻地址(bilibili)
使用PWM調速
調速就要用到pwm,L298N調速方式可以有兩種方式,但都是大差不差,一種是ENA直接使能(1和0),在IN1/2那里給pwm控制,另一種是IN1/2那里給邏輯電平(1和0),ENA用PWM控制,我這里是用的第二種方法,第一種方法我沒有研究過...
經過查閱資料,決定用PB8/9作為輸出pwm的端口
控制程序如下:
//PWM 部分初始化
//arr:自動重裝值
//psc:時鍾預分頻數
void Motor_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定時器4時鍾
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設和AFIO復用功能模塊時鍾
GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //Timer4重映射 TIM4_CH3->PB8 TIM4_CH4->PB9
//設置該引腳為復用輸出功能,輸出TIM_CH1和TIM_CH2和的PWM脈沖波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //TIM_CH3和TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
//初始化TIM4 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC3Init(TIM4, &TIM_OCInitStructure); //初始化外設TIM4 OC3
TIM_OC4Init(TIM4, &TIM_OCInitStructure); //初始化外設TIM4 OC4
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的預裝載寄存器
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR2上的預裝載寄存器
TIM_Cmd(TIM4, ENABLE); //使能TIM4
}
接線圖如下:
示例程序如下:
#include "delay.h"
#include "l298n.h"
int main(void)
{
delay_init(); //延時函數初始化
Motor_Init();
Motor_PWM_Init(899,0);
/*
定時器從0開始計數到899,共900次計數,即自動重載值為900
不分頻。PWM頻率=72000000/900=80Khz
*/
TIM_SetCompare3(TIM4,400); //TIM4 通道3 用400作為區分高低的線
TIM_SetCompare4(TIM4,400); //TIM4 通道4 用400作為區分高低的線
while(1)
{
Motor_Forward();
delay_ms(1500);
Motor_Stop();
delay_ms(1500);
Motor_Backward();
delay_ms(3000);
}
}
如果要改輸出pwm的端口的話,必須看清楚程序的通道和定時器標號
效果如下:
視頻地址(bilibili)