本文作者:烟火之旅

CW32L012/F030灵眸X1智能小车--电机正反转控制

烟火之旅 2026-04-03 3976

一、电机正转

电机驱动芯片RZ7899

RZ7899是一种高性能电机驱动芯片,广泛应用于各种电机控制场合,特别是在步进电机和直流电机的驱动中。以下是该芯片的一些关键特性和应用:

主要特性:

高驱动能力:RZ7899能够驱动高电流的电机,适合需要大功率输出的应用。

双通道设计:具备双通道输出,能够同时驱动两个电机,提升设计灵活性。

PWM控制:支持脉宽调制(PWM)控制,使得电机的运行更加平滑和高效。

过流保护:内置过流保护功能,确保芯片和电机在异常情况下的安全运行。

热保护功能:能够监测温度并在过热时自动停止工作,防止损坏。

低静态功耗:在静态模式下功耗较低,适合需要长时间待机的应用场合。

多种控制模式:支持多种控制模式,包括全桥、半桥等,满足不同电机控制需求。

该模块在开发板上位置如下:

图片

2.原理图

在开发板上左右两个电机分别接到了两块RZ7899上,左电机使用CW32的PB3和PB4控制,右电机使用CW32的PB12和PB5控制。

3.查看资料

翻阅手册我们可以发现,其实驱动电机只需要输入端接到MCU的两个引脚,输出端分别接到电机的两个引脚,即可通过改变输入端电平实现正反转。

注意:输出端5脚和6脚,7脚和8脚为一组

4.代码编写

根据上述从手册中查到的信息,我们知道了驱动方法之后就可以开始驱动代码的编写了。在工程中新建一个电机的.c和.h文件,名字自己确定,然后在.c中编写如下代码:

void Motor_Init(void)
{
        __RCC_GPIOB_CLK_ENABLE();//开启GPIOB时钟
        GPIO_InitTypeDef GPIO_InitStruct; 
        GPIO_InitStruct.IT=GPIO_IT_NONE;
        GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;//配置为推挽输出
        GPIO_InitStruct.Pins=GPIO_PIN_3 | GPIO_PIN_4;//选择GPIO口
        GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
}

随后在main函数中编写如下代码

int main(void)
{
        OLED_Init();//初始化
        Motor_Init();//初始化电机
        while(1)
        {
                PB03_SETHIGH();//PB3置高电平
                PB04_SETLOW();//PB4置低电平
        }
}

我们给PB3置为高电平,PB4置低电平,满足手册驱动真值表中驱动电机要求,即可实现正转。

5.运行现象

将本次项目代码烧录进开发板之后,可以观察到左电机开始正转。

二、电机正反转控制

根据上面的实验,我们已经完成了单个电机的正转,那么凭各位工程师的聪明才智应该很快就能想到如何控制两个电机同时正转以及反转了。复制上一次工程,我们稍加修改即可。

1.代码如下:

void Motor_Init(void)
{
        __RCC_GPIOB_CLK_ENABLE();//开启GPIOB时钟
        GPIO_InitTypeDef GPIO_InitStruct; 
        GPIO_InitStruct.IT=GPIO_IT_NONE;
        GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;//配置为推挽输出
        GPIO_InitStruct.Pins=GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_12 | GPIO_PIN_5;//选择GPIO口
        GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOB, &GPIO_InitStruct);

        Right_Motor_stop();//
        Left_Motor_stop();//
}

将右边电机的控制GPIO也初始化,然后将电机运动稍微封装一下

void Left_Motor_foreward(void)
{
        PB03_SETHIGH();//PB3置高电平
        PB04_SETLOW();//PB4置低电平
}
void Left_Motor_reversal(void)
{
        PB04_SETHIGH();//PB4置高电平
        PB03_SETLOW();//PB3置低电平
}
void Left_Motor_stop(void)
{
        PB04_SETLOW();//PB4置低电平
        PB03_SETLOW();//PB3置低电平
}
void Right_Motor_foreward(void)
{
        PB05_SETLOW();//PB12置低电平
        PB12_SETHIGH();//PB5置高电平
}
void Right_Motor_reversal(void)
{
        PB12_SETLOW();//PB12置低电平
        PB05_SETHIGH();//PB5置高电平
}
void Right_Motor_stop(void)
{
        PB12_SETLOW();//PB12置低电平
        PB05_SETLOW();//PB5置低电平
}

这样就可以灵活地驱动电机正反转了,然后在主函数中加入以下代码

uint8_t keynum,Left_state,Right_state;
int main(void)
{
        OLED_Init();//初始化
        LED_Init();//LED初始化
        Key_Init();//按键初始化
        Motor_Init();//初始化电机
        while(1)
        {
                keynum=Key();//获取键码,
                if(keynum==1){Left_state++;Left_state%=4;}//按键1按下一次,变量+1,加到4归零
                if(keynum==2){Right_state++;Right_state%=4;}
                if(Left_state==0 || Left_state==2)//条件判断变量为1或者2停下
                {
                        Left_Motor_stop();//左电机停

                }
                else if(Left_state==1)
                {
                        Left_Motor_foreward();//左电机正转

                }
                else if(Left_state==3)
                {
                        Left_Motor_reversal();//左电机反转
                        PC13_SETHIGH();
                }
                if(Right_state==0 || Right_state==2)
                {
                        Right_Motor_stop();//右电机停
                }
                else if(Right_state==1)
                {
                        Right_Motor_foreward();//右电机正转
                }
                else if(Right_state==3)
                {
                        Right_Motor_reversal();//右电机正转
                }
                if((Right_state==0 || Right_state==2 ) && (Left_state==0 || Left_state==2 ))
                {
                        PC13_SETLOW();//LED点亮
                }
                else{
                        PC13_SETHIGH();                //LED熄灭        
                }
                OLED_ShowNum(1,1,Left_state,2);//屏幕显示变量
                OLED_ShowNum(2,1,Right_state,2);
        }
}

2.运行现象

将本次项目代码烧录进开发板之后,我们可以观察到以下现象:

上电之后电机停止

OLED屏幕第一行显示00,第二行也显示00,记录按键按下次数,到四归零

LED点亮

按下按键一,左电机正转,再按下停止,再按下反转,再按下停止

按下按键二,右电机正转,再按下停止,再按下反转,再按下停止

电机停止时LED点亮,反之则熄灭

7455588942e1d88d26d636dafd887ab2.jpg