掌握嵌入式开发板控电机,是机器人、智能家居等的核心技能。从精准驱动到节能提效,融合算法与硬件调试,是智能时代刚需,解锁自动化与 AI 控制潜力。
实现功能:
- 控制直流电机的
转动
。 - 控制直流电机的
转动方向
- 控制直流电机的
转动速度
熟悉硬件:
电机

如图所示该直流电机(也叫马达)
- 可控制节点两端的接入正负极实现控制电机的转动方向
- 可控制电压的大小实现控制电机的转动速度
l298n电机驱动模块

如图所示该l298n电机驱动模块
可通过b站,抖音等学习该驱动模块的各个引脚作用。(这里不做详细描述)
硬件连接

代码实现
由于 esp-hal处于更新迭代阶段 McPwm 属于不稳定状态所以要引入unstable
修复Cargo.toml文件的esp-hal引入
toml
...
esp-hal = { version = "^1.0.0-rc.0", features = ["esp32s3", "unstable"] }
...
声明电机方向控制引脚
rs
...
let config = OutputConfig::default();
let mut dj1 = Output::new(peripherals.GPIO4, Level::High, config); //控制电机电源输入的左边引脚
let mut dj2 = Output::new(peripherals.GPIO5, Level::Low, config); //控制电机电源输入的右边引脚
...
注册pwm流输出
rs
...
let clock_cfg = PeripheralClockConfig::with_frequency(Rate::from_mhz(40)).unwrap();
let mut mcpwm = McPwm::new(peripherals.MCPWM0, clock_cfg);
let pin = peripherals.GPIO6;
mcpwm.operator0.set_timer(&mcpwm.timer0);
let mut pwm_pin = mcpwm
.operator0
.with_pin_a(pin, PwmPinConfig::UP_ACTIVE_HIGH);
let timer_clock_cfg = clock_cfg
.timer_clock_with_frequency(99, PwmWorkingMode::Increase, Rate::from_khz(20))
.unwrap();
mcpwm.timer0.start(timer_clock_cfg);
pwm_pin.set_timestamp(50);//设置为50%
...
实现电机先加速旋转,再减速度反方向旋转
rs
...
let mut light = true;
loop {
let m = pwm_pin.timestamp();
if light {
pwm_pin.set_timestamp(m + 1);
} else {
pwm_pin.set_timestamp(m - 1);
}
if m == 1 {
light = true;
dj1.set_high();
dj2.set_low();
} else if m == 99 {
dj1.set_low();
dj2.set_high();
light = false;
}
...
}
完整代码
rs
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
use esp_hal::mcpwm::operator::{PwmPinConfig};
use esp_hal::mcpwm::timer::PwmWorkingMode;
use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
use esp_hal::time::Rate;
use esp_hal::{
clock::CpuClock,
gpio::{Level, Output, OutputConfig},
main,
time::{Duration, Instant},
};
use esp_println::println;
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {
println!("Panic!");
}
}
pub fn update_method(timestamp: u32) {
println!("update_method: {}", timestamp);
}
esp_bootloader_esp_idf::esp_app_desc!();
#[main]
fn main() -> ! {
// generator version: 0.5.0
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let config = OutputConfig::default();
let mut dj1 = Output::new(peripherals.GPIO4, Level::High, config); //控制电机电源输入的左边引脚
let mut dj2 = Output::new(peripherals.GPIO5, Level::Low, config); //控制电机电源输入的右边引脚
let clock_cfg = PeripheralClockConfig::with_frequency(Rate::from_mhz(40)).unwrap();
let mut mcpwm = McPwm::new(peripherals.MCPWM0, clock_cfg);
let pin = peripherals.GPIO6;
mcpwm.operator0.set_timer(&mcpwm.timer0);
let mut pwm_pin = mcpwm
.operator0
.with_pin_a(pin, PwmPinConfig::UP_ACTIVE_HIGH);
let timer_clock_cfg = clock_cfg
.timer_clock_with_frequency(99, PwmWorkingMode::Increase, Rate::from_khz(20))
.unwrap();
mcpwm.timer0.start(timer_clock_cfg);
pwm_pin.set_timestamp(50);
let mut light = true;
loop {
let m = pwm_pin.timestamp();
if light {
pwm_pin.set_timestamp(m + 1);
} else {
pwm_pin.set_timestamp(m - 1);
}
if m == 1 {
light = true;
dj1.set_high();
dj2.set_low();
} else if m == 99 {
dj1.set_low();
dj2.set_high();
light = false;
}
let delay_start = Instant::now();
while delay_start.elapsed() < Duration::from_millis(10) {}
}
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin
}
实现效果
