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

[复制链接]
2190|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连接电路板)



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

  25. void TIM1_OUT_Config(void)
  26. {
  27.         CCR1_Val = 0;
  28.         CCR2_Val = 0;
  29.         CCR3_Val = 0;
  30.         CCR4_Val = 0;

  31.         //输出PWM模式
  32.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                                 //TIM1输出PWM1
  33.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //TIM1ʹÄÜÊä³ö±È½Ï¹¦ÄÜ״̬
  34.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  35.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                 //TIM1输出比较极性高
  36.         TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  37.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;                //TIM1£ºµ±MOE=1 ÉèÖÃTIM1Êä³ö±È½Ï¿ÕÏÐ״̬
  38.         TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
  39.         
  40.         TIM_OCInitStructure.TIM_Pulse = CCR1_Val;                                                
  41.         TIM_OC1Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜÆµµÀ1ÅäÖÃ
  42.         TIM_OCInitStructure.TIM_Pulse = CCR2_Val;                                                
  43.         TIM_OC2Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜÆµµÀ1ÅäÖà       
  44.         TIM_OCInitStructure.TIM_Pulse = CCR3_Val;                                                
  45.         TIM_OC3Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜÆµµÀ1ÅäÖÃ
  46.         TIM_OCInitStructure.TIM_Pulse = CCR4_Val;                                                
  47.         TIM_OC4Init(TIM1, &TIM_OCInitStructure);                                                //ʹÄÜÆµµÀ1ÅäÖà       
  48.         TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);

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

  11.         if(TIM_GetITStatus(TIM3, TIM_IT_CC1) == SET)
  12.         {
  13.                 TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);        //清除中断标志位
  14.                 if(capture_number_CH1 == 0)
  15.                 {
  16.                         capture_number_CH1 = 1;
  17.                         last_time_CH1 = TIM_GetCapture1(TIM3);        //保存计数值
  18.                         TIM3->CCER |= (1 << 1);                                 //更改为捕获下降沿
  19.                         LED_Open(0);
  20.                 }
  21.                 else if(capture_number_CH1 == 1)
  22.                 {
  23.                         capture_number_CH1 = 0;
  24.                         this_time_CH1 = TIM_GetCapture1(TIM3);        //»ñÈ¡¼ÆÊýÆ÷µÄÖµ
  25.                         if(this_time_CH1 > last_time_CH1)                //若未溢出,则直接计算计数器差值
  26.                         {
  27.                                 tmp16_CH1 = (this_time_CH1 - last_time_CH1);//¼ÆËãʱ¼ä¼ä¸ô
  28.                         }
  29.                         else
  30.                         {
  31.                                 tmp16_CH1 = ((0xFFFF - last_time_CH1) + this_time_CH1);
  32.                         }
  33.                         TIM3->CCER &= ~(1 << 1);                                 //更改为捕获上升沿
  34.                         //±¸ÓôúÂë
  35.                         tmp16_CH1 = (tmp16_CH1 * 3) / 2;                //TIM3配置后为30ms溢出一次,因为TIM3的通道输入的信号为20ms的PWM,故用30ms的TIM来捕获,而TIM1为20ms溢出
  36.                         TIM1->CCR1 = tmp16_CH1;
  37.                         TIM1->CCR2 = tmp16_CH1;
  38.                         TIM1->CCR3 = tmp16_CH1;
  39.                         TIM1->CCR4 = tmp16_CH1;
  40.                         LED_Close(0);                        
  41.                 }        
  42.         }//if(TIM_GetITStatus(TIM4, TIM_IT_CC1) == SET)
  43. }</p>
  1. //主函数
  2. int main(void)
  3. {
  4.         SystemInit();
  5.         LED_Init();
  6.         Systick_Init();

  7.         LED_Open(1);
  8.         Delay_ms(1000);
  9.         LED_Close(1);
  10.         Delay_ms(1000);
  11.         
  12.         TIM3_INT_Config();
  13.         TIM1_INT_Config();
  14.         TIM3_IN_Config();
  15.         TIM1_OUT_Config();
  16.         while(1)
  17.         {
  18.                 LED_Open(0);
  19.                 Delay_ms(1000);
  20.                 LED_Close(0);
  21.                 Delay_ms(1000);/**/
  22.         }        
  23. }




 楼主| feiyinglala 发表于 2016-3-1 14:32 | 显示全部楼层
自己顶一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

224

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部