打印
[STM32F0]

求助,关于定时器同步门控模式的问题

[复制链接]
3849|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
shi33|  楼主 | 2015-2-1 01:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
使用的是STM32F030F4P6,PA9复用为TIM1_CH2为输出比较翻转模式,PA6复用为TIM3_CH1为PWM输出模式。
TIM1为主模式,OC2REF为触发输出。
TIM3为从模式,从定时器1获得触发,并设置为门控模式。
最终要达到的效果是当PA9为高电平的时候PA6输出PWM波,当PA9为低电平的时候PA6停止PWM输出。

最终的效果却像图上那样是反过来的(变成PA9为低电平的时候PA6输出PWM波,当PA9为高电平的时候PA6停止PWM输出)黄色为PA9,蓝色为PA6。

下面是定时器配置代码,跪求帮忙找找原因。
void TIM1_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);   //使能定时器时钟
//引脚启用复用定时器功能   
    GPIO_InitStructure.GPIO_Pin = TIM1_OC_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
    GPIO_Init(TIM1_OC_PORT, &GPIO_InitStructure);
    GPIO_PinAFConfig(TIM1_OC_PORT, TIM1_OC_SRC, TIM1_OC_AF);
//使能定时器中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
//定时器时基配置
    TIM_TimeBaseStructure.TIM_Period = 65535;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//定时器输出比较配置   
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //输出比较翻转模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出状态启用
    TIM_OCInitStructure.TIM_Pulse = 1000;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;   //输出极性高
    TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCIdleState_Set;
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable); //预装载禁用
   
    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC2Ref);    //选择主模式的触发输出
    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);    //主从模式使能
   
    TIM_CtrlPWMOutputs(TIM1, ENABLE);  //使能主输出
    TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
}

void TIM1_StartOutput(uint16_t t_Pulse)
{
    TIM_ClearFlag(TIM1, TIM_FLAG_Update);   //清零更新标志
    TIM1->CNT = 0;           //清零计数器的值
    TIM1->CCR2= t_Pulse;     //装入比较值 CH1
    TIM_Cmd(TIM1, ENABLE);   //使能定时器17
}

void TIM3_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
//引脚启用PWM输出   
    GPIO_InitStructure.GPIO_Pin   = TIM3_PWM_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;       //复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //高速
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;   //无上下拉
    GPIO_Init(TIM3_PWM_PORT, &GPIO_InitStructure);
    GPIO_PinAFConfig(TIM3_PWM_PORT, TIM3_PWM_SRC, TIM3_PWM_AF);   //启用定时器引脚
//定时器时基配置
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   //使能定时器3时钟
    TIM_TimeBaseStructure.TIM_Prescaler   = 0;      //指定时钟为
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
    TIM_TimeBaseStructure.TIM_Period      = TIM3_CH1PWM_PERIOD; //周期时间
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;      
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;   
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);     
//CH1输出配置
    TIM_OCInitStructure.TIM_OCMode       = TIM_OCMode_PWM1;   
    TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse        = TIM3_CH1PWM_PULSE;
    TIM_OCInitStructure.TIM_OCPolarity   = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCIdleState_Reset;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_OC1FastConfig(TIM3, TIM_OCFast_Enable);     //快速触发
   
    TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);      //选择从模式的触发源 TIM1
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); //从模式选择为 门控模式 高电平计数
   
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);
}

void TIM3_StartPWM(uint16_t t_Period,uint16_t t_Pulse)
{
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);   //清零更新标志
    TIM3->CNT = 0;           //清零计数器的值
    TIM3->ARR = t_Period;    //装入周期值
    TIM3->CCR1= t_Pulse;     //装入占空值
    TIM_Cmd(TIM3, ENABLE);   //使能定时器3
}

沙发
戈卫东| | 2015-2-1 09:52 | 只看该作者
极性?

使用特权

评论回复
板凳
huzi2099| | 2015-2-1 09:53 | 只看该作者
你这个最好是用高级定时器的互补功能实现.

使用特权

评论回复
地板
shi33|  楼主 | 2015-2-1 20:08 | 只看该作者

你说的极性是指?
按照定时器从模式选择门控模式,应该是触发源为高电平时定时器计数,但是现在反过来了。

使用特权

评论回复
5
shi33|  楼主 | 2015-2-1 20:09 | 只看该作者
huzi2099 发表于 2015-2-1 09:53
你这个最好是用高级定时器的互补功能实现.

互补没办法实现吧?

使用特权

评论回复
6
huzi2099| | 2015-2-1 22:19 | 只看该作者
shi33 发表于 2015-2-1 20:09
互补没办法实现吧?

可以的,我做过的,这是最好的实现方式.

使用特权

评论回复
7
戈卫东| | 2015-2-2 01:26 | 只看该作者

我测试的波形。没有问题。
如果TIM1输出极性翻转(TIM1->CCER的BIT5=1),就会得到你的波形。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
shi33 + 1 很给力!
8
戈卫东| | 2015-2-2 01:36 | 只看该作者
检查下你的示波器是不是那个通道反相

使用特权

评论回复
9
shi33|  楼主 | 2015-2-2 09:22 | 只看该作者
戈卫东 发表于 2015-2-2 01:26
我测试的波形。没有问题。
如果TIM1输出极性翻转(TIM1->CCER的BIT5=1),就会得到你的波形。

很感谢,昨晚睡前搞定了。 忽略了手册上这么写的
These bits define the behavior of the output reference signal OC1REF from which OC1 and
OC1N are derived. OC1REF is active high whereas OC1 and OC1N active level depends on
CC1P and CC1NP bits.
就是说,OC1REF 的输出是由 OC1 跟OC1N的极性共同决定的,我的代码只写了OC1,所以一直搞不定

使用特权

评论回复
10
戈卫东| | 2015-2-2 14:20 | 只看该作者
但是我觉得不是你楼上说的原因。。。
我觉得你的示波器的那个通道带了“反相”。。。。。

使用特权

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

本版积分规则

2

主题

22

帖子

0

粉丝