黄工无刷电机学习
直播中

丁冬芹

7年用户 1256经验值
私信 关注
[问答]

如何用STM32玩L298N的正反转和调速?

如何用STM32玩L298N的正反转和调速?

回帖(1)

黎歆俭

2021-10-15 11:02:47
开发板: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);
                }
}


接线图如下:





效果如下:

  L298N控制直流电机正反转



  视频地址(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的端口的话,必须看清楚程序的通道和定时器标号
举报

更多回帖

发帖
×
20
完善资料,
赚取积分