打印

求助,TIM1的PWM输出不能第二次初始化

[复制链接]
3601|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zepanwucai|  楼主 | 2012-6-26 23:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
调这个调了很久,还是找不出原因,把调试得到的一些现象放上来,希望前辈们能指点迷津!背景:Preset_Init()是初始化SPWM的函数,调用完成后可以产生预置频率的SPWM,函数中包含初始化PWM的函数pwm_init(&PWM1);
现象:调试到最后,把程序删减成如下几句:
Preset_Init();
Preset_Init();
while(1);
这时,SPWM一直存在,程序正常。
然而,改成下面这样,单步调试可知在第二次执行Preset_Init();后SPWM就没了,PWM也没有输出了(恒为0V)
while(1)
{
Preset_Init();
}
单步跟踪的结果是,Preset_Init();->pwm_init(&PWM1);->TIM_OC1Init(PWMx->TIMx, &TIM_OCInitStructure);->TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);
最后那句关闭输出使能后,pwm停止输出,后面重新初始化PWM并使能后pwm却不再出现了。。
另外查看TIM1的相关寄存器发现,正常输出pwm和无法输出pwm时各寄存器设置是一样的,定时器都在走,自动重装,pwm输出也是使能的。。
还有,一直run的时候发现RCR偶尔会从0x88变到0x01,而单步调试的时候却看不到这个变化。

求问这到底是什么原因呢?
沙发
acgean| | 2012-6-27 08:44 | 只看该作者
关注一下 LOCK 的设置。
我估计应该有差别, 再对比两次的各个寄存器的值。
RCR偶尔会从0x88变到0x01, 这也不应该, 是不是软件哪里有缺陷

使用特权

评论回复
板凳
figo20042005| | 2012-6-27 09:10 | 只看该作者
while(1)
{
Preset_Init();
}
                                        你不是一直在初始化啊,PWM还没完成,你又初始化更新了

使用特权

评论回复
地板
zepanwucai|  楼主 | 2012-6-27 10:21 | 只看该作者
2# acgean LOCK位一直是0额。。
下面是调试时用的程序的全部代码(简化了下):
void Preset_Init(void)
{
TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
DMA_InitTypeDef  DMA_InitStructure;
//设置TIM2,定时T/P_COUNT

//打开定时器的时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

//TIMx寄存器重设为缺省值

TIM_DeInit(TIM2);

//时钟源,内部时钟

TIM_InternalClockConfig(TIM2);

//不预分频,72M

TIM_TimeBaseStructure.TIM_Prescaler=1-1;

//初始化时基

TIM_TimeBaseStructure.TIM_Period=SystemCoreClock/P_COUNT/MW.f_set;//自动重装载寄存器周期的值

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频,不分频

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

//允许更新事件

TIM_ITConfig(TIM2, TIM_IT_Update|TIM_IT_Trigger,ENABLE);  

//清TIM2计数器

TIM2->CNT = 1;

TIM2->SR&=~TIM_FLAG_Update;

//开启时钟

TIM2->CR1 |= TIM_CR1_CEN;
//PWM初始化

pwm_init(&PWM1);
}

void pwm_init(PWM_TypeDef *PWMx)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
u16 ps ;
//预分频值


//开启时钟,下面是简写过的,去掉switch..case等,看起来清楚些

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);




RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//初始化IO

GPIO_InitStructure.GPIO_Pin=PWMx->Pinx;
//对应引脚

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//复用输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//输出速度最高

GPIO_Init(PWMx->GPIOx, &GPIO_InitStructure);

//重映射开启





GPIO_PinRemapConfig(PWMx->GPIO_Remap, ENABLE);
  

//根据要产生的频率计算分频值

ps=1-1;

//定时器时基初始化

TIM_TimeBaseStructure.TIM_Period =(u16)(SystemCoreClock/(PWMx->f)/(ps+1)-0.5);

TIM_TimeBaseStructure.TIM_Prescaler = ps;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(PWMx->TIMx, &TIM_TimeBaseStructure);

//PWM输出初始化

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//边沿对齐

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse =(u16)(SystemCoreClock/(PWMx->f)/(ps+1)*(PWMx->duty)-0.5);

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

//根据不同通道初始化

TIM_OC1Init(PWMx->TIMx, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(PWMx->TIMx, TIM_OCPreload_Enable);

//使能ARR自动重装

TIM_ARRPreloadConfig(PWMx->TIMx, ENABLE);

/* TIMx enable counter */

TIM_Cmd(PWMx->TIMx, ENABLE);

//如果是高级定时器需要再加

if(PWMx->TIMx==TIM1)

TIM_CtrlPWMOutputs(PWMx->TIMx,ENABLE);

}


void TIM2_IRQHandler(void)
{

TIM2->SR&=~TIM_FLAG_Update;

TIM1->CCR1=sin_data[sin_index];

sin_index=(sin_index+1)%P_COUNT;
}


中断优先级是分组2,TIM2占先1,响应0.
以上就是调试时用的全部代码了,希望前辈能指点一下!

使用特权

评论回复
5
zepanwucai|  楼主 | 2012-6-27 10:23 | 只看该作者
3# figo20042005 这只是调试时简单起见写的,即使在while里加Delay几秒的延时结果还是一样的,第二次执行还是会无法输出。。

使用特权

评论回复
6
zepanwucai|  楼主 | 2012-6-27 17:59 | 只看该作者
顶顶

使用特权

评论回复
7
figo20042005| | 2012-6-27 20:19 | 只看该作者
建议不要这样更新配置,可以在PWM中断中改变配置

使用特权

评论回复
8
150625| | 2018-8-28 20:02 | 只看该作者

楼主最后找到原因了吗?我也遇到相似的,不知道什么原因

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

180

帖子

6

粉丝