找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13525|回复: 0
打印 上一主题 下一主题
收起左侧

STM32 PWM输出无信号的问题解决

[复制链接]
跳转到指定楼层
楼主
ID:98618 发表于 2016-1-22 01:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者:Miler Shao
近日,从ST MCU技术论坛看到一个贴子,觉得有点意思,拿过来稍作整理交流下。

发帖者问: 我利用stm32f103要做PWM輸出,利用timer1 GPIO PE8, PE9 做輸出程式碼如下,當我將PE8,9設定為out_pp時利用示波器可以看到波形輸出,但是一設定成AF_PP時,示波器就看不到任何輸出了!所以想要請問,我下面的程式碼哪裡出錯了呢?


从上面的繁体字和措辞不难看出发帖者极可能是港台同胞。文字信息就这么多。另外发帖者还附加了下面一些程序配置代码。

void Time_init(void)
{
TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1,DISABLE);
TIM1_TimeBaseInitStruct.TIM_Prescaler = 999;
TIM1_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM1_TimeBaseInitStruct.TIM_Period = 8;
TIM1_TimeBaseInitStruct.TIM_ClockDivision = 0x0;
TIM1_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&TIM1_TimeBaseInitStruct);
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);
TIM_Cmd(TIM1,ENABLE);
}

void pwm_init(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 120;

TIM_OC1Init(TIM1,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 680;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);


TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1 );

TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);
TIM_Cmd(TIM1, ENABLE);
}

void GPIO_Configuration(void)
{
GPIO_InitTypeDef g;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);

g.GPIO_Pin = GPIO_Pin_9;
g.GPIO_Mode = GPIO_Mode_AF_PP;
g.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &g);

g.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9 ;
g.GPIO_Mode = GPIO_Mode_AF_PP;
g.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &g);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);
}

int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
Time_init();
pwm_init();
while(1);
}
void TIM1_CC_IRQHandler(void) //Interruptroutine
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

GPIOE-> ODR ^= GPIO_Pin_9;
}
}


可以看出,发帖的代码是基于ST 官方的传统标准外设库来写的。上面代码对TIM1ARRCCR1CCR2及相关捕捉中断做了配置并使能。PE8/PE9做了GPIO及复用配置,开启了TIM1复用脚的部分REMAP功能。针对上述问题,下面拟出几点一起交流下。


1看看上面红色的捕捉中断代码。竟然发现有对GPIOPE9的翻转操作,感觉上他是希望利用捕捉中断做GPIO翻转来实现PWM输出?

诚然,在使用有些其它品牌MCU芯片的时候,要实现PWM输出可能不太方便,需借助定时中断和GPIO翻转来实现。这个过程实现起来往往并不是很方便,也有诸多局限性。对于ST MCU,不论STM8还是STM32所有芯片都能利用内部的定时器轻松实现PWM输出。只需做些基本配置,给定信号周期和脉宽就好,无须借助CPU中断来协助实现。


2发帖者的描述信息中没有给出完整的STM32芯片型号,不说完整芯片型号经常是个麻烦事。STM329大系列,几百个料号。其实不少问题是跟具体料号息息相关的。所以,如果通过邮件或网络咨询时,提供完整的信息是必须的。


上图是STM32F1系列参考手册里关于TIM1复用功能REMAP的表格。


发帖配置了PE8/PE9却又只是做了PARTIAL REMAP, 结合上图表格得知TIM1OC1/OC2输出只能出现在PA8/PA9。不知怎么又扯到PE8/PE9了。如果用PE8PE9,那对应的OC输出应该是OC1OC1N这对互补输出,这跟OC1/OC2又并不一样,而且还得做FULL REMAP操作才行。也就是说,按照他的配置,在PE口是看不到TIM1_CH1/2OC输出的,具体到这里就是不能在PE口看到PWM输出。


3发帖说当他把PE9GPIO模式配置为OUT_PP时能看到脉冲,配置为AF_PP时又看不到,这是怎么回事呢?

在标准库里对GPIO输出模式有相关定义,这里的OUT_PPAF_PP分别是指GPIO_MODE_OUT_PP和GPIO_Mode_AF_PP前者GPIO不做复用时的输出配置;后者是指GPIO做复用输出时的配置。

尽管发帖的代码有点混乱,但他的定时器1的基本配置还是能工作的,导致捕捉中断能进入。前面提过,在捕捉中断里他做了PE9IO翻转。作为普通GPIO口,即配置为GPIO_MODE_OUT_PP,当然能用示波器看到该脚翻转的脉冲,但这并等同于来自STM32定时器硬件实现的PWM信号,纯粹IO翻转脉冲。而当PE9被配置为GPIO_Mode_AF_PP时,意味着它要输出其它复用信号,而不是本身IO通道的信号。前面说了,按他现有配置,PWM输出是到不了PE9的,此时看不到IO翻转信号也就不难理解了。

下面是STM32F1系列GPIO管脚复用时的原理框图


4发帖的代码混乱还有个地方,那就是关于PWM的脉宽和信号周期的设置。上面的代码里信号周期设置为8个预分频时钟,而2个通道的脉宽却配置为120680个,即CCRARR大得多。按照这样的配置,即使其它有关GPIO复用及REMAP的地方配置无误,它也无法在相应管脚看到PWM跳变脉冲。因为两个通道都没有电平翻转的机会,输出一定是个固定电平。具体是高还是低跟PWM输出模式与CCR的值有关。经常有人在参考库代码基础上,机械地对个别数据一通神改,结果发现PWM出不来了。还比如,对DEADTIME参数的随意修改,也会导致同样问题。


5STM32F1系列是目前STM32 九大系列中推出得最早的,其有关管脚复用配置个人觉得是最啰嗦的,没有后面推出的STM32F0F4F3等系列的配置简洁。另外印象中STM32F1系列也是唯一没有二级加密保护的芯片。如果可能的话,在新品选型时不一定要拘泥于STM32F1,其实STM32家族中有很多性价比很好的型号可以选择。再就是对于初学者的STM32开发,建议使用STM32CUBEMX做初始化配置。尤其涉及到管脚复用和重映射的地方,操作简单快捷,不易出错。也建议尽量使用ST官方推出CUBE固件库,里面资源比传统固件库更为丰富。


6程序代码的正确,终究离不开对原理的清晰理解。不论有多好、多方便的工具,它不论代替你对原理的理解和把握。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表