STM32的PWM输出及频率和脉宽(占空比)的计算
09:35:22编辑:什么鱼 关键字:&&&&&&&&
一、stm32的pwm输出引脚是使用的IO口的复用功能。
二、T2~T5这4个通用定时器均可输出4路PWM&&CH1~CH4。
三、我们以tim3的CH1路pwm输出为例来进行图文讲解(其它类似),并在最后给出tim3的ch1和ch2两路pwm输出的c代码(已在F103RBT6上测试成功,大家放心使用!)。
四、给出了PWM和的计算公式。
步骤如下:
1、使能TIM3时钟
RCC->APB1ENR |= 1 << 1;
2、配置对应引脚(PA6)的复用输出功能
GPIOA->CRL &= 0XF0FFFFFF;//PA6清0
GPIOA->CRL |= 0X0B000000;//复用功能输出(推挽50MHz输出)
GPIOA->ODR |= 1 << 6;//PA6上拉
3、设定计数器自动重装值及是否分频
TIM3->ARR =//设定计数器自动重装值(决定PWM的频率)
&TIM3->PSC =//预分频器,0为不分频
4、设置PWM的模式(有1和2两种模式,区别在于输出电平极性相反),根据需求选一种即可
注:TIMX_CCMR1决定CH1~CH2路,TIMX_CCMR2决定CH3~CH4路。
//TIM3->CCMR1 |=&6 << 4;//CH1 PWM1模式&
TIM3->CCMR1 |= 7 << 4;//CH1 PWM2模式&
&TIM3->CCMR1 |= 1 << 3;//CH1预装载使能
5、输出使能设置
TIM3->CCER& |= 1 << 0;//输入/捕获1输出使能
6、自动重装载预装载允许位(ARPE) 及 定时器&使能
TIM3->CR1 = 0X0080;//ARPE使能(此句不配置也行)
TIM3->CR1 |= 0X01;//使能定时器3
下面给出TIM3_CH1及TIM3_CH2的代码:
void PWM_Init_TIM3_CH1(u16 arr, u16 psc)
&&&&//1、使能TIM3时钟&&&
&&& RCC->APB1ENR |= 1 << 1;//使能TIM3时钟
&&&&//2、配置对应引脚(PA6)的复用输出功能
&&& GPIOA->CRL &= 0XF0FFFFFF;//PA6清0
&&& GPIOA->CRL |= 0X0B000000;//复用功能输出(推挽50MHz输出)
&&& GPIOA->ODR |= 1 << 6;//PA6上拉&&&
&&&&//3、设定计数器自动重装值及是否分频
&&& TIM3->ARR =//设定计数器自动重装值(决定PWM的频率)
&&& TIM3->PSC =//预分频器 0为不分频
&&&&//4、设置PWM的模式
&&& TIM3->CCMR1 |= 7 << 4;//CH1 PWM2模式&
&&& TIM3->CCMR1 |= 1 << 3;//CH1预装载使能&&&&
&&&&//5、输出使能设置
&&& TIM3->CCER& |= 1 << 0;//输入/捕获1输出使能
&&&&//6、自动重装载预装载允许位(ARPE) 及 定时器&使能
&&& TIM3->CR1 = 0X0080;//ARPE使能
&& &TIM3->CR1 |= 0X01;//使能定时器3
void PWM_Init_TIM3_CH2(u16 arr, u16 psc)
&& &RCC->APB1ENR |= 1 << 1;//使能TIM3时钟
&&& GPIOA->CRL &= 0X0FFFFFFF;//PA7清0
&&& GPIOA->CRL |= 0XB0000000;//复用功能输出(推挽50MHz输出)
&& &GPIOA->ODR |= 1 << 7;//PA7上拉
&& &TIM3->ARR =//设定计数器自动重装值(决定PWM的频率)
&& &TIM3->PSC =//预分频器 不分频
&& &TIM3->CCMR1 |= 7 << 12;//CH2 PWM2模式
&&& TIM3->CCMR1 |= 1 << 11;//CH2预装载使能
&& &TIM3->CCER& |= 1 << 4;//输入/捕获2输出使能
&& &TIM3->CR1 = 0X0080;//ARPE使能
&&& TIM3->CR1 |= 0X01;//使能定时器3
//Fpwm = 72M / ((arr+1)*(psc+1))(单位:Hz)
//duty circle = TIM3->CCR1 / arr(单位:%)
注:本文方法的一个定时器4个通道的pwm输出的频率是相同的,但占空比可以不同!
关键字:&&&&&&&&
来源: eefocus
引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
关注eeworld公众号快捷获取更多信息
关注eeworld服务号享受更多官方福利
/*&名称:C51、STM32和S3C2440中断体系的比较&说明:对于这三个芯片的中断体系来说,就我目前了解的, 我说:差不多。这里说的差不多,是中断的本质上差不多,都是首先中断源提出申请(比如触发了外部中断,定时器中断等),然后经过中断源屏蔽寄存器,再然后中断优先级的比较,最后CPU相应中断。(我去,这好像又回到了计算机组成原理啊)。不同的是细节,C51作为低级一点的芯片,其中断少,中断能达到的功能也少,相对来说较为简单些(无论是设计还是具体使用)。而STM32和S3C2440来说,其提供的功能较多,设计起来和使用起来要复杂的多(使用的时候得配置好多好多寄存器)。目前总结的,差不多就是这些吧。*/
/*&名称:STM32_GPIO之按键输入&说明:这个实验是GPIO的输入功能。基本的思路和51单片机差不多。也是&操作相应的IO口,不过不同的是对于独立按键输入实验来说,51单片机是&需要一开始把待检测的IO口设置成高电平,然后检测其何时被拉低。而对&于STM32来说,其GPIO端口就可以设置成上拉输入,即不需要再人为的把对&应的对应的IO口设置成高电平,硬件电路会自动把对应端口引脚拉成高电&平。还有一点关于条件编译要说的:这个ifndef… #endif 一般用在头文件中。书上说为了防止重复编译。就我目前了解的来看,在实际应用中,如果在两个.c源文件中都
/*&名称:STM32之利用I2C协议读写EEPROM&说明:&1.利用STM32来读写EEPROM和C51最大的不同就是,前者是直接使用I2C控制器(硬件方式)来产生所需要的I2C时序,而后者是通过软件方式来产生I2C时序。相对来说,前者使用硬件电路简化了编程的复杂性,用户只要将数据发送到相应的数据寄存器,然后I2C控制器自动按照I2C协议把数据通过SCL和SDA总线发送出去。而后者,你必须按照I2C协议手动产生SCL和SDA的高低电平。当然对于EEPROM来说,它是感受不到发送来的数据是通过硬件电路还是软件方式产生的。2.还有,STM32内部集成的I2C控制器不仅可以产生时序,还包括了一些
/*&名称:STM32有关GPIO引脚的一些问题&说明:今天在编写一个键盘扫描程序的时候,出现了一些问题。&有的引脚能读出电平状态、有点引脚确一直读不出状态。改了一下午,查了好久,终于有点眉目了。现简述如下:&我在用引脚的时候,使用的是PB0、PB1、PB2、PB3、PB4…,将其引脚配置的方式是上拉输入。PB2、PB3、PB4一直有问题。PB0、PB1是可以读出状态的(但是只能单独使用)。对于PB2来说,其不仅是PB2,它也是BOOT1引脚。当系统复位之后,开始的几个系统时钟使用的是BOOT1,用来判断系统从何处读取置零。之后,PB2就可以作为普通的IO引脚使用了。由于开发板设置
/*&名称:STM32定时器之控制LED灯循环显示&说明:对于STM32来说,其定时器要比C51的定时器要多,功能也更复杂。就数目来说来说,STM32的定时器可以分为基本定时器,通用定时器和高级定时器(还包括Systick、看门口定时器和窗口定时器)。就STM32F103,一般来说,它有2个高级定时器TIM1和TIM8、4个通用定时器TIM2/3/4/5、2个基本定时器TIM6和TIM7。而C51一般只有几个定时器。就功能来说,&STM32中:&对于基本定时器,其功能就是和C51差不多,只有定时功能。&对于通用定时器,它的功能有定时、输出比较、输入捕获。虽然目前,我也不知道后面两个
***************************************************************************************************************************************开发板 & :奋斗STM32CPU & & & &:STM32F103开发环境:keil uVsion4
热门资源推荐
■等你报名做客黑科技直播间:基于 TI DLP®技术的工业创新应用介绍
■有奖直播:TI MSP430TM集成可配置信号链模块在传感测量领域的应用
最新单片机文章
最新视频课程
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。
相关热搜器件STM32F103高级定时器TIM1产生六路PWM控制无刷舵机BLDC - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 3761|回复: 18
STM32F103高级定时器TIM1产生六路PWM控制无刷舵机BLDC
在线时间8 小时
该用户从未签到主题帖子精华
初级会员, 积分 151, 距离下一级还需 49 积分
首次发帖、不周之处请指正!
先描述下问题,最近在做120度霍尔BLDC的控制,用STM32F103 TIM1产生六路PWM时出现问题。
想要实现的控制状态是可以控制六个通道中任何一个通道的PWM输出与关断,不用互补、不需要死区
选用引脚:
TIM1配置如下图
我想要6路PWM的,但是只产生四路& &PB0与PB1只在刚开始有输出
而且,当我把CH1设置为Disable时,CH1N仍然是Enable
仿真结果如下,CH1与CH1N不输出、其他四路输出正常
由此产生了几个问题
1、CH1的设置 会对PB0(CH2N)&&PB1(CH3N)产生影响? CH1 Enable,CH2N、CH3N不输出,CH1 Disable CH2N、CH3N输出
2、CH1由Enable变为Disable&&对CH1N的输出产生了影响,CH1 的失能与使能时CH1与CH1N的总开关?我之后使能CH1、失能CH1N,除CH1N以外的其余五路输出
怀疑是库函数的原因、尝试用寄存器写&&手册与配置&&仿真结果如下图
想要的输出状态是上图红线标注的& &CH通道关闭&&CHN通道输出,百度过这种输出状态,有人说可以实现但是没讲方法
这样配置六路均有输出、但是PB0、PB1不正常&&而且也不是我想要的输出状态,可能是配置问题,很少用寄存器,不清楚这么对不对,请指正
前边都是截图,补一下TIM1配置部分、main部分代码
int main(void)
& & delay_init();
15:44 上传
点击文件名下载附件
下载积分: ST金币 -1
3.44 MB, 下载次数: 360, 下载积分: ST金币 -1
            
      
在线时间8 小时
该用户从未签到主题帖子精华
初级会员, 积分 151, 距离下一级还需 49 积分
void PWM_OUT_Init()
{
& & //PA8&&9&&10 对应CBA&&相&&PA7&&PB0 PB1 对应C-B-A-相&&复用推挽输出
& & GPIO_InitTypeDef GPIO_InitS
& & TIM_TimeBaseInitTypeDef TIM_TimeBaseS
& & TIM_OCInitTypeDef& && & TIM_OCInitS
//& & TIM_BDTRInitTypeDef& &&&TIM_BDTRInitS&&
& &
& & & & RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA , ENABLE); ///RCC_APB2Periph_AFIO
& & & & GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);&&//需要部分重映像
& & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_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_0 | GPIO_Pin_1;
& & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
& & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & GPIO_Init(GPIOB, &GPIO_InitStructure);
& &
& & & & TIM_DeInit(TIM1);
& & & &
& & /* Time Base configuration */
& & TIM_TimeBaseStructure.TIM_Prescaler = 0;
& & TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
& & TIM_TimeBaseStructure.TIM_Period = 4500;&&/// PWM 16K&&
& & TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
& & TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
& & TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
& & /* Channel 1, 2,3 and 4 Configuration in PWM mode */
& & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;&&///TIM_OCMode_PWM2&&TIM_OCMode_Timing
& & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
& & TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_E
& & TIM_OCInitStructure.TIM_Pulse = 2000;
& & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H&&///TIM_OCNPolarity_High
& & TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_L
& & TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_R ///TIM_OCNIdleState_Set
& & TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_R
& & & & TIM_OC2Init(TIM1, &TIM_OCInitStructure);
& & TIM_OC1Init(TIM1, &TIM_OCInitStructure);
& & & & TIM_OC3Init(TIM1, &TIM_OCInitStructure);
& & /* TIM1 counter enable */
& & TIM_Cmd(TIM1, ENABLE);
& & /* Main Output Enable */
& & TIM_CtrlPWMOutputs(TIM1, ENABLE);
int main(void)
{
& & delay_init();& & & && &&&& & & &&&//延时函数初始化& & & && &
& & NVIC_Configuration(); & & & &&&//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
& & GPIO_init();
& & USART_init();
//& & & & Hall_Init();
& & & & PWM_OUT_Init();
& & GPIO_SetBits(GPIOA,GPIO_Pin_1);&&//TX_OE
& & & & TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
& & & & TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
& & & & TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
& & & & /*&&Channel2 configuration */
& & & & TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1 );
& & & & TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
& & & & TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
& & & & /*&&Channel3 configuration */
& & & & TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
& & & & TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
& & & & TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);& & & &
& & & & //N 通道受主通道影响&&主DISABLE 则N通道也关闭
//& & & & TIM1-&BDTR &=0xfc00;&&//解锁
//& & & & TIM1-&BDTR |= 0x8800;
//& & & & TIM1-&CR2 |=0x1f80;
//& & & & TIM1-&CCER = 0x00;&&
//& & & & TIM1-&CCER |= 0x555;
}复制代码
代码部分没贴上去,补一下
在线时间276 小时
ST金币2302
该用户从未签到主题帖子精华
金牌会员, 积分 4595, 距离下一级还需 405 积分
            
      
在线时间3 小时
该用户从未签到主题帖子精华
初级会员, 积分 60, 距离下一级还需 140 积分
在线时间8 小时
该用户从未签到主题帖子精华
初级会员, 积分 151, 距离下一级还需 49 积分
            
      
在线时间2372 小时
ST金币974484
TA的每日心情开心 09:20签到天数: 1 天[LV.1]初来乍到主题帖子精华
图片也太小了吧,根本看不清
在线时间300 小时
ST金币3015
该用户从未签到主题帖子精华
楼主解决了吗,坐等结果呀
            
      
在线时间29 小时
该用户从未签到主题帖子精华
高级会员, 积分 632, 距离下一级还需 368 积分
关于如何输出六路互补带死区PWM波形,请关注“单片机STM32”公众号,里面有一篇文章“STM32定时器TIM1输出六路带死区互补PWM波形(一)”描述。
在线时间29 小时
该用户从未签到主题帖子精华
高级会员, 积分 632, 距离下一级还需 368 积分
            
      
在线时间8 小时
该用户从未签到主题帖子精华
初级会员, 积分 151, 距离下一级还需 49 积分
图片也太小了吧,根本看不清
感兴趣可以下载源文件看哈
在线时间8 小时
该用户从未签到主题帖子精华
初级会员, 积分 151, 距离下一级还需 49 积分
楼主解决了吗,坐等结果呀
最后驱动无刷使用的H_ON L_PWM的方式,只用了三路输出PWM,其余三路直接拉高拉低IO口
折腾了几天我的结论是 CH1的Enable与Disable是CH1与CH1N的总开关,无论寄存器还是库函数
引脚映射会对PWM输出产生影响,所以建议在最初调的时候先用原输出脚仿真
还有。。。有感无刷使用PWM方波驱动时有多种方式,六路互补输出不是必要的,而且也有论文指出六路PWM驱动的无刷会有MOS换相频繁、力矩波动的问题
STM32粉丝勋章Ⅳ
狂欢节专属(智多星)
STM32粉丝勋章Ⅲ
狂欢节专属(分享宝宝)
STM32粉丝勋章Ⅰ
狂欢节专属(微信上墙)
STM32粉丝勋章Ⅱ
狂欢节专属(研讨会问答)
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered by查看: 1943|回复: 1
STM32通用定时器(TIM2-5)PWM输出
本帖最后由 51黑黑黑 于
22:21 编辑
& &STM32的定时器是个强大的模块,定时器使用的频率也是很高的,定时器可以做一些基本的定时,还可以做PWM输出或者输入捕获功能。从系统框架图下看,名为TIMx的有八个,其中TIM1和TIM8挂在APB2总线上,而TIM2-TIM7则挂在APB1总线上。其中TIM1&TIM8称为高级控制定时器(advancedcontroltimer).他们所在的APB2总线也比APB1总线要好。APB2可以工作在72MHz下,而APB1最大是36MHz。
& &由上图可知,当APB1的预分频系数为1 时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8 或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率两倍。也就是,当APB1不分频,TIM3的时钟速度为36MHz,当2分频是,APB1变成18MHz,但是TIM又会倍频,即TIM时钟等于18*2=36MHz。这里我们用向上计数的方式,即TIMx_CNT中的计数值达到TIMx_ARR中的值时,产生中断,TIMx_CNT又从0开始计。
按以下步骤编程:
1.系统初始化,主要初始化时钟等。
2.GPIO初始化,用于LED,有了灯就便于观察了。
3.TIM3的配置。
4.NVIC的配置。
5.编写中断服务函数。
void GPIO_PA_Init()
{//PA8管脚配置
GPIO_InitTypeDef GPIO_InitS
GPIO_DeInit(GPIOA);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能端口时钟A
GPIO_Init(GPIOA,&GPIO_InitStructure);
void TIMER3_Init()
TIM_TimeBaseInitTypeDefTIM_TimeBaseS
TIM_DeInit(TIM3);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseStructure.TIM_Period=10000;//ARR的值
TIM_TimeBaseStructure.TIM_Prescaler=7200-1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3, ENABLE); //开启时钟
void NVIC_Configuration()
NVIC_InitTypeDef NVIC_InitS
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);&&// 抢占式优先级别
NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQC//指定中断源
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;// 指定响应优先级别1
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
int main(void)
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72);& &&&//延时初始化
GPIO_PA_Init();
TIMER3_Init();
NVIC_Configuration();
void TIM3_IRQHandler()
if(TIM_GetITStatus(TIM3 , TIM_IT_Update) ==SET)
&&TIM_ClearITPendingBit(TIM3 ,TIM_FLAG_Update);
&&if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8))GPIO_ResetBits(GPIOA, GPIO_Pin_8);
&&else GPIO_SetBits(GPIOA,GPIO_Pin_8);
&&脉冲宽度调制(PWM),是英文“Pulse WidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。
PWM输出模式
STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:
110:PWM模式1-在向上计数时,一旦TIMx_CNT&TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT&TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
111:PWM模式2-在向上计数时,一旦TIMx_CNT&TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT&TIMx_CCR1时通道1为有效电平,否则为无效电平。
由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。
而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。
PWM输出管脚
PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC.7上了。
PWM输出信号
PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。
按以下步骤配置:
1. 设置RCC时钟;
2. 设置GPIO时钟;
3. 设置TIMx定时器的相关寄存器;
4. 设置TIMx定时器的PWM相关寄存器;
& &第1步设置RCC时钟已经在前文中给出了详细的代码,在此就不再多说了。需要注意的是通用定时器TIMx是由APB1提供时钟,而GPIO则是由APB2提供时钟。注意,如果需要对PWM的输出进行重映像的话,还需要开启引脚复用时钟AFIO。
& &第2步设置GPIO时钟时,GPIO模式应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映像的话,则需要用GPIO_PinRemapConfig()函数进行设置。
& &第3步设置TIMx定时器的相关寄存器时,和前一篇学习笔记一样,设置好相关的TIMx的时钟和技术模式等等。
& &第4步设置PWM相关寄存器,首先要设置PWM模式(默认情况下PWM是冻结的),然后设置占空比(根据前面所述公式进行计算),再设置输出比较极性:当设置为High时,输出信号不反相,当设置为Low时,输出信号反相之后再输出。最重要是是要使能TIMx的输出状态和使能TIMx的PWM输出使能。相关设置完成之后,就可以通过TIM_Cmd()来打开TIMx定时器,从而得到PWM输出了。
以下是我写的参考程序:
void GPIO_PA_Init()
{//PA13管脚配置
GPIO_InitTypeDef GPIO_InitS
GPIO_DeInit(GPIOA);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能端口时钟A
GPIO_Init(GPIOA,&GPIO_InitStructure);
void TIMER3_Init()
TIM_TimeBaseInitTypeDefTIM_TimeBaseS
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_DeInit(TIM3);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseStructure.TIM_Period=10000-1;//ARR的值周期10K
TIM_TimeBaseStructure.TIM_Prescaler=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
void TIMER3_PWM_Init()
TIM_OCInitTypeDef TIMOCInitS
TIMOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1输出
TIMOCInitStructure.TIM_Pulse=0;//占空比=(CCRx/ARR)*100%
TIMOCInitStructure.TIM_OCPolarity =TIM_OCPolarity_H//TIM输出比较极性高
TIMOCInitStructure.TIM_OutputState =TIM_OutputState_E//使能输出状态
TIM_OC2Init(TIM3,&TIMOCInitStructure);//TIM3的CH2输出
TIM_CtrlPWMOutputs(TIM3,ENABLE);//设置TIM3的PWM输出为使能
TIM_Cmd(TIM3, ENABLE); //开启时钟
Powered by查看: 7754|回复: 7
利用STM32定时器输出2路PWM方波 怎么解决相位差的问题
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间0 小时
RT。。。要求相位差在0-359.9之间可调 并且分辨率不大于0.1度
呵呵,请回复
主题帖子精华
金钱131849
在线时间1216 小时
不大于0.1度....
可以用3个定时器,来实现你的要求.
具体:定时器A,B作为两路PWM的输出,他们的时钟由定时器C提供.这样你设置好A,B的初始值,然后再开启C作为他们的时钟,达到A,B在C的控制下同步工作,但相位可以设置.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
原子哥,&我们老师推荐的方法用所谓的&&“码表”&&来解决问题。但是码表是什么&老师没有明说。。&不知道&原子哥&能指点一下不
主题帖子精华
金钱131849
在线时间1216 小时
我也没用过.不知道所谓的码表是什么方法,呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间0 小时
回复【4楼】正点原子:
---------------------------------
e&..谢谢了啊。
主题帖子精华
初级会员, 积分 196, 距离下一级还需 4 积分
在线时间4 小时
回复【2楼】正点原子:
---------------------------------
定时器计数器的值可以自己写入吗??
主题帖子精华
金钱131849
在线时间1216 小时
主题帖子精华
新手入门, 积分 10, 距离下一级还需 10 积分
在线时间5 小时
你好,请问这个问题你解决了吗?
必看:"原子哥”力荐 /1
千讲STM32视频,文档覆盖STM32F1~STM32H7,数百个原创实例,让你一次嗨个够!
Powered by}