原创 STM32 工频周期采集,及相位同步输出

2010-3-16 16:04 2782 6 6 分类: MCU/ 嵌入式

最近在做STM32工频相位及采集,主要用到TIM8_CH1及TIM4_CC_IRQ.将工作中使用的主要寄存器配置及主要思路记录下来,希望对即将从来该方面工作的研友们有所帮助,
也希望可以指引新人入门.同时希望前辈能给予指正,代码中存在问题及可改进之处.
由于工作时间有限,所记录之处难免有漏,像系统时钟及IO口配置等,默认研友们已作相应且正确配置.


思路
TIM8 的CH1通道1作为输入捕获.同时产生中断.
TIM4 的4路输出中的TIM4_CH1通道一作为输出比较,同时产生中断.
方法
1) 设置计数器向下计数模式,自动重载寄存器设置为:0xFFFF,这样计数器会循环计数
2) 设置工频周期计数(由TIM8_CH1通道1us采一次)为,当前TIM4_CH1预加载值(即将于定时器TIM4_CC1_CNT比较的值).
3) TIM4定时器通道设置为输出比较模式,并设置比较匹配时,产生相应的中断.
4) 在中断中将PF0(=1) 高压放电.


高级定时器TIM8_CH1,用于输入捕获.这在前面一遍工作笔记中已作描述,有不懂的可以留言探讨.



settimer.c如下:
extern volatile float Value;


void Tim4_SetupTIMOC(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;


  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 0xffff; //自动重载寄存器   ARR
  TIM_TimeBaseStructure.TIM_Prescaler = 71;    //分频系统720  PSCR TIM4系统时钟为:72MHZ  72MHZ/(71+1)=1MHZ 即:1us
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;


  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);


  /* Output Compare Timing Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse =(u32) (Value);//设置预加载值 CCR1
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;


  TIM_OC1Init(TIM4, &TIM_OCInitStructure);


  TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
 
  TIM_ClearFlag(TIM4,TIM_FLAG_Update);//清中断,以免一启用中断后立即产生中断
  Tim4_SetupNVIC();// 中断使能
}


void Tim4_EnableTIMOC(void)
{
    // TIM IT enable  使能中断源
  TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
  // TIM4->DIER |=0x0002;
  /* TIM4 总开关,开启enable counter */
  TIM_Cmd(TIM4, ENABLE);
   // TIM4->CR1 |=0x0081;
  TIM_ARRPreloadConfig(TIM4, ENABLE);
  TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Disable);//预加载值立即生效   这条语句很重要
}
void Tim4_DisableTIMOC(void)
{
    // TIM IT enable  禁能中断源
  TIM_ITConfig(TIM4, TIM_IT_CC1, DISABLE);


  /* TIM2 总开关,开启enable counter */
  TIM_Cmd(TIM4, DISABLE);
}


stm32f10x_it.c如下:


extern volatile bool Tim8_NVIC2_f;
extern volatile bool Phasic_F;



void TIM4_IRQHandler(void)//10us定时中断
{
  if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
  {
   
     GPIO_WriteBit(GPIOF,GPIO_Pin_0,(BitAction)(0)); //  //打开PF0开关 主开关闭合
    //  u16 count="TIM"_GetCounter(TIM4); 调试用
     Tim4_DisableTIMOC();
      TIM4->CNT = 0;
      TIM4->ARR = 65535;
     TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
     Phasic_F=TRUE;
  }
}


void TIM8_CC_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET)
  {
       TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); 
      if(Tim8_NVIC2_f)    //相位同步触发用
       {
         Tim8_NVIC2_f=FALSE;
         Tim4_SetupTIMOC();
         Tim4_EnableTIMOC();
        
         // TIM IT disable  禁能中断源
         TIM_ITConfig(TIM8,TIM8_CC_IRQChannel, DISABLE);
         /* TIM8 总开关,关闭Disable counter */
         TIM_Cmd(TIM8, DISABLE);
       }
       else             //工频周期采集用
       { 
           Tim4_DisableTIMBASE();
            if(HW_flag==0)
            {
               IC1[HW_NUM]=TIM8->CCR1;
               if ( IC1[HW_NUM] != 0)
               {
                    IC1[HW_NUM]=TIM8->CCR1;
                    TIM8->CNT = 0;
                    TIM8->ARR = 65535;
                }
              }
 
             HW_NUM++;
             if(HW_NUM>=14)   //共采集14个数据作平均数
             {
               HW_NUM=0;
        
               HW_flag=1;
              }
      }
 
  }



}


main.c 如下:
#define Phasic 0x01 //定义工频投入 键码:0x01


main()
{
   GET_period();
     if(Phasic_F)
     {    
          Phasic_F=FALSE;
         //DoComplete();做相位同步完成的工作
         
     }


     if(GetKey() == Phasic)
     {
         Tim8_NVIC2_f=TRUE;
         //other things...
     }
}


void GET_period(void)
{
  unsigned int temp;
  unsigned int sum="0";
  if(HW_flag==1)
    {
      for(i=0;i<14;i++)
      {       
        temp="IC1";
        sum +=temp;    
      }
  
   
    ICValue="sum/14";
  //  ICValue="20000"; 调试用
    if(IntnumTestphasic == 0)//将用户设定0度归为360度处理,提高相位同步精度.
    {
        IntnumTestphasic="360";
    }
    Value=( (ICValue)/360.0)*( IntnumTestphasic); //工频相位0~360度平均到1us 的预加载值
    HW_flag=0;
  }
}

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条