您现在的位置是:首页 >其他 >江协科技stm32-[6-5] PWM驱动直流电机-PWM配置研究及关键代码网站首页其他
江协科技stm32-[6-5] PWM驱动直流电机-PWM配置研究及关键代码
简介江协科技stm32-[6-5] PWM驱动直流电机-PWM配置研究及关键代码
江协科技stm32-[6-5] PWM驱动直流电机-PWM配置研究及关键代码
码字不易,点个赞在看吧(如果能关注就更好了😊)
文章如有错误,更欢迎各位大佬指出,谢谢啦😘
1. 程序原理聚焦提问:
- 为什么PWM的产生原理叫做定时器输出比较?
- 为什么PWM输出要用GPIO口的复用推挽输出模式?
- 程序中我们定义了函数
void Motor_SetSpeed(int8_t Speed),并在其中用函数PWM_SetCompare3(Speed);来进行调速,那么笔者问个问题,Speed有单位吗?如果没有,那Speed的含义是什么?
2.程序原理聚焦回答:
- 见我的上一篇回答定时器输出比较原理及PWM配置研究
AF(Alternate Function):表示该引脚不是普通 GPIO,而是 连接到片上某个外设(这里是TIM2)。
PP(Push-Pull):推挽输出模式,意味着该引脚可以输出 高电平(Vcc)或低电平(GND),并且内部结构带有 下拉/上拉,驱动能力较强,适用于高速信号传输(如PWM、SPI、USART)。
如果不使用 AF_PP,而使用 GPIO_Mode_Out_PP(普通推挽输出):
该引脚不会被 TIM2 控制,而是作为普通 GPIO,由 GPIOx->ODR 控制。
这样 PWM 波形不会正确输出。
- 这里的Speed就是上篇文章提到过的定时器输出比较原理及PWM配置研究CCR寄存器的值啦!
3. 程序核心代码:
PWM.c
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //TIM2是APB1总线的外设
//初始化GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//初始化AFIO,进行引脚(复用功能)重映射
/*
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出才能够将引脚控制权交给片上外设,PWM波才能够通过引脚输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2); //定时器上电后默认使用内部时钟,不写也行
//配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 50; //CCR
//频率1KHz,占空比为50%
//PA0口对应输出通道1
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare3(uint16_t Compare)
{
TIM_SetCompare3(TIM2, Compare);
}
Motor.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
void Motor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5);
PWM_Init();
}
void Motor_SetSpeed(int8_t Speed)
{
if(Speed >= 0){
//正转
GPIO_SetBits(GPIOA, GPIO_Pin_4);
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
PWM_SetCompare3(Speed);
}else{
//反转
GPIO_SetBits(GPIOA, GPIO_Pin_5);
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
PWM_SetCompare3(-Speed); //Speed必须为正数
}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。




QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
U8W/U8W-Mini使用与常见问题解决
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结