STM32用OCToggle模式产生单脉冲

平台:KEIL5+stm32f103。

功能:采用TIM3的1,2通道的比较翻转模式产生宽度可调的单脉冲(本例的脉冲宽度200us/100us),脉冲之间间隔1s。

目前网上流传较多的方案一般2种:第一种:外部IO做触发源,定时器接收后产生脉宽;第二种:用定时器的主从或门控模式,用一个定时器驱动另外一个定时器。这两种方案要么需要外部IO,要么需要2个通用或高级的定时器,占用资源相对较多。本方案使用一个高级活通用定时器+系统滴答。系统滴答做这一件事同时还可以执行其他计时任务,总的来说,占用资源相对较少。

 

#define TIMER3_OCTOGGLE_FREQUENCY (uint32_t)1000000	//MHz,OCToggle模式下计时时钟

//翻转频率 = TIMER3_OCTOGGLE_FREQUENCY/Timer3_PWM_CCR1_Val
uint16_t Timer3_PWM_CCR1_Val = 100;//翻转频率 = 方波频率*2
uint16_t Timer3_PWM_CCR2_Val = 50;

void TIMER3_OCToggleMode_Config(void)	
{
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
       
	uint16_t Timer3_PWM__PrescalerValue = 0;

	/* PCLK1 = HCLK/4 */
	RCC_PCLK1Config(RCC_HCLK_Div4);

	/* TIM3 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

	/* GPIOA clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

	/* GPIOA Configuration:TIM3 Channel1, 2 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Enable the TIM3 global Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

	NVIC_Init(&NVIC_InitStructure);

	Timer3_PWM__PrescalerValue = (uint16_t) (SystemCoreClock / TIMER3_OCTOGGLE_FREQUENCY) - 1;

	/* Time base configuration */
	TIM_TimeBaseStructure.TIM_Period = 65535;
	TIM_TimeBaseStructure.TIM_Prescaler = Timer3_PWM__PrescalerValue;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

	/* Output Compare Toggle Mode configuration: Channel1 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = Timer3_PWM_CCR1_Val;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

	/* Output Compare Toggle Mode configuration: Channel2 */
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = Timer3_PWM_CCR2_Val;

	TIM_OC2Init(TIM3, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);


	/* TIM enable counter */
	TIM_Cmd(TIM3, ENABLE);

	/* TIM IT enable */
	TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
	
}
uint8_t ch0cnt = 0;//通道1翻转的次数
uint8_t ch1cnt = 0;//通道2翻转的次数

u32 G_SystemTickTime;//滴答系统时钟变量
u32 G_SecondTimeCnt;//秒计时


void TIM3_IRQHandler(void)
{
#if 1
  /* TIM3_CH1 toggling with frequency =  Hz */
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
	capture = TIM_GetCapture1(TIM3);
	TIM_SetCompare1(TIM3, capture + Timer3_CCR1_Val);

	ch0cnt++;
		
	if (ch0cnt > 0)//set  pulse  number
	{
	    TIM_CCxCmd(TIM3,TIM_Channel_1,TIM_CCx_Disable);
            TTIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE);
	}

  }

  /* TIM3_CH2 toggling with frequency =  Hz */
  if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    capture = TIM_GetCapture2(TIM3);
    TIM_SetCompare2(TIM3, capture + Timer3_CCR2_Val);

	ch1cnt++;
	if (ch1cnt > 0)//set  pulse  number
	{
	    TIM_CCxCmd(TIM3,TIM_Channel_2,TIM_CCx_Disable);
            TIM_ITConfig(TIM3, TIM_IT_CC2, DISABLE);
	}
  }

#endif  
}

 

 

 

void SysTick_Handler(void)
{
    uint16_t tmp;//记录当前计数值
    G_SystemTickTime++;

    if (G_SystemTickTime == 1000)//每1s执行一次
    {
	G_SecondTimeCnt++;

	tmp = TIM_GetCounter(TIM3);//必须读此值,否则脉冲宽度不是固定值
	TIM_SetCompare1(TIM3, tmp + Timer3_CCR1_Val);//调整CCR1_Val可以改变脉宽
	TIM_SetCompare2(TIM3, tmp + Timer3_CCR2_Val);
        //重新打开该通道
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC2 );
	TIM_CCxCmd(TIM3,TIM_Channel_1,TIM_CCx_Enable);
        TIM_CCxCmd(TIM3,TIM_Channel_2,TIM_CCx_Enable);
        TTIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
        TTIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

        ch0cnt = 0;
        ch1cnt = 0;

        G_SystemTickTime = 0;
    }
}

keil仿真结果:绿色的是通道1,红色的通道2。

 

STM32用OCToggle模式产生单脉冲_第1张图片

你可能感兴趣的:(嵌入式)