求助各路大神:使用STM8S103F3的TIM2_CH1的输入捕获功能不常

2019-12-14 13:08发布

STM8S103F3P 无法使用PD4上的TIM2_CH1进行输入捕获,TIM2的CH3用于PWM输出,驱动LED,该功能正常。
OptionByte配置如图:
option.jpg (35.54 KB, 下载次数: 0) 下载附件 2014-8-10 18:08 上传
代码如下:
  1. #pragma vector = TIM2_OVR_UIF_vector
  2. __interrupt void TIM2_UIF_IRQHandler(void){
  3.   u16LedCnt++;
  4.   if(u16LedCnt == u16LedPeriod){   
  5.     u16Led = (uint16_t)(u16Led + s8LedStep);
  6.     if(u16Led > TIM2_PERIOD && s8LedStep < 0){
  7.       u16Led = 0;
  8.     }
  9.     TIM2_CCR3H = (uint8_t)((u16Led & 0xFF00) >> 8);
  10.     TIM2_CCR3L = (uint8_t)(u16Led & 0x00FF);
  11.     u16LedCnt = 0;
  12.   }
  13.   
  14.   if(u16Led >= TIM2_PERIOD){
  15.     s8LedStep = -80;
  16.   }else if(u16Led < 1){
  17.     s8LedStep = 80;
  18.   }
  19.   
  20.   if(TIM2_CCER1_bit.CC1P){
  21.     //计数器溢出,且没有捕获到下降沿,重新开始捕获上升沿
  22.     TIM2_CCER1_bit.CC1P = 0;
  23.   }
  24.   TIM2_SR1_bit.UIF = 0;
  25. }

  26. #pragma vector = TIM2_CAPCOM_CC1IF_vector
  27. __interrupt void TIM2_CC_IRQHandler(void){  
  28.   if(TIM2_SR1_bit.CC1IF){   
  29.     if(TIM2_CCER1_bit.CC1P){
  30.       //当前捕获到下降沿,完成一次PWM宽度获取,开始下次捕获上升沿
  31.       TIM2_CCER1_bit.CC1P = 0;
  32.       u16PwmWidth = (uint16_t)(TIM2_CCR1H << 8);
  33.       u16PwmWidth |= TIM2_CCR1L;
  34.     }else{
  35.       //当前上升沿, 开始捕获下降沿
  36.       TIM2_CCR1H = 0;
  37.       TIM2_CCR1L = 0;
  38.       TIM2_CCER1_bit.CC1P = 1;
  39.     }   
  40.     TIM2_SR1_bit.CC1IF = 0;
  41.   }  
  42. }

  43. void Tim2Config(void){
  44.   //PD4为PWM输入,配置为浮空输入模式
  45.   PD_DDR_bit.DDR4 = 0;
  46.   PD_CR1_bit.C14 = 0;
  47.   PD_CR2_bit.C24 = 0;
  48.   //PA3为LED输出 OpenDrain
  49.   PA_DDR_bit.DDR3 = 1;
  50.   PA_CR1_bit.C13 = 0;
  51.   PA_CR2_bit.C23 = 1;
  52.   PA_ODR_bit.ODR3 = 1;
  53.   /* CH1用于输入捕获, CH3用于LED呼吸灯 */
  54.   TIM2_PSCR = 0x01;
  55.   
  56.   TIM2_CR1_bit.ARPE = 1;
  57.   TIM2_CR1_bit.URS = 0;
  58.   TIM2_CR1_bit.UDIS = 0;
  59.   TIM2_CR1_bit.OPM = 0;
  60.    
  61.   
  62.   TIM2_CCMR1 = 0xC1;            //输入模式
  63.   
  64.   TIM2_CCMR3_bit.OC3M = 0x06;
  65.   TIM2_CCMR3_bit.CC3S = 0x00;   //输出模式
  66.   TIM2_CCMR3_bit.OC3PE = 0;
  67.   
  68.   TIM2_CCER1_bit.CC1E = 1;
  69.   TIM2_CCER1_bit.CC1P = 0;      //上升沿捕获
  70.   
  71.   TIM2_CCER2_bit.CC3E = 1;
  72.   TIM2_CCER2_bit.CC3P = 1;
  73.   
  74.   TIM2_ARRH = (uint8_t)((TIM2_PERIOD & 0xFF00) >> 8);
  75.   TIM2_ARRL = (uint8_t)(TIM2_PERIOD & 0x00FF);
  76.   
  77.   u16Led = 0x0001;
  78.   s8LedStep = 80;
  79.   
  80.   TIM2_CCR1H = 0;
  81.   TIM2_CCR1L = 0;
  82.   
  83.   TIM2_CCR3H = (uint8_t)((u16Led & 0xFF00) >> 8);
  84.   TIM2_CCR3L = (uint8_t)(u16Led & 0x00FF);
  85.   
  86.    
  87.   TIM2_IER_bit.CC1IE = 1;
  88.   TIM2_IER_bit.UIE = 1;
  89.   
  90.   ITC_SPR4_bit.VECT15SPR = 3;
  91.   ITC_SPR5_bit.VECT16SPR = 3;
  92.   
  93.   
  94.   TIM2_CR1_bit.CEN = 1;
  95.   TIM2_SR1_bit.CC1IF = 0;
  96.   TIM2_EGR_bit.CC1G = 1;
  97. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
Malo
1楼-- · 2019-12-15 10:28
qycc566 发表于 2014-8-11 17:02
检查过了,寄存器正常,单步时在程序启初次运行时会进入CC1中断一次,然后就再也不会进入中断了 ...

在开启中断之后立即清除一次中断标志位,这样就不会有误中断进入。ST公司的就这样。

一周热门 更多>