文章
博客 网店

 STM8S定时器输入捕获功能测量波形


1.关于TI1FP1,TI1FP2,TI2FP1,TI2FP2这四个信号的解释
TIMx_CH1 进入的信号叫TI1
TI1去通道1的信号叫TI1FP1
TI1去通道2的信号叫TI1FP2
同样
TIMx_CH2 进入的信号叫TI2
TI2去通道1的信号叫TI2FP1
TI2去通道2的信号叫TI2FP2
也就是说STM8S的定时器输入捕获通道和输入引脚不是一一对应的,一个输入信号可以接入两个测量通道。列如中TIMx_CH1

进入的频率信号通道1或通道2都可以测量,相应的TIMx_CH2进入的信号通道1或通道2也都可以测量。

2.在芯片对应的数据手册中TIMx_CHx如果是在中括号中标注的,说明这个功能不是
IO引脚默认的复用功能,需要在选项字节里重新设置才能映射到此功能,调试输入捕获程序时很容易忽略这一点。

3.测量通道只能设置成上升沿检测或下降沿检测,所以要同时测量一个波形的高电平时间和低电平时间时,需要用到两个

通道对同一个输入进捕获测量。你如测量pwm信号的占空比。


以下为TIM1 的TIM1_CH4引脚测量红外遥控按键信号的示例,注意,定时器有复杂的输入检测触发功能但本示例没有用到
触发功能,定时器只是简单的向上计数,溢出时重新从0开始计数


#define CAP_COUNT 24      //一次接收捕获次数
uint16_t g_Record[CAP_COUNT];    //电平保持时间记录
uint8_t g_Index;      //当前捕获位置
uint8_t volatile g_RecvFlag;

//系统时钟为8M
void Timer1Open(void)
{
  //1us计时,CH4捕获中断
  CLK->PCKENR1 |= CLK_PCKENR1_TIM1;//TIM1定时器时钟允许
  
  TIM1->CNTRH = 0x00;//清零计数器高8位
  TIM1->CNTRL = 0x00;//清零计数器低8位
  
  TIM1->PSCRH = 0x00;//计数器时钟分频高8位
  TIM1->PSCRL = 0x08;//计数器时钟分频低8位8分频
  
  //通道3通道4连接到TIM1_CH4引脚 通道3上升沿捕获通道4下降沿捕获
  TIM1->CCER2&=0;//清零TIM1_CCER2 CC4E位,之后才可配置TIM1_CCMR1
  TIM1->CCMR3 =0x22;
  TIM1->CCMR4 = 0x21; //不分频,波波4周期 TI4(TIM1_CHR4)到通道4 (TI4FP4) (中文参考手册有误,请参考 

英文 参考手册 )
  TIM1->CCER2 = TIM1_CCER2_CC4P|TIM1_CCER2_CC3E|TIM1_CCER2_CC4E;//捕获使能,cc4 下降沿 cc3上升沿

  TIM1->IER = TIM1_IER_CC3IE|TIM1_IER_CC4IE;//使能捕获/比较4中断
  TIM1->EGR=TIM1_EGR_CC3G|TIM1_EGR_CC4G;//触发中断
  
  TIM1->CR1 |= TIM1_CR1_CEN;//使能定时/计数器  
}


//输入捕获中断
INTERRUPT void TIM1_CAPHandler(void)
{
  uint16_t t;
  
  if(TIM1->SR1 & TIM1_SR1_CC4IF)
  {
    //读痕迹冰清标志
    t=TIM1->CCR4H;
    t<<=8;
    t+=TIM1->CCR4L;
  }
  else if(TIM1->SR1 & TIM1_SR1_CC3IF)
  {
    t=TIM1->CCR3H;
    t<<=8;
    t+=TIM1->CCR3L;
  }
  else
  {
    TIM1->SR1=0;
    return ;
  }
  
  TIM1->SR1=0;//清标志位
  
  if(g_RecvFlag) return ;
  if(g_Index >= CAP_COUNT)
  {
    g_RecvFlag=1;
    return ;
  }
  

  g_Record[g_Index++]=t;
  
  if(g_Index >= CAP_COUNT)
  {
    g_RecvFlag=1;
    frm_set_event(EVENT_IR_ID);//程序框架触发接收完成一个按键操作
  }
}


//初始化红外检测
void ir_start_scan(void)
{
  //TIM1_CH4 PC4
  GPIOC->DDR&=~(1<<4);//输入模式
  GPIOC->CR1&=~(1<<4);//浮空输入
  //GPIOC->CR1|=(1<<5);上拉输入
  GPIOC->CR2&=~(1<<4);//中断关闭
  
  g_Index=0;
  g_RecvFlag=0;
  Timer1Open();
}

//接口函数,读取接收数据
uint8_t ir_read_code(void)
{
  uint8_t i,ir_code;
  uint16_t prev,next;
  
  if( g_RecvFlag == 0)
    return 0;
    
  //时间痕迹会记录在g_Record数组里,下面进分析 HS9148发送的波形得出按键值并返回 
  for(i=0;i<CAP_COUNT;i+=2)
  {
    prev=g_Record[i];
    next=g_Record[i+1];
    
    if(next>=prev)
      prev=next-prev;
    else
      prev=next+(0xffff-prev);
    
    ir_code<<=1;
    if(prev > 800)
      ir_code|=1;
  }

  return ir_code;
}

//接收一个按键码后调用此函数以重新接收新的按键码
void ir_recv_enable(void)
{  
  drv_enter_critical();//程序框架提供的关中断函数
  TIM1->SR1 =0;
  g_RecvFlag=0;    
  g_Index=0;
  drv_exit_critical();//程序框架提供的开中断函数  
}





芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved