CH579_TMR定时器边沿捕获

前言:
在CH579官方例程中,已经有了通过定时器翻转IO口、定时器产生PWM输出、定时器产生CAP捕捉(DMA通道)、定时器产生计数器的相关例程。本篇博客主要是通过定时器1产生CAP捕获功能并作讲解。

一、操作
使用CH579芯片进行定时器的CAP捕捉,首先需要注意的是引脚功能,PA10是作为低频振荡器的输入端。使用该引脚进行捕捉,需要释放该引脚原先的功能,所以第一步是启用芯片内部32K,同时程序中关闭外部低频晶振引脚功能。

PWR_UnitModCfg( DISABLE, UNIT_SYS_LSE );     // 注意此引脚是LSE晶振引脚,要保证关闭才能使用其他功能

CH579的定时器是26位,所以最大超时为3FFFFFF。在捕捉时我们可以自由设置超时时间。如下图,设置超时为FFFF,则在打印时我们将红框里的数据全部相加,然后将所得值除以主频,便得到了捕获的值((0x0000ffff×6 + 1a84) / 40M ,结果如下图可见)。如果,设置超时时间为默认值即3FFFFFF,则会打印为00061a7e,将得到的值除以40M,结果是一样的(0x00061a7e / 40M)。详细讲解见CH579的芯片手册。

 

二、程序

/*程序:(使用40M的时钟进行CAP捕捉。需注意开启PLL电源控制位)*/
UINT32 capbuf[200];
UINT16 caplen = 0;
void DebugInit(void) //配置串口1打印
{
    GPIOA_SetBits(GPIO_Pin_9);
  GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
  GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
  UART1_DefInit();
}
int main()
{    
  SetSysClock(CLK_SOURCE_PLL_40MHz);  //R8_HFCK_PWR_CTRL |= RB_CLK_PLL_PON;  //打开PLL电源控制位
  DebugInit(); //配置串口调试
#if 1       /* 定时器3,PWM输出 */   //此为被捕捉的方波,由定时器产生
  GPIOA_ResetBits( GPIO_Pin_2 );            // 配置PWM口 PA2
  GPIOA_ModeCfg( GPIO_Pin_2, GPIO_ModeOut_PP_5mA );
  TMR3_PWMInit( High_Level, PWM_Times_1 );
  TMR3_PWMCycleCfg( 400000 ); // 周期 10ms
  TMR3_Disable();
  TMR3_PWMActDataWidth( 200000 ); // 占空比设置 , 修改占空比必须暂时关闭定时器
  TMR3_Enable();
  while(1);
#endif  

#if 1
    PWR_UnitModCfg( DISABLE, UNIT_SYS_LSE );                  // 注意此引脚是LSE晶振引脚,要保证关闭才能使用其他功能
    GPIOA_ResetBits( GPIO_Pin_10 );                           // 配置PWM口 PA10
    GPIOA_ModeCfg( GPIO_Pin_10, GPIO_ModeIN_PU );
    TMR1_CapInit( FallEdge_To_FallEdge );                   //下降沿到下降沿  & 计数下降沿
    TMR1_CAPTimeoutCfg( 0xFFFF );                         // 设置捕捉超时时间,最大为3FFFFFF(定时器为26位)
    TMR1_ITCfg(ENABLE,RB_TMR_IE_DATA_ACT|RB_TMR_IE_CYC_END);       //配置中断使能寄存器
    NVIC_EnableIRQ( TMR1_IRQn );                        //开启定时器1中断
    mDelaymS(3);
    while(1)                                    //中断中产生的数据在这里打印出来
    {    
      if(caplen > 200)                              //一次打印200个,可根据需求增减
        {
            NVIC_DisableIRQ( TMR1_IRQn );                   //打印时关闭中断,防止继续捕获
            TMR1_ITCfg(DISABLE,RB_TMR_IE_DATA_ACT|RB_TMR_IE_CYC_END);  //打印时关闭中断,防止继续捕获
            for(caplen = 0; caplen < 200; caplen++)
            {
              printf( "capbuf = %08lx\n", capbuf[caplen]);        //打印CAP捕捉值
            }
      }
    }
#endif
}
 
void TMR1_IRQHandler( void )                    // TMR1 定时中断
{
  UINT16 i ;
    if( TMR1_GetITFlag(RB_TMR_IF_DATA_ACT) )        //进入普通捕捉(普通与超时:有且仅有二选一)
  {
      capbuf[caplen] = R32_TMR1_FIFO;            //采集的值放在FIFO寄存器中
    caplen++;                         //设置捕捉次数,本次为200(可增减)
    TMR1_ClearITFlag( RB_TMR_IF_DATA_ACT );        // 清除中断标志  
  }
  if( TMR1_GetITFlag( RB_TMR_IF_CYC_END ) )       //进入超时捕捉(普通与超时:有且仅有二选一)
  {
    capbuf[caplen] = R32_TMR1_CNT_END;          //计数终值寄存器,即设置捕捉超时的时间
    caplen++;
    TMR1_ClearITFlag( RB_TMR_IF_CYC_END );         // 清除中断标志  
  }
}

 

posted @ 2022-03-21 15:43  SweetTea_lllpc  阅读(550)  评论(0编辑  收藏  举报