历史上的今天
今天是:2024年09月22日(星期日)
2018年09月22日 | 【STM32电机方波】记录4——PWM输出配置
2018-09-22 来源:eefocus
PWM生成原理:
通用定时器可以利用GPIO引脚进行脉冲输出,在配置为比较输出、PWM输出功能时,捕获/比较寄存器通用定时器可以利用GPIO引脚进行脉冲输出,在配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。 这里直接举例说明定时器的PWM输出工作过程:若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。 而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。 如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为 A/(N+1) 。
STM32产生PWM的配置方法:
1、配置GPIO口:
配置IO口的时候无非就是开启时钟,然后选择引脚、模式、速率,最后就是用结构体初始化。不过在32上,不是每一个IO引脚都可以直接使用于PWM输出,因为在硬件上已经规定了用某些引脚来连接PWM的输出口。下面是定时器的引脚重映像,其实就是引脚的复用功能选择:
a.定时器1/8的引脚配置及复用功能映像:


根据以上重映像表,我们使用定时器1的通道TIM1__CH2作为PWM的输出通道,若选择PA9引脚则应进行配置,如下:
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
//使能 GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); //选择Tim1完全重映像,即用了 PE11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化引脚
}
产生六路PWM互补输出的GPIO配置:
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; //PA8、9、10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //PB13、14、15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
产生六路PWM互补输出的TIM1设置:
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义时基结构体
TIM_OCInitTypeDef TIM_OCInitStructure;//定义输出结构体
TIM1_BDTRInitTypeDef TIM1_BDTRInitStructure; //定义死区结构体
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM1, ENABLE); //使能定时器1时钟
TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载寄存器ARR的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //TIM1预分频器PSC的值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割,不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据以上功能对定时器进行初始化
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式,TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputNState_Enable; //互补端输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出比较极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //输出互补端极性
//TIM1_OCInitStructure.TIM1_OCIdleState = TIM1_OCIdleState_Reset; //死区后输出状态
//TIM1_OCInitStructure.TIM1_OCNIdleState = TIM1_OCIdleState_Reset; //死区后互补端输出状态
TIM_OCInitStructure.TIM_Pulse = ccr1; //设置通道CH1/CH1N占空比
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //通道CH1/CH1N初始化
TIM_OCInitStructure.TIM_Pulse = ccr2; //设置通道CH2/CH2N占空比
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //通道CH2/CH2N初始化
TIM_OCInitStructure.TIM_Pulse = ccr3; //设置通道CH3/CH3N占空比
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //通道CH3/CH3N初始化
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM1_BDTRInitStructure.TIM1_OSSRState = TIM1_OSSRState_Enable; //运行模式下输出选择
TIM1_BDTRInitStructure.TIM1_OSSIState = TIM1_OSSIState_Enable; //空闲模式下输出选择
TIM1_BDTRInitStructure.TIM1_LOCKLevel = TIM1_LOCKLevel_OFF; //锁定设置
TIM1_BDTRInitStructure.TIM1_DeadTIM1 = 0xF2; //死区时间,2us
TIM1_BDTRInitStructure.TIM1_Break = TIM1_Break_Enable; //刹车功能使能
TIM1_BDTRInitStructure.TIM1_BreakPolarity =TIM1_BreakPolarity_High; //刹车输入极性
TIM1_BDTRInitStructure.TIM1_AutomaticOutput =TIM1_AutomaticOutput_Enable; //自动输出使能
TIM1_BDTRConfig(&TIM1_BDTRInitStructure);
TIM_Cmd(TIM1, ENABLE); //使能TIM1
TIM1_CtrlPWMOutputs(ENABLE); //使能TIM1的主输出
}
至此,用TIM1产生6路PWM互补输出的配置结束。
TIM1输出初始化缺省值:
{
TIM1_OCMode = TIM1_OCMode_Timing;
TIM1_OutputState = TIM1_OutputState_Disable;
TIM1_OutputNState = TIM1_OutputNState_Disable;
TIM1_Pulse = TIM1_Pulse_Reset_Mask;
TIM1_OCPolarity = TIM1_OCPolarity_High;
TIM1_OCNPolarity = TIM1_OCNPolarity_High;
TIM1_OCIdleState = TIM1_OCIdleState_Reset;
TIM1_OCNIdleState = TIM1_OCNIdleState_Reset;
}
TIM1死区初始化缺省值:
{
TIM1_OSSRState = TIM1_OSSRState_Disable;
TIM1_OSSIState = TIM1_OSSIState_Disable;
TIM1_LOCKLevel = TIM1_LOCKLevel_OFF;
TIM1_DeadTime = TIM1_DeadTime_Reset_Mask;
TIM1_Break = TIM1_Break_Disable;
TIM1_BreakPolarity = TIM1_BreakPolarity_Low;
TIM1_AutomaticOutput = TIM1_AutomaticOutput_Disable;
}
主要完成任务:
1、对无霍尔BLDC电机程序作了更深层的理解,尝试修改程序将 PWM_OFF的过零检测模式换成PWM_ON,删除程序冗余部分,对TIM 高级定时器的程序段作了详细注释,加深印象。
2、对有霍尔BLDC电机程序进行了解及解读,基本上理解其运行原理及程序编写方式。
带霍尔元件的BLDC电机:
与不带霍尔元件的电机的区别除了少了启动检测外,多了EXTI 外部中断,电机的转动程序在此中断服务子程序中。霍尔元件的检测采用了三个中断线路捕获转子位置。
对于其PWM输出与无霍尔元件BLDC电机相同,换向也是用六步换向为霍尔六步换向,但无过零检测即无ADC 外设的参与。
史海拾趣
|
汽车环境的宽工作电压要求、大瞬变电压以及大温度漂移等因素共同作用下,电子系统面临着严酷的条件,本文介绍如何在性能要求变得愈加苛刻的条件下,设计多个电源电压以满足汽车电子系统不同部分的要求。 ...… 查看全部问答> |
|
功率MOSFET具有导通电阻低、负载电流大的优点,因而非常适合用作开关电源(switch-mode power supplies,SMPS)的整流组件,不过,在选用MOSFET时有一些注意事项。 功率MOSFET和双极型晶体管不同,它的栅极电容比较大,在导通之前要 ...… 查看全部问答> |
|
如题. 做ARM开发,有时候会用到串并口,现在 的笔记本一般都没有,不知道大家有什么建议,我听朋友说,用转接口不太稳定.最好用台式机,不过我还是想换个带串并口的笔记本,大家有什么建议… 查看全部问答> |
|
eboot 分了 4个分区, 1个binfs 3个fatfs 3个fatfs在pc上都是别出来了, 现在遇到以下问题: 1). 我想隐藏其中2个fatfs分区, 因为 我要放 应用程序 用 所以需要隐藏起来 2). 现在分区的路径名是按默认的名字, 比如默认是 disk, 那么 后面几 ...… 查看全部问答> |
|
【课后练习】LaunchPad课后练习九之模拟SPI驱动数码管 LaunchPad课后练习九之模拟SPI驱动数码管 1.采用共阳极的数码管 数码管实际上是由7个发光管组成8字形构成的,加上小数点就是8个。 什么是共阳极呢?就是他们的公共端接正极。扫描型的意思是,几位的数码管的段选都是 ...… 查看全部问答> |
|
1、寄存器 R13 在 ARM 指令中常用作堆栈指针 2、对于 R13 寄存器来说,它对应6个不同的物理寄存器,其中的一个是用户模式与系统模式共用,另外5个物理寄存器对应于其他5种不同的运行模式。采用以下的记号来区分不同的物理寄存器: R13_ 其中,mo ...… 查看全部问答> |




