提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、原理介绍
- [二、电机驱动模块 L298N 介绍](#二、电机驱动模块 L298N 介绍)
-
- [2.1 模块介绍](#2.1 模块介绍)
- [2.2 代码解析](#2.2 代码解析)
-
- [2.2.1 Arduino IDE](#2.2.1 Arduino IDE)
- [2.2.1 Arduino IDE(PWM)](#2.2.1 Arduino IDE(PWM))
- [2.2.3 Keil(PWM)](#2.2.3 Keil(PWM))
- 总结
前言
电机驱动通常采用如L298N、DRV8870或DRV8833等芯片。
一、原理介绍
对于一般的5V电机,实际上仅需一个5V电源(例如锂电池)正负极直接连接电机两端,即可使其运转(除步进电机等需脉冲驱动的类型外)。由此可见,电机运转的基本需求,就是一端接高电平、一端接低电平,形成电压差。

进一步推广,我们也可以利用单片机的5V或3.3V电源引脚连接电机一端,另一端接GND,从而驱动电机。

再进一步,若将电源引脚改为普通IO口,并将该IO设置为高电平输出(相当于提供3.3V或5V电压),另一端仍接GND,同样可形成电压差,驱动电机转动。

在实际操作中还会发现,不同电压(如5V与3.3V)会导致电机转速不同。因此可采用PWM(脉冲宽度调制)方式实现对电机转速的调节。通过调整IO口输出PWM信号的占空比,可改变电机两端的平均电压,从而实现从停止到全速之间的无极调速。

二、电机驱动模块 L298N 介绍
2.1 模块介绍
L298N需要使用12V锂电池供电,并且可以输出5V给单片机进行供电。最高可驱动24V电机。

工作原理。我们将 IN1234 接到单片机上,单片机输出高低电平,对应的OUT1234也会输出对应的高低电压(与供电电压一致)

2.2 代码解析
2.2.1 Arduino IDE
cpp
/*
点灯/电机转动
*/
void setup() {
pinMode(7, OUTPUT); // 将7号引脚设置为输出模式
}
void loop() {
digitalWrite(7, HIGH); // 给7号引脚高电平
delay(1000); // 保持1秒
digitalWrite(7, LOW); // 给7号引脚低电平
delay(1000); // 再保持1秒,然后循环
}
2.2.1 Arduino IDE(PWM)
cpp
/*
PWM 点灯/电机转动
*/
// 定义引脚
const int motorPwmPin = A0; // 电机驱动器的PWM控制引脚连接至模拟引脚A0
// 变量声明
int pwm = 0; // 0-255调速
void setup() {
// 设置电机控制引脚为输出模式
pinMode(motorPwmPin, OUTPUT);
// 启动串口通信,用于调试(可选)
Serial.begin(9600);
}
void loop() {
// 将PWM信号输出到电机驱动器
analogWrite(motorPwmPin, pwm);
// 通过串口监视器查看当前数值,便于调试
Serial.print(" PWM Output: ");
Serial.println(pwmOutput);
// 短暂延时,保持输出稳定
delay(100);
}
2.2.3 Keil(PWM)
cpp
//PWM调速
/*
.C文件
*/
#include "stm32f10x.h"
#include "PWM.h"
// GPIO初始化函数
void MOTOR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 开启GPIOA时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* 配置PA1(TIM2_CH2)和PA2(TIM2_CH3)为复用推挽输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
// PWM初始化函数
void PWM_TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* 开启TIM2时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* 调用GPIO初始化函数 */
MOTOR_Init();
/* 配置TIM2时基单元 */
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; // ARR: 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; // PSC: 预分频器
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
/* 配置TIM2输出比较通道2 (PA1) */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 0; // 通道2初始占空比0%
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
/* 配置TIM2输出比较通道3 (PA2) */
TIM_OCInitStructure.TIM_Pulse = 0; // 通道3初始占空比0%
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
/* 使能TIM2预装载寄存器 */
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* 使能TIM2 */
TIM_Cmd(TIM2, ENABLE);
TIM_CtrlPWMOutputs(TIM2, ENABLE);
}
/* 设置PA1(TIM2_CH2)占空比函数 */
void PWM_TIM2_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(TIM2, Compare);
}
/* 设置PA2(TIM2_CH3)占空比函数 */
void PWM_TIM2_SetCompare3(uint16_t Compare)
{
TIM_SetCompare3(TIM2, Compare);
}
cpp
/*
.h文件
*/
#ifndef _PWM_H
#define _PWM_H
#include "sys.h"
#include "stdlib.h"
void MOTOR_Init(void);
void PWM_TIM2_Init(void);
void PWM_TIM2_SetCompare2(uint16_t Compare);
void PWM_TIM2_SetCompare3(uint16_t Compare);
#endif
总结
本文是为说明《基于任意单片机的PWM调速电机》