本帖最后由 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);/**/
- }
- }
|