OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2792|回复: 5

求教,TIM1互补输出模式,互补通道的占空比不能改变

[复制链接]

8

主题

293

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1001
金钱
1001
注册时间
2018-8-16
在线时间
327 小时
发表于 2018-9-19 08:28:09 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 brucewoo 于 2018-9-19 12:05 编辑

问题已解决,是在其他地方的疏忽以及自己观察不仔细造成的,属于愚蠢的错误,惭愧惭愧。。。。
无论如何,谢谢回复的朋友。
//==============================================================

大家好,最近在看网上的教程自学STM32,今天在试验高级定时器的互补输出时,遇到了一个问题。

具体是,输出通道和互补输出通道各接上一个LED来直观的观察效果。
按照例程配置和初始化定时器和通道后,CH1和CH1N上接的LED会根据初始化时设定的TIM_Pulse值,有不同的明暗度,CH1和CH1N的明暗度相反,这应该符合互补输出的特性。

但是,如果在main函数里修改TIM1->CCR1的值,主通道LED的亮度会变化,但接互补通道的LED亮度没有变化。

请问这是为什么?
希望大家指点一下。

初始化的代码:
[mw_shl_code=c,true]RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);

/*--------------------时基结构体初始化-------------------------*/
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_TimeBaseStructure.TIM_Period=(1000-1);               
        TIM_TimeBaseStructure.TIM_Prescaler= (72-1);               
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;               
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;               
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;        
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

        /*--------------------输出比较结构体初始化-------------------*/               
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;         //反向通道有效
        TIM_OCInitStructure.TIM_Pulse = 4;               
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
        TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
        TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
        TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);               

        /*-------------------刹车和死区结构体初始化-------------------*/
        TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  TIM_BDTRInitStructure.TIM_DeadTime = 11;
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  TIM_BDTRConfig(ADVANCE_TIM, &TIM_BDTRInitStructure);
        
        // 使能计数器
        TIM_Cmd(ADVANCE_TIM, ENABLE);        
        TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);[/mw_shl_code]

Main函数中的代码:只有主通道的LED出来呼吸灯效果,互补通道的LED一直不会动
[mw_shl_code=c,true]if((Millis()-recMillis)<=(PWMLightCycle/2))
                {
                        TIM1->CCR1=PWMmax*((Millis()-recMillis)/((float)PWMLightCycle/2));
                }
                else if((Millis()-recMillis)<=(PWMLightCycle))
                {
                        TIM1->CCR1=PWMmax*(1-((Millis()-recMillis-(PWMLightCycle/2))/((float)PWMLightCycle/2)));
                }
                else
                {
                        recMillis=Millis();
                }[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=c,true]/* Prescaler = (TIM1CLK / TIM1 counter clock) - 1 TIM1_Priod = (SystemCoreClock / 50000) - 1 ARR = (TIM1 counter clock / TIM1 output clock) - 1 TIM1 Channel1 duty cycle = (TIM1_CCR1 / TIM1_ARR)*100 = 50% TIM1 Channel2 duty cycle = (TIM1_CCR2 / TIM1_ARR)*100 = 50% TIM1_CCRx = (DutyCycle * TIM1_ARR) / 100 要求PWM输出频率为50KHz。所以ARR=(72MHz/100000)-1=719 因为ARR加1的时 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2018-9-19 08:28:10 | 显示全部楼层
[mw_shl_code=c,true]/*
Prescaler = (TIM1CLK / TIM1 counter clock) - 1
TIM1_Priod = (SystemCoreClock / 50000) - 1
ARR = (TIM1 counter clock / TIM1 output clock) - 1
TIM1 Channel1 duty cycle = (TIM1_CCR1 / TIM1_ARR)*100 = 50%
TIM1 Channel2 duty cycle = (TIM1_CCR2 / TIM1_ARR)*100 = 50%
TIM1_CCRx = (DutyCycle * TIM1_ARR) / 100
要求PWM输出频率为50KHz。所以ARR=(72MHz/100000)-1=719
因为ARR加1的时间为(1/72MHz)s,则(1/72MHz)X=3us。
X=216即CCR1、 CCR2之间相隔216时,PWM的相位差是3us。
*/

void TIM1_PWM_DeadtimeInit(u16 arr, u16 psc, u16 ccr1, u16 ccr2, u16 deadtime)
{
    GPIO_InitTypeDef GPIO_InitSturcture;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    //TIM1 互补PWM CH1->PA8  CH2->PA9  CH1N->PB13  CH2N->PB14
    GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitSturcture);

    GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
    GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitSturcture);
    //定时器设置
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x00;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
    //通道1 捕获比较模式设置
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;                                 //翻转,当 TIMx_CCR1=TIMx_CNT时,翻转OC1REF的电平
    TIM_OCInitStructure.TIM_Pulse = ccr1;                                                        //100
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                //CCER的CC1P,输入/捕获输出极性
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //CER的CC1N,输入/捕获输出使能
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;        //OIS1位
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;  //CR2的OIS1N位,当MOE位0时,输出空闲状态位OIS1N.
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    //通道2 设置
    TIM_OCInitStructure.TIM_Pulse = ccr2;                                                        //316
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    //刹车和死区设置
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;         //OSSR:运行模式下“关闭状态”选择
    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;         //OSSI:空闲模式下“关闭状态”选择
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;                         //锁定设 置,级别为1
    TIM_BDTRInitStructure.TIM_DeadTime = deadtime;                                        //死区延时时间
    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;                        //禁止刹车输 入
    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;                 //刹车输入极性
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能
    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
       
        TIM_CtrlPWMOutputs(TIM1,ENABLE);
        TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
        TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
        TIM_ARRPreloadConfig(TIM1,ENABLE);
        TIM_Cmd(TIM1,ENABLE);
}


TIM1_PWM_DeadtimeInit(719,0,100,244,72);//50KHz[/mw_shl_code]
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-9-19 10:41:13 | 显示全部楼层
HXYDJ 发表于 2018-9-19 09:38
[mw_shl_code=c,true]/*
Prescaler = (TIM1CLK / TIM1 counter clock) - 1
TIM1_Priod = (SystemCoreCloc ...

你可以稍微解释下嘛
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2018-9-19 11:11:53 | 显示全部楼层
定时器1的通道1和通道2互补输出,改变arr的值可以改变占空比。
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2018-9-19 11:46:56 | 显示全部楼层
你把互补极性设置成低电平有效试试,互补两个通道也可以是不互补的,不知道你的原因是不是因为互补以后OCXN通道的输出极性相反造成的占空比变化范围不一样的问题,我之前是因为互补后,占空比变化和OCX输出的占空比正好相反,所以就导致LED不变化了
回复

使用道具 举报

8

主题

293

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1001
金钱
1001
注册时间
2018-8-16
在线时间
327 小时
 楼主| 发表于 2018-9-19 12:14:01 | 显示全部楼层
wangmingwei093 发表于 2018-9-19 11:46
你把互补极性设置成低电平有效试试,互补两个通道也可以是不互补的,不知道你的原因是不是因为互补以后OCXN ...

谢谢回复。后来找到问题了,是其他地方的代码的疏忽,我上面贴出来哪部分的代码时没有问题的。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 20:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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