完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本次实验实现的是使用F429输出PWM,从而控制减速电机的速度。实验主要是通过对定时器3的通道3和通道4的配置来实现PWM的输出,并且可以通过调整占空比来实现对电机转速的控制。
实验前准备 本次实验需要用到的器材有:STM32F429开发板、两路减速电机、L298N电机驱动模块、杜邦线,电机及其驱动模块。 原理介绍 PWM工作原理 PWM,即脉冲宽度调制(Pulse Width Modulation)的缩写,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制, PWM 原理如下图所示: 上图就是一个简单的 PWM 原理示意图。图中,我们假定定时器工作在向上计数 PWM模式,且当 CNT《CCRx 时,输出 0,当 CNT》=CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。 定时器输出PWM STM32F429 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4 路的 PWM 输出!这里我们仅使用 TIM3 的CH3和CH4 产生两路 PWM 输出。要使 STM32F429 的通用定时器 TIMx 产生 PWM 输出,除了配置定时器的几个基本的寄存器外,还会用到 3 个寄存器,来控制 PWM 的。这三个寄存器分别是:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。详细介绍参考正点原子配套资料教程:STM32F429开发指南-HAL库版本——定时器中断实验和PWM输出实验,里面有更为详细的介绍。 程序源码 程序改自正点原子的配套源码——实验八PWM输出实验: 在该项目工程文件中,编写了两个主要的.c文件,分别是定时器中断配置文件和管脚输出文件各部分代码如下: timer.c文件: #include “timer.h” #include “motor.h” TIM_HandleTypeDef TIM3_Handler; //定时器3PWM句柄 TIM_OC_InitTypeDef TIM3_CH3Handler;//定时器3通道3句柄 TIM_OC_InitTypeDef TIM3_CH4Handler;//定时器3通道4句柄 //TIM3 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM3_PWM_Init(u16 arr,u16 psc) { TIM3_Handler.Instance=TIM3; //定时器3 TIM3_Handler.Init.Prescaler=psc; //定时器分频 TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式 TIM3_Handler.Init.Period=arr; //自动重装载值 TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&TIM3_Handler); //初始化PWM TIM3_CH3Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1 TIM3_CH3Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50% TIM3_CH3Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH3Handler,TIM_CHANNEL_3);//配置TIM3通道3 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_3);//开启PWM通道3 TIM3_CH4Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1 TIM3_CH4Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50% TIM3_CH4Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH4Handler,TIM_CHANNEL_4);//配置TIM3通道4 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_4);//开启PWM通道4 } //定时器底层驱动,时钟使能,引脚配置 //此函数会被HAL_TIM_PWM_Init()调用 //htim:定时器句柄 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_TIM3_CLK_ENABLE(); //使能定时器3 __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟 GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; //PB1/0 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 GPIO_Initure.Alternate= GPIO_AF2_TIM3; //PB1复用为TIM3_CH4 HAL_GPIO_Init(GPIOB,&GPIO_Initure); } //设置TIM通道4的占空比 //compare:比较值 void TIM_SetTIM3Compare3(u32 compare1) { TIM3-》CCR3=compare1; } void TIM_SetTIM3Compare4(u32 compare2) { TIM3-》CCR4=compare2; } timer.h文件: #ifndef __PWM_H #define __PWM_H #include “sys.h” extern TIM_HandleTypeDef TIM3_Handler; //定时器3PWM句柄 extern TIM_OC_InitTypeDef TIM3_CH3Handler; //定时器3通道3句柄 extern TIM_OC_InitTypeDef TIM3_CH4Handler; //定时器3通道4句柄 void TIM3_Init(u16 arr,u16 psc); void TIM3_PWM_Init(u16 arr,u16 psc); void TIM_SetTIM3Compare3(u32 compare1); void TIM_SetTIM3Compare4(u32 compare2); #endif motor.c文件: #include “motor.h” #include “delay.h” void MOTOR_Init(void) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟 GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; //PB1,0 GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOB,&GPIO_Initure); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); //PB0置1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); //PB1置1 } motor.h文件: #ifndef _MOTOR_H #define _MOTOR_H #include “sys.h” #define LED0 PBout(1) //LED0 #define LED1 PBout(0) //LED1 void MOTOR_Init(void); #endif main.c文件: #include “sys.h” #include “delay.h” #include “usart.h” #include “motor.h” #include “timer.h” int main(void) { //u8 dir=1; u16 motor0pwmval=420; //具体数值(范围可取0~499) u16 motor1pwmval=100;//具体数值(范围可取0~499) HAL_Init(); //初始化HAL库 Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz delay_init(180); //初始化延时函数 uart_init(115200); //初始化USART MOTOR_Init(); //初始化LED TIM3_PWM_Init(500-1,90-1); //90M/90=1M的计数频率,自动重装载为500,那么PWM频率为1M/500=2kHZ while(1) { delay_ms(10); /*if(dir)led0pwmval++; //dir==1 led0pwmval递增 else led0pwmval--; //dir==0 led0pwmval递减 if(led0pwmval》300)dir=0; //led0pwmval到达300后,方向为递减 if(led0pwmval==0)dir=1; */ //led0pwmval递减到0后,方向改为递增 TIM_SetTIM3Compare3(motor0pwmval); //修改比较值,修改占空比 TIM_SetTIM3Compare4(motor1pwmval); //修改比较值,修改占空比 } } 至于硬件电路连接,这里就不列出来了,要注意的是,要是驱动步进电机的话最好通过L298N去驱动,毕竟是大电流电机。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 01:13 , Processed in 0.818862 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号