0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CW32L012/F030灵眸X1智能小车--电机调速控制

CW32生态社区 来源:CW32生态社区 2026-04-02 16:49 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1.认识PWM

PWM(Pulse Width Modulation脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是5v的,那么经过改变PWM的占空比,可以达到在一定时间内输出3.3V或者1.3V的效果

2.CW32 PWM介绍

普通的IO控制虽然能让电机实现正反转但是电机只能在一个固定的速度下实现,我们没法改变电机转动的速度,那在实际使用中是非常不方便的,所以本项目的目的为实现开发板上电机调速。

想要实现电机调速其实非常简单,根据前文芯片手册可知,控制引脚置一个置高电平一个置低电平电机即可动起来,两个都置低电平或高电平就会停止,那我们只需要改变高电平持续时间不就可以实现调速了吗。想要改变高电平持续时间,我们可以使用 CW32内部的硬件资源PWM。

PWM功能是在定时器的基础上实现的,但不是所有的定时器都支持PWM输出功能。从用户手册上可以了解到,高级定时器拥有4个PWM通道,通用定时器拥有4个PWM通道,通用定时器拥有PWM通道。每一个PWM通道都对应单片机的一个管脚,这个引脚不是唯一固定的,可能有一个或者两个管脚都对应同一个通道,我们在使用的时候可以任选其一进行配置。

根据开发板原理图可知,在开发板上左右两个电机分别接到了两块RZ7899上,左电机为PB3和PB4,右电机为PB1和PB5。再翻阅CW32数据手册可知

wKgZO2nL0E6AGKP0AAAbyA9HXNU557.jpg

PB4和PB5复用功能可以使用通用定时器输出比较的一通道和二通道,我们配置一下即可。

3.PWM基本参数

PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。

  • 频率:PWM的频率是整个周期的倒数。
  • 占空比:占空比是指一个周期内高电平所占的比例。

4.控制方法

采样控制理论中有一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。PWM控制技术就是以该结论为理论基础,对半导体开关器件的导通和关断进行控制,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。

5.基本原理

控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使个脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。

6.PWM优点

PWM的一个优点是从处理器到被控制系统信号都是数字形式,无需进行数模转换。让信号保持为数字形式可将噪声影响降到最小。噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,才能对数字信号产生影响。对噪声抵抗能力的增强是PWM相对于模拟控制的另一个优点,而且这也是在某些时候将PWM用于通信的主要原因。

7.配置流程

一般使用定时器PWM功能,都需要有以下几个步骤。

  • 使能时钟
  • 配置GPIO
  • 配置定时器
  • 配置PWM
  • 使能TIMER
  • 调整定时器输出通道占空比

8.配置GPIO

前面介绍过PWM输出是依赖于定时器的,所以要对定时器进行配置,但是我们不使用定时器的中断功能,顾不用对定时器的中断进行配置。

又因为我们使用的PB4是GTIM1的通道1,PB5是GTIM1的通道2,所以我们要配置PB0的GPIO参数。

首先是GPIO的参数结构体:

GPIO_InitTypeDef GPIO_InitStruct;  // GPIO初始化结构体

然后是GPIO配置参数:

 GPIO_Initstructure.IT=GPIO_IT_NONE;
        GPIO_Initstructure.Mode=GPIO_MODE_OUTPUT_PP;//推挽输出
        GPIO_Initstructure.Pins=GPIO_PIN_4 | GPIO_PIN_5;//引脚配置
        GPIO_Initstructure.Speed=GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOB,&GPIO_Initstructure);

使用复用功能,将PB5复用为GTIM1通道2的通道,将PB4复用为GTIM1通道1的通道:

 PB04_AFx_GTIM1CH1();//配置PB4复用功能为通用定时器一的一通道
        PB05_AFx_GTIM1CH2();//配置PB5复用功能为通用定时器一的二通道

9.配置定时器

要使用定时器参数配置有一个结构体,如图所示。

0fa88d50f79a5ad45d11e1255c9fa188.png

参数说明

  1. uint32_t Mode: 这个字段用于指定GTIM的工作模式。
    1. GTIM_MODE_TIME:基本定时器模式。
    2. GTIM_MODE_COUNTER:计数器模式。
    3. GTIM_MODE_TRIGGER:触发模式,可能指定时器被用作触发源或响应于某个外部触发信号开始/停止计数。
    4. GTIM_MODE_GATE:门控模式,意味着定时器的计数操作受一个外部信号的控制,即只有当这个控制信号有效时,定时器才开始或继续计数。
  2. uint32_t OneShotMode: 此字段决定定时器是工作在单次计数模式还是一直循环计数(连续计数)模式。如果设置为单次模式,定时器在达到重载值后会停止计数,直到复位或重新配置;如果是连续计数模式,则会在达到重载值后自动重置并继续计数。
  3. FunctionalState ToggleOutState: 这个字段用于控制定时器的输出翻转功能是否使能。FunctionalState是一个类型定义,通常有两个的值:ENABLE和DISABLE,分别表示启用或禁用定时器的输出引脚翻转功能。当定时器计数达到特定条件时,其关联的输出引脚电平会翻转。
  4. uint32_t Prescaler: 预分频器的设置值。预分频器用于降低提供给定时器时钟的频率,使得计数速度变慢,从而实现更宽范围的计时能力。
  5. uint32_t ReloadValue: 重载值,也称为自动装载寄存器值。当计数值达到此值时,定时器会产生一个更新事件(如中断或DMA请求),并且计数器会根据OneShotMode的设置重置或继续计数。这个值决定了定时器溢出的周期,是定时操作的核心配置之一。

结构体定义:

GTIM_InitTypeDef GTIM_InitStruct;  // 通用定时器初始化结构体

相关配置如下:

GTIM_InitStruct.Mode = GTIM_MODE_TIME;               // 定时器模式
GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;   // 连续计数模式
GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV1024;    // DCLK = PCLK / 64 = 64MHz/64 = 1MHz
GTIM_InitStruct.ReloadValue = 1000;                  // 重装载值设置
GTIM_InitStruct.ToggleOutState = DISABLE;            // 输出翻转功能

初始化配置:

GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);        // 初始化

10.配置PWM

配置好GTIMER1参数之后,需要配置PWM输出。

GTIM_OCInit(CW_GTIM1,GTIM_CHANNEL1,GTIM_OC_OUTPUT_PWM_HIGH);//输出比较通道初始化
GTIM_OCInit(CW_GTIM1,GTIM_CHANNEL2,GTIM_OC_OUTPUT_PWM_HIGH);

11.使能TIMER

我们使用函数TIM_Cmd初始化函数:

GTIM_Cmd(CW_GTIM1, ENABLE);  // 使能定时器

12.调整定时器输出通道占空比

void GTIM_SetCompare1(GTIM_TypeDef *GTIMx, uint32_t Value)

该函数GTIM_SetCompare3用于设置通用定时器(GTIM)的第3个通道(Channel 3)的比较值(Compare Value)

  • GTIMx: 指向通用定时器的类型定义指针。这是一个重要的参数,用来指定要操作的具体定时器实例(例如 TIM1、TIM2 等)。使用前需要确保指针非空且指向有效的定时器。
  • Value: 要设置的比较值,类型为无符号32位整数。这个值决定了定时器计数器何时与之“比较”,进而可能触发输出状态的改变(比如在PWM模式下改变占空比)

函数没有返回值(@retval None)。

注意:每个通道有不同的函数。通道2是GTIM_SetCompare2,通道3是GTIM_SetCompare3,如此以此类推。。。。

在PWM(脉冲宽度调制)应用中,可以通过改变CCR3的值来调整PWM信号的占空比。例如,增加CCR3的值会增加PWM高电平的持续时间,从而增加占空比。

13.软件编写

修改代码如下:

void Motor_Init(void)
{
        RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOB,ENABLE);//开启GPIOB时钟
        RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_GTIM1,ENABLE);//开启通用定时器一时钟

        PB04_AFx_GTIM1CH1();//配置PB4复用功能为通用定时器一的一通道
        PB05_AFx_GTIM1CH2();//配置PB5复用功能为通用定时器一的二通道

        GPIO_InitTypeDef GPIO_Initstructure;
        GPIO_Initstructure.IT=GPIO_IT_NONE;
        GPIO_Initstructure.Mode=GPIO_MODE_OUTPUT_PP;
        GPIO_Initstructure.Pins=GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_1;
        GPIO_Initstructure.Speed=GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOB,&GPIO_Initstructure);

        GTIM_InitTypeDef GTIM_Initstructure;
        GTIM_Initstructure.Mode=GTIM_MODE_TIME;//定时器模式
        GTIM_Initstructure.OneShotMode=GTIM_COUNT_CONTINUE;//连续计数
        GTIM_Initstructure.Prescaler=GTIM_PRESCALER_DIV1024;//配置预分频器
        GTIM_Initstructure.ReloadValue=1000;//自动重装载值
        GTIM_Initstructure.ToggleOutState=DISABLE;//关闭输出反转
        GTIM_TimeBaseInit(CW_GTIM1,>IM_Initstructure);

        GTIM_OCInit(CW_GTIM1,GTIM_CHANNEL1,GTIM_OC_OUTPUT_PWM_HIGH);//输出比较通道初始化
        GTIM_OCInit(CW_GTIM1,GTIM_CHANNEL2,GTIM_OC_OUTPUT_PWM_HIGH);

        CW_GTIM1->CCR1=0;//初始化ccr
        CW_GTIM1->CCR2=0;

        GTIM_ITConfig(CW_GTIM1,GTIM_IT_OV,ENABLE);
        GTIM_Cmd(CW_GTIM1,ENABLE);
}

配置输出通道

/**************************
通道一输出配置
形参:占空比,最大1000
**************************/
void GTIM1_SetCompare1(uint16_t value)//通道一输出配置
{
        GTIM_SetCompare1(CW_GTIM1,value);
}
/**************************
通道二输出配置
形参:占空比,最大1000
**************************/
void GTIM1_SetCompare2(uint16_t value)//通道二输出配置
{
        GTIM_SetCompare2(CW_GTIM1,value);
}

电机正反转

/**************************
//左电机正转
形参:占空比,最大1000
**************************/
void Motor_Left_Run(uint16_t value)//左电机正转
{
        GTIM1_SetCompare1(value);
        PB03_SETHIGH();
} 
/**************************
//右电机正转
形参:占空比,最大1000
**************************/
void Motor_Right_Retreat(uint16_t value)//右电机反转
{
        value=1000-value;
        GTIM1_SetCompare2(value);
        PB12_SETLOW();
}
/**************************
左电机反转
形参:占空比,最大1000
**************************/
void Motor_Left_Retreat(uint16_t value)//左电机反转
{
        value=1000-value;
        GTIM1_SetCompare1(value);
        PB03_SETLOW();
}
/**************************
右电机正转
形参:占空比,最大1000
**************************/
void Motor_Right_Run(uint16_t value)//右电机正转
{
        GTIM1_SetCompare2(value);
        PB12_SETHIGH();
}
void Car_Run(uint16_t value)//小车前进
{
        Motor_Left_Run(value);
        Motor_Right_Run(value);
}
void Car_Left(uint16_t value)//左转
{
        Motor_Left_Retreat(value);
        Motor_Right_Run(value);
}
void Car_Right(uint16_t value)//右转
{
        Motor_Left_Run(value);
        Motor_Right_Retreat(value);
}
void Car_Retreat(uint16_t value)//后退
{
        Motor_Left_Retreat(value);
        Motor_Right_Retreat(value);
}
void Car_Stop(void)//停止
{
        Motor_Left_Run(0);
        Motor_Right_Run(0);
}

在主函数中编写以下代码

int16_t keynum,speed;
int main(void)
{
        OLED_Init();//初始化
        LED_Init();//LED初始化
        Key_Init();//按键初始化
        Motor_Init();//初始化电机
        while(1)
        {
                keynum=Key();//获取键码,
                if(keynum==1){speed+=100;if(speed>1000){speed=1000;}}
                if(keynum==2){speed-=100;if(speed< 0){speed=0;}}
                Motor_Left_Run(speed);//控制左电机
                Motor_Right_Run(speed);//控制右电机
                OLED_ShowString(1,1,"speed=");
                OLED_ShowNum(1,7,speed,4);//屏幕显示变量
        }
}

14.实验现象

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

  • 按下按键一,电机速度将会以10%的速度递增
  • 按下按键二,电机速度将会以10%的速度递减
  • 屏幕显示当前占空比

a3699f30f1ea0446477caf77d31289c8.jpg
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PWM
    PWM
    +关注

    关注

    116

    文章

    5890

    浏览量

    226513
  • 智能小车
    +关注

    关注

    87

    文章

    565

    浏览量

    83518
  • CW32
    +关注

    关注

    1

    文章

    323

    浏览量

    1955
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L012/F030X1智能小车——板载WS2812驱动示例

    WS2812是一种广泛使用的地址可控制的RGB LED模块,其内置驱动电路和控制芯片,允许用户通过单线信号控制多个LED的颜色和亮度。
    的头像 发表于 01-05 16:35 3304次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——板载WS2812驱动示例

    CW32L012/F030X1智能小车——超声波模块配置

    SR04超声波模块是一款广泛应用的测距传感器,主要用于使用超声波测量物体与传感器之间的距离。它是一个成本低廉、精度较高且易于使用的传感器,常用于机器人、智能家居、无人机、汽车防撞系统等项目。
    的头像 发表于 01-05 16:54 3062次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——超声波模块配置

    CW32L012/F030X1智能小车——使用NRF24L01通信

    NRF24L01所使用的通讯协议为SPI,SPI又可分为软件SPI和硬件SPI。
    的头像 发表于 04-01 16:49 2533次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——使用NRF24<b class='flag-5'>L</b>01通信

    CW32L012/F030X1智能小车——使用蓝牙模块通讯

    主控板配套的是一款低功耗蓝牙模块,适用于短距离无线通信。该模块通常被用于各种嵌入式项目,如物联网(IoT)设备、手机配件、智能家居设备、医疗设备等。
    的头像 发表于 04-01 16:54 3272次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——使用蓝牙模块通讯

    FOC控制中如何利用芯片内部的运放设计电流采样电路?

    最近开发电机控制的项目,我开始使用最新的CW32L012做主控,CW32L012作为混合信号MCU,相比于传统MCU控制,集成度较高,性能当
    的头像 发表于 01-05 16:50 2945次阅读
    FOC<b class='flag-5'>控制</b>中如何利用芯片内部的运放设计电流采样电路?

    坚持继续布局32位MCU,进一步完善产品阵容,96Mhz主频CW32L012新品发布!

    基于CW32L01x系列低功耗微控制器家族的全新成员:CW32L012系列产品。 CW32L012基于ARM® Cortex-M0+内核,主频高达96MHz,同时集成了CORDIC硬件
    发表于 07-16 16:32

    **CW32L012****开发评估板的第一个程序**

    CW32L012****开发评估板的第一个程序 最近以15.99在CW32生态社区入手了这块CW32L012开发评估板,我迫不及待的烧录进电灯程序,看看这块板子是否是正常的,能否满足我后面的学习
    发表于 11-22 00:09

    CW32L012小型机器人控制评估板活动 四足机器人+智能小车 开箱评测

    CW32L012活动相关资料链接:https://dwi41yhz703.feishu.cn/wiki/B1Ihw31ebiX0vkkhQr2cINnkn1g 小型机器人+智能小车
    发表于 11-24 23:44

    CW32F030C8T7永磁同步电机无感FOC控制的方案

    基于ARM®Cortex®-M0+内核的微控制CW32F030C8T7,在永磁同步电机无感FOC控制方案中展现了卓越的性能,为电机
    发表于 12-03 06:34

    基于CW32F030C8T6的舵机控制应用

    基于CW32F030C8T6的舵机控制应用
    的头像 发表于 10-25 16:52 1934次阅读
    基于<b class='flag-5'>CW32F030</b>C8T6的舵机<b class='flag-5'>控制</b>应用

    使用芯源CW32的CW32L012开发评估板做了spi屏幕驱动

    CW32生态社区以极高的性价比入手了这块CW32L012开发评估板,开发板以底板、核心板、1.77寸TFT显示屏构成,所有的IO口都引出了排针,这点好评,使用杜邦线可以非常方便的连接其他模块。引脚
    的头像 发表于 11-21 11:34 795次阅读
    使用芯源<b class='flag-5'>CW</b>32的<b class='flag-5'>CW32L012</b>开发评估板做了spi屏幕驱动

    CW32L012小机器人的电机控制

    线的大功率调速电机控制性能直接决定了系统的响应速度、运行精度、能耗效率与稳定性。这里分享CW32L012小机器人的正反转、调速
    的头像 发表于 11-21 13:18 2535次阅读
    <b class='flag-5'>CW32L012</b>小机器人的<b class='flag-5'>电机</b><b class='flag-5'>控制</b>

    CW32L012与STM32F103的三角运算性能对比

    没有硬件浮点运算单元。 但在运算三角函数时,CW32L012支持CORDIC算法。 二、 三角运算性能具体分析 1:标准库浮点运算(如 math.h 的 sinf, cosf) 这是最常用但也是最慢的方式。 STM32F103C
    的头像 发表于 12-29 15:32 2486次阅读
    <b class='flag-5'>CW32L012</b>与STM32<b class='flag-5'>F</b>103的三角运算性能对比

    CW32L012与STM32G431的CORDIC三角函数运算性能对比

    CORDIC协处理器的三角运算性能对比。对比结果出乎意料。 一、硬件架构 二、运算100W次SIN30度与COS30度的代码实现 1.CW32L012 CW32L012的CORDIC提供某些数学函数
    的头像 发表于 12-29 15:55 2753次阅读
    <b class='flag-5'>CW32L012</b>与STM32G431的CORDIC三角函数运算性能对比

    CW32L012/F030X1智能小车--电机正反转控制

    RZ7899是一种高性能电机驱动芯片,广泛应用于各种电机控制场合,特别是在步进电机和直流电机的驱动中。
    的头像 发表于 04-02 16:48 1100次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>--<b class='flag-5'>电机</b>正反转<b class='flag-5'>控制</b>