关于任意I/O输出占空比可调pwm问题,进来看看

2019-08-17 08:09发布

由于硬件原因,现在需要任意I/O输出多路占空比可调pwm,我尝试利用定时器的比较时间模式(TIM_OCMode_Timing),然后在中断里面更新占空比和频率。可能是我思路不对,只能改变频率,占空比一直是50%,也就是改变不了频率。另外利用翻转模式(TIM_OCMode_Toggle)是不是只能对应TIMx固定的输出引脚?程序如下 有空闲的朋友帮忙看下,或者给点任意I/O输出占空比可调pwm的思路
void TIM2_Int_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
         TIM_OCInitTypeDef TIM_OCInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //ê±Öóê1Äü

        TIM_TimeBaseStructure.TIM_Period = 65535; //éèÖÃÔúÏÂò»¸ö¸üDÂê¼t×°èë»î¶ˉμÄ×Ô¶ˉÖØ×°ÔؼÄ′æÆ÷ÖüÆúμÄÖμ         ¼Æêyμ½5000Îa500ms
        TIM_TimeBaseStructure.TIM_Prescaler =0; //éèÖÃóÃà′×÷ÎaTIMxê±ÖóÆμÂê3yêyμÄÔ¤·ÖÆμÖμ  10KhzμļÆêyÆμÂê  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //éèÖÃê±Öó·Ö¸î:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIMÏòéϼÆêyÄ£ê½
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //¸ù¾YTIM_TimeBaseInitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉTIMxμÄê±¼ä»ùêyμ¥λ

        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;//éèÖñè½Ïê±¼äÄ£ê½
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//êä3öê1Äü
        TIM_OCInitStructure.TIM_Pulse = 3600;//éèÖñè½ÏÖμ
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //êä3ö¼«DÔ
        TIM_OC1Init(TIM2, &TIM_OCInitStructure);//3õê¼»ˉTIM2μÄêä3öí¨μà1
        TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);//2»×Ô¶ˉÖØ×°¼ÆêyÖμ

        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//êä3öê1Äü
        TIM_OCInitStructure.TIM_Pulse = 3600;//éèÖñè½ÏÖμ
        TIM_OC2Init(TIM2, &TIM_OCInitStructure);//3õê¼»ˉTIM2μÄêä3öí¨μà2
        TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);//2»×Ô¶ˉÖØ×°¼ÆêyÖμ
       
        TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2  , ENABLE);//Çå3yÖD¶Ï±êÖ¾
        TIM_Cmd(TIM2, ENABLE);//′ò¿a¶¨ê±Æ÷
       
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2ÖD¶Ï
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //ÏèÕ¼óÅÏ輶0¼¶
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //′óóÅÏ輶3¼¶
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQí¨μà±»ê1Äü
        NVIC_Init(&NVIC_InitStructure);  //¸ù¾YNVIC_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèNVIC¼Ä′æÆ÷

        TIM_Cmd(TIM2, ENABLE);  //ê1ÄüTIMxíaéè
                                                         
}


void OCTiming_GPIO_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
}


void TIM2_IRQHandler(void)
{
        static u16 capture = 0;
        if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//êä3ö±è½Ïí¨μà1
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

                GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_6)));//·-×aμçƽÖμ
                capture2 = TIM_GetCapture1(TIM2);//»ñ衱è½ÏÖμ
                TIM_SetCompare1(TIM2, capture2 + 3600);//ÖØDÂéèÖñè½ÏÖμ
        }
        if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)//êä3ö±è½Ïí¨μà1
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

                GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_7)));//·-×aμçƽÖμ
                capture = TIM_GetCapture2(TIM2);//»ñ衱è½ÏÖμ
                TIM_SetCompare2(TIM2, capture + 3600);//ÖØDÂéèÖñè½ÏÖμ
        }
       
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
wdodo0929
1楼-- · 2019-08-17 11:56
时间比较没用过。翻转模式不知道你表达的意思,我现在用的是应该是TIMx下所有的翻转。另外想要给点任意I/O输出占空比可调pwm的思路,定时器的引脚是固定的,想要输出可调占空比的PWM,建议直接给寄存器CCR赋值。强烈推荐原子哥的USMART组件
1063378440
2楼-- · 2019-08-17 16:55
原子哥求救啊
一个爱做梦的人
3楼-- · 2019-08-17 20:31
 精彩回答 2  元偷偷看……
miracle629
4楼-- · 2019-08-18 00:14
使用TIMx的PWM模式,专门用来输出PWM波,其实就是设置好了输出捕获模式给你用,频率用ARR寄存器控制(周期值,就是TIM_Period的值),占空比等于CCR寄存器(比较值,就是TIM_Pluse的值)与ARR寄存器值的比,还有I/O口并不是固定的,只要修改PIN口就可以。你的中断服务程序里我不太能看懂是怎么改比较值的。
1063378440
5楼-- · 2019-08-18 00:28
wdodo0929 发表于 2017-6-12 20:14
时间比较没用过。翻转模式不知道你表达的意思,我现在用的是应该是TIMx下所有的翻转。另外想要给点任意I/O ...

多谢指点,,我去实验在思考一下
1063378440
6楼-- · 2019-08-18 01:31
一个爱做梦的人 发表于 2017-6-12 21:15
以前做过输出16路pwm控制舵机的,直接开一个定时器,定时0.1ms中断,然后中断里面计数,计到200次重新计数 ...

恩,,这个思路跟51利用定时器模拟pwm差不多,但是频率没办法做的很高

一周热门 更多>