打印
[STM32F0]

[已解决]TIM1输出PWM极性总是不对

[复制链接]
1927|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feiyinglala|  楼主 | 2016-2-29 22:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PWM, TI, ST, tmp, LED
本帖最后由 feiyinglala 于 2016-3-1 20:31 编辑

RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);                //TIM1 RCC用错了函数
我用STM32F051来实现TIM1输出四路PWM波,预想的效果是,在TIM_CNT <CCRx时,输出高电平(TIM1配置见代码段1)
然后CCRx是由TIM3来捕获的遥控器通道1传来的PWM波的宽度,在TIM3的捕获中断中来直接操控寄存器CCRx来更改TIM1输出的PWM高电平宽度(见代码段2)
目前遇到的困难是,在TIM1配置中,无论配置为PWM1还是PWM2,极性配置为高还是低,输出的PWM波形都是与我预想的情况相反的(TIM_CNT <CCRx时输出低电平)
请各位高手大侠指点,我问题出在哪里? TIM3的捕获脉冲宽度功能是正常的,我在示波器上验证过

说明:芯片是STM32F051R8  系统:win7 64位  开发环境:uVersion V5.11
          下载器:ST-LINK 山寨版(USB口连到电脑,然后通过SWD连接电路板)



void TIM1_INT_Config(void)
{
        <font color="red">RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);                //TIM1 RCC 使能</font>
//        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);        //GPIOA的RCC已在点亮LED灯时使能
        TIM_DeInit(TIM1);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        //GPIO_ResetBits(GPIOA,GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_2);                //配置端口复用
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_2);                //GPIO¹Ü½Å¸´ÓÃÉèÖÃ
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_2);                //GPIO¹Ü½Å¸´ÓÃÉèÖÃ
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_2);                //GPIO¹Ü½Å¸´ÓÃÉèÖÃ
        
        
        //配置TIM1每20ms溢出一次,以控制无刷电调
        TIM_TimeBaseStructure.TIM_Period = 63999;                                //
        TIM_TimeBaseStructure.TIM_Prescaler = 14;                                //                        
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);               
}

void TIM1_OUT_Config(void)
{
        CCR1_Val = 0;
        CCR2_Val = 0;
        CCR3_Val = 0;
        CCR4_Val = 0;

        //输出PWM模式
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                                 //TIM1输出PWM1
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //TIM1ʹÄÜÊä³ö±È½Ï¹¦ÄÜ״̬
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                 //TIM1输出比较极性高
        TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
        TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;                //TIM1£ºµ±MOE=1 ÉèÖÃTIM1Êä³ö±È½Ï¿ÕÏÐ״̬
        TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
        
        TIM_OCInitStructure.TIM_Pulse = CCR1_Val;                                                
        TIM_OC1Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜƵµÀ1ÅäÖÃ
        TIM_OCInitStructure.TIM_Pulse = CCR2_Val;                                                
        TIM_OC2Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜƵµÀ1ÅäÖà       
        TIM_OCInitStructure.TIM_Pulse = CCR3_Val;                                                
        TIM_OC3Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜƵµÀ1ÅäÖÃ
        TIM_OCInitStructure.TIM_Pulse = CCR4_Val;                                                
        TIM_OC4Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜƵµÀ1ÅäÖà       
        TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);

        TIM_Cmd(TIM1, ENABLE);                                                                                        //Timer3ʹÄÜ
        TIM_CtrlPWMOutputs(TIM1, ENABLE);                                                                //TIM1Ö÷Êä³öʹÄÜ
}
<p>void TIM3_IRQHandler(void)
{//主要功能是捕获一个周期为20ms的PWM的脉冲时间,测得时间后把相应数值赋予TIM1->CCRx
        static uint16_t this_time_CH1 = 0;                //当前进入时刻计数器值
        static uint16_t last_time_CH1 = 0;                //上次中断进入时刻计数器值
        static uint8_t capture_number_CH1 = 0;        //捕获过程中,方向的标志位
        uint16_t tmp16_CH1;                                                //测得的脉冲宽度对应的计数器值
        static uint16_t this_time_CH2 = 0;                //µ±Ç°ÖжϽøÈëʱ¿Ì¶¨Ê±Æ÷µÄ¼ÆÊýÖµ
        static uint16_t last_time_CH2 = 0;                //ÉÏ´ÎÖжϽøÈëʱ¿ÌµÄ¶¨Ê±Æ÷¼ÆÊýÖµ
        static uint8_t capture_number_CH2 = 0;        //²¶»ñ¹ý³Ì±ê־λ
        uint16_t tmp16_CH2;                                                //ʱ¼ä²îÖµ

        if(TIM_GetITStatus(TIM3, TIM_IT_CC1) == SET)
        {
                TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);        //清除中断标志位
                if(capture_number_CH1 == 0)
                {
                        capture_number_CH1 = 1;
                        last_time_CH1 = TIM_GetCapture1(TIM3);        //保存计数值
                        TIM3->CCER |= (1 << 1);                                 //更改为捕获下降沿
                        LED_Open(0);
                }
                else if(capture_number_CH1 == 1)
                {
                        capture_number_CH1 = 0;
                        this_time_CH1 = TIM_GetCapture1(TIM3);        //»ñÈ¡¼ÆÊýÆ÷µÄÖµ
                        if(this_time_CH1 > last_time_CH1)                //若未溢出,则直接计算计数器差值
                        {
                                tmp16_CH1 = (this_time_CH1 - last_time_CH1);//¼ÆËãʱ¼ä¼ä¸ô
                        }
                        else
                        {
                                tmp16_CH1 = ((0xFFFF - last_time_CH1) + this_time_CH1);
                        }
                        TIM3->CCER &= ~(1 << 1);                                 //更改为捕获上升沿
                        //±¸ÓôúÂë
                        tmp16_CH1 = (tmp16_CH1 * 3) / 2;                //TIM3配置后为30ms溢出一次,因为TIM3的通道输入的信号为20ms的PWM,故用30ms的TIM来捕获,而TIM1为20ms溢出
                        TIM1->CCR1 = tmp16_CH1;
                        TIM1->CCR2 = tmp16_CH1;
                        TIM1->CCR3 = tmp16_CH1;
                        TIM1->CCR4 = tmp16_CH1;
                        LED_Close(0);                        
                }        
        }//if(TIM_GetITStatus(TIM4, TIM_IT_CC1) == SET)
}</p>
//主函数
int main(void)
{
        SystemInit();
        LED_Init();
        Systick_Init();

        LED_Open(1);
        Delay_ms(1000);
        LED_Close(1);
        Delay_ms(1000);
        
        TIM3_INT_Config();
        TIM1_INT_Config();
        TIM3_IN_Config();
        TIM1_OUT_Config();
        while(1)
        {
                LED_Open(0);
                Delay_ms(1000);
                LED_Close(0);
                Delay_ms(1000);/**/
        }        
}




沙发
feiyinglala|  楼主 | 2016-3-1 14:32 | 只看该作者
自己顶一下

使用特权

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

本版积分规则

21

主题

224

帖子

1

粉丝