历史上的今天
返回首页

历史上的今天

今天是:2024年10月05日(星期六)

正在发生

2018年10月05日 | 【STM32电机方波】记录4——PWM输出配置

2018-10-05 来源: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的引脚配置及复用功能映像:

【STM32电机方波】记录4——PWM输出配置
【STM32电机方波】记录4——PWM输出配置
根据以上重映像表,我们使用定时器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 外设的参与。


推荐阅读

史海拾趣

Connect-Tech Products Corp公司的发展小趣事

Connect-Tech Products Corp公司深知人才是企业发展的核心力量。因此,公司注重人才培养和团队建设,通过定期举办培训、组织技术交流活动等方式,提升员工的专业技能和综合素质。同时,公司还建立了完善的激励机制,鼓励员工创新创造,为公司的发展贡献智慧和力量。这些举措不仅增强了公司的凝聚力和向心力,也为企业的发展提供了有力的人才保障。

Essentra Components公司的发展小趣事

Essentra Components公司一直将客户服务放在首位,通过提供优质的售前咨询、售中支持和售后服务,赢得了客户的广泛赞誉。公司不仅为客户提供了丰富的产品选择,还根据客户的具体需求提供定制化的解决方案。此外,公司还建立了完善的物流配送体系,确保产品能够及时、准确地送达客户手中。这些努力使得Essentra Components在客户中树立了良好的口碑,为公司的发展奠定了坚实的基础。

Discera公司的发展小趣事

在成功进入军用市场后,Discera公司开始将目光投向更广阔的商用市场。他们积极与各大电子厂商合作,推广自己的CMOS MEMS谐振器产品。随着技术的不断普及和成本的降低,越来越多的商用电子产品开始采用Discera的谐振器产品,公司的市场份额也逐步扩大。

Amidon Associates Inc公司的发展小趣事

在成功进入军用市场后,Discera公司开始将目光投向更广阔的商用市场。他们积极与各大电子厂商合作,推广自己的CMOS MEMS谐振器产品。随着技术的不断普及和成本的降低,越来越多的商用电子产品开始采用Discera的谐振器产品,公司的市场份额也逐步扩大。

FETek Technology(东沅)公司的发展小趣事

随着业务的不断扩展,东沅开始寻求国际化的发展道路。他们积极参加国际电子展会和技术交流活动,与全球各地的客户和合作伙伴建立了广泛的联系。同时,东沅还加大了对品牌建设的投入,通过广告宣传、媒体合作等方式提升品牌知名度和美誉度。这些努力使得东沅在国际市场上逐渐崭露头角,成为一家备受瞩目的电子企业。

科通(COMTEK)公司的发展小趣事

为了进一步扩大市场份额,科通技术积极实施国际化战略。公司在全球范围内设立了多个办事处和分公司,加强了与国际市场的联系和合作。同时,科通技术还积极参加国际电子展会和论坛等活动,展示公司的最新产品和技术成果,提升了公司的国际知名度和影响力。

问答坊 | AI 解惑

美女,请嫁给我们电子工程师!

美女,当你选择丈夫时,请先把电子工程师与以下的职业作一番比较:      医生     几乎所有女人都喜欢追求当医生的。所以不要期望你们的婚姻能持续五年以上,因为早晚有一天,他会跟某个护士小姐跑掉的,或是被一个假装生病的年轻女人 ...…

查看全部问答>

请教:关于51单片机P0口上拉至6.5V问题

哪位大虾有什么好方法使51单片机的P0口上拉到6.5V(单片机供电为3.3V,P0口用作输出口,产生0~6.5V的方波,无需驱动能力)。 我试过直接用10K电阻上拉的方式,由于PAD上有ESD结构,结果PIN脚上的电压被钳位置3.8V了。 不知哪位大虾能帮忙解决一 ...…

查看全部问答>

几种简单的直流升压电路

一、几种简单的直流升压电路 以下是几种简单的直流升压电路,主要优点:电路简单、低成本;缺点:转换效率较低、电池电压利用率低、输出功率 一、几种简单的直流升压电路 以下是几种简单的直流升压电路,主要优点:电路简单、低成本;缺点:转换 ...…

查看全部问答>

Wince下Flash开发

我在找到了一个flash播放器的源码,flash5的,移植了下,在wince6的平台下运行起来了,有图像,但没声音.有没有那个大侠有wince下的flash源码,能正常播放的,有声音和图片的.帮忙发给个给我!…

查看全部问答>

请教这段话的意思,谢谢!

CQueuedPipe(Interrupt)::CheckForDoneTransfers - failure on TD 0x3e58c0, address = 1, endpoint = 1, errorCounter = 0, status field = 0x22 这是USB驱动里的调试信息中的一句话,谁知道呢?分不够再加。…

查看全部问答>

IAR烧写uCOS程序后不能调试的原因?

                                 用IAR烧写进去后不能调试,一调试就死机(没有响应)是什么原因?用得是EKSTM32开发板上的仿真器…

查看全部问答>

只想问一下~~~

不知ST有没有计划做网口+外部总线的STM32呢?呵呵 发点消息出来呀~~~,没的话,就转Ti去了,呵呵…

查看全部问答>

430单片机1.2伏还是低电平吗??

我现在测试低电平LED亮; 发现1。2V 时LED还是亮的 当我把测试脚接3。6V电源时 LED 就灭了 是不是1。2V还是低电平啊 还有就是 我要检测的引脚平时是悬空,有外部动作时是低电平,那么该怎么做…

查看全部问答>

试试sparten 6的以太网性能如何

不知道大家有谁试过他的100M以太网的性能,最好在此交流一下。…

查看全部问答>

考研或者就业

请问各位前辈,本人对电子很感兴趣,现在纠结于考研或者就业,各位过来人有什么好的经验和建议?? 诚心求教…

查看全部问答>