STM8S103F外部触发,捕获/比较寄存器更新了,但无法中断

2020-01-10 19:40发布

本帖最后由 zhcj66 于 2018-6-8 14:32 编辑

调试了2天了如题"STM8S103F外部触发捕获/比较寄存器更新了,但无法中断"不知道咋回事,是程序的问题还是芯片的问题

  1. //程序设置如下
  2. void TIM1_Init(void)
  3. {
  4.   
  5.   GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_FL_IT);
  6.   
  7.   TIM1->CNTRH = 0x00;//清零计数器高8位  
  8.   TIM1->CNTRL = 0x00;//清零计数器低8位
  9.    
  10.   TIM1->ARRH = 0xFF; //自动重装载的值 255
  11.   TIM1->ARRL = 0xFF; //自动重装载的值 255
  12.   TIM1->PSCRH = 0x00;
  13.   TIM1->PSCRL = 0xA0-1; //160分频  正好是10us
  14.    
  15.   TIM1->CCER2 &= ~0x01;//清零CCxE,之后才可配置CCMR
  16.   TIM1->CCMR3 = 0x01;//IC3映射在TI3FP3;无分频;无滤波
  17.   TIM1->CCER2 &= ~0x02;//上升沿或高电平有效
  18.   TIM1->IER |= 0x08; //使能CC3IE中断
  19.   TIM1->CCER2 |= 0x01;//输入捕获使能
  20.   TIM1->CR1 = 0x01; //启动定时器
  21. }

  22. INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
  23. {//程序无法进入这个中断
  24.    TIM1_ClearITPendingBit(TIM1_IT_CC3);
  25. }
复制代码

中断标志寄存器也置位了,可是就是无法进入中断寄存器;可以确定的是全局中断已经打开,因为定时器2正常工作着.
TIM1_IER值为0x08应该标志位置位后就可以进入中断的,可是就是进不去,在触发的时候TIM1_CCR3也有数据更新
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
zhcj66
1楼-- · 2020-01-11 01:37
本帖最后由 zhcj66 于 2018-6-11 10:01 编辑

问题已经解决

问题出在IO设置上 应该设置成GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT); 上拉无中断,结果设置成了中断  因此无法进入定时的的IC中断

  1. //本程序可以通过检测脉冲的上升沿和下降沿,来判断脉冲的占空比
  2. #include <stdio.h>
  3. #include "stm8s.h"
  4. #include "sys.h"

  5. #define TLI_VECTOR                                0
  6. #define AWU_VECTOR                                1
  7. #define CLK_VECTOR                                2
  8. #define EXTI_PA_VECTOR                        3
  9. #define EXTI_PB_VECTOR                        4
  10. #define EXTI_PC_VECTOR                        5
  11. #define EXTI_PD_VECTOR                        6
  12. #define EXTI_PE_VECTOR                        7
  13. #define CAN_RX_VECTOR                        8
  14. #define CAN_TX_VECTOR                        9
  15. #define SPI_VECTOR                                10
  16. #define TIM1_UPD_OVF_VECTOR                11
  17. #define TIM1_CAP_COM_VECTOR                12
  18. #define TIM2_UPD_OVF_VECTOR                13
  19. #define TIM2_CAP_COM_VECTOR                14
  20. #define TIM3_UPD_OVF_VECTOR                15
  21. #define TIM3_CAP_COM_VECTOR                16
  22. #define UART1_TX_VECTOR                        17
  23. #define UART1_RX_VECTOR                        18
  24. #define I2C_VECTOR                                19
  25. #define UART23_TX_VECTOR                20
  26. #define UART23_RX_VECTOR                21
  27. #define ADC_VECTOR                                22
  28. #define TIM4_UPD_OVF_VECTOR                23
  29. #define FLASH_VECTOR                        24


  30. //16MHz/800/1000=2Hz
  31. void TIM1_Init(void)
  32. {
  33.   
  34. //  GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);
  35.     GPIOC->DDR&=~(1<<3);//PD3 输入模式
  36.         GPIOC->CR1|=1<<3;        //PD3,上拉
  37.         GPIOC->CR2&=~(1<<3);//PD3,不使用中断(注意这里必须设置对)
  38.   
  39.   TIM1->CNTRH = 0x00;//清零计数器高8位  
  40.   TIM1->CNTRL = 0x00;//清零计数器低8位
  41.    
  42.   TIM1->ARRH = 0xFF; //自动重装载的值 255
  43.   TIM1->ARRL = 0xFF; //自动重装载的值 255
  44.   TIM1->PSCRH = 0x00;
  45.   TIM1->PSCRL = 0xA0-1; //160分频  正好是10us
  46.   
  47.   //配置通道3
  48.   TIM1->CCMR3 = 0x01;//IC3映射在TI3FP3;无分频;无滤波
  49.   TIM1->CCER2 &= ~0x02;//上升沿或高电平有效
  50.   TIM1->CCER2 |= 0x01;//输入捕获使能
  51.   
  52.   //配置通道4
  53.   TIM1->CCMR4 = 0x02;//IC3映射在TI3FP3;无分频;无滤波
  54.   TIM1->CCER2 |= 1<<5;//下降沿或低电平有效
  55.   TIM1->CCER2 |= 0x10;//输入捕获使能
  56.   
  57.   TIM1->SR1 &=0<<3;   // 清除捕获标志
  58.   TIM1->SR2 &=0<<3 ;   // 清除重复捕获标志
  59.   
  60.   TIM1->SR1 &=0<<4;   // 清除捕获标志
  61.   TIM1->SR2 &=0<<4 ;   // 清除重复捕获标志
  62.   
  63.   TIM1->CR1 |= 1<<7; //预装载使能
  64.   
  65.   TIM1->IER |= 1<<3; //使能CC3IE中断
  66.   TIM1->IER |= 1<<4; //使能CC3IE中断
  67.   
  68.   TIM1->CR1 |= 1<<0; //启动定时器
  69. }

  70. //16MHz/512/15625=2Hz
  71. void TIM2_Init(void)
  72. {
  73.     GPIOD->DDR&=~(1<<3);//PD3 输入模式
  74.         GPIOD->CR1|=1<<3;        //PD3,上拉
  75.         GPIOD->CR2&=~(1<<3);//PD3,不使用中断
  76.         
  77.         
  78.     CLK->PCKENR1|=1<<5;        //开启TIM2时钟
  79.         TIM2->PSCR=3;                //2^psc次方分频
  80.         TIM2->ARRH=0XFF;        //必须先设置ARR的高字节
  81.         TIM2->ARRL=0XFF;//再设置低字节
  82.         
  83.    
  84.     /**********************************通道1配置*********************/
  85.     TIM2->CCMR1|=0X02;//映射通道2
  86.     TIM2->CCER1&=0<<1;//捕获上升沿
  87.     TIM2->CCER1|=1<<0;//IC1使能

  88.     /**********************************通道2配置*********************/
  89.         TIM2->CCMR2|=0X01<<0;//映射通道2
  90.         TIM2->CCER1|=1<<5;        //捕获下降沿
  91.         TIM2->CCER1|=1<<4;        //IC2输入捕获使能,允许捕获计数器的值到捕获寄存器中

  92.         
  93.     TIM2->SR1 &=0<<2;   // 清除捕获标志
  94.     TIM2->SR2 &=0<<2 ;   // 清除重复捕获标志
  95.         
  96.         TIM2->CR1|=1<<7;        //预装载使能
  97.         //TIM2->IER|=1<<2;        //通道2捕获中断使能
  98.         TIM2->IER|=0X03<<1;//通道1,通道2捕获中断使能
  99.         TIM2->CR1|=1<<0;        //使能TIM2
  100.         
  101. }

  102. //Timer1 Capture/Compare Interrupt routine
  103. INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
  104. {
  105.     TIM1->SR1&=~(1<<4);//清除通道2捕获中断标志位
  106.     TIM1->SR1&=~(1<<3);
  107. }

  108. INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14)
  109. {
  110.     TIM1->SR1&=~(1<<1);//清除通道2捕获中断标志位 TIM2_ClearITPendingBit(TIM2_IT_CC1);
  111.     TIM1->SR1&=~(1<<2);//TIM2_ClearITPendingBit(TIM2_IT_CC2);
  112.    
  113. }

  114. int main( void )
  115. {   
  116.         __disable_interrupt();       
  117.     CLK->CKDIVR&= (uint8_t)(~0x18);/*时钟复位*/
  118.     CLK->CKDIVR|= (uint8_t)0x00;/*设置时钟为内部16M高速时钟*/
  119.     TIM1_Init();
  120.     TIM2_Init();
  121.     __enable_interrupt();
  122.           while(1)
  123.         {                           

  124.         }
  125. }


复制代码
openmcu666
2楼-- · 2020-01-11 02:46
  1. /*****************************************************************************************************************************/
  2. //定时器2.输入捕获初始化代码
  3. //输入捕获计数频率: Fmaster/(2^psc)
  4. //输入捕获最大值:arr
  5. //psc:分配系数,0~15;分频系数为:2^psc,最大为2^15=32768分频
  6. //arr:自动重装载值,0~65535
  7. void TIM2_CAP_Init(u8 psc,u16 arr)
  8. {
  9.        
  10.         GPIOD->DDR&=~(1<<3);//PD3 输入模式
  11.         GPIOD->CR1|=1<<3;        //PD3,上拉
  12.         GPIOD->CR2&=~(1<<3);//PD3,不使用中断
  13.         
  14.         
  15.          CLK->PCKENR1|=1<<5;        //开启TIM2时钟
  16.         TIM2->PSCR=psc;                //2^psc次方分频
  17.         TIM2->ARRH=arr>>8;        //必须先设置ARR的高字节
  18.         TIM2->ARRL=arr&0XFF;//再设置低字节
  19.         
  20.         //TIM2->CNTRH=0;                                        //计数器清空
  21.         //TIM2->CNTRL=0;       
  22.         
  23.         /**********************************通道1配置*********************/
  24.         TIM2->CCMR1|=0X02;//映射通道2
  25.         TIM2->CCER1&=0<<1;//捕获上升沿
  26.         TIM2->CCER1|=1<<0;//IC1使能

  27.         /**********************************通道2配置*********************/
  28.         TIM2->CCMR2|=0X01<<0;//映射通道2
  29.         TIM2->CCER1|=1<<5;        //捕获下降沿
  30.         TIM2->CCER1|=1<<4;        //IC2输入捕获使能,允许捕获计数器的值到捕获寄存器中

  31.         
  32.         TIM2->SR1 &=0<<2;   // 清除捕获标志
  33.         TIM2->SR2 &=0<<2 ;   // 清除重复捕获标志
  34.         
  35.         TIM2->CR1|=1<<7;        //预装载使能
  36.         //TIM2->IER|=1<<2;        //通道2捕获中断使能
  37.         TIM2->IER|=0X03<<1;//通道1,通道2捕获中断使能
  38.         TIM2->CR1|=1<<0;        //使能TIM2

  39. }
复制代码
zhcj66
3楼-- · 2020-01-11 05:04
 精彩回答 2  元偷偷看……
openmcu666
4楼-- · 2020-01-11 06:26
zhcj66 发表于 2018-6-8 16:19
抄上你的函数,发现也无法进入中断函数;你那个可以正常进入吗?

还是我中断函数出错了

可以啊,这个是项目中用过的
zhcj66
5楼-- · 2020-01-11 06:45
openmcu666 发表于 2018-6-8 16:28
可以啊,这个是项目中用过的

看看我的中断函数没错吧,
openmcu666
6楼-- · 2020-01-11 10:11
zhcj66 发表于 2018-6-8 16:32
看看我的中断函数没错吧,

  1. //TIM2捕获中断服务函数
  2. INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, TIM2_CAP_COM_VECTOR)
  3. {   
  4.        uint16_t data;

  5.       if(TIM2->SR1&0x04)//捕获2发生捕获事件
  6.           {       
  7.                data=(TIM2->CCR2H<<8)+TIM2->CCR2L;
  8.                printf("进入中断下降沿 ");
  9.                TIM2->SR1&=~(1<<2);//清除通道2捕获中断标志位
  10.           }
  11.       
  12.         if(TIM2->SR1&0X02){
  13.               data=(TIM2->CCR1H<<8)+TIM2->CCR1L;
  14.            printf("进入中断上升沿中断 ");
  15.            TIM2->SR1&=~(1<<1);//清除通道1捕获中断标志位
  16.          }
  17.                
  18.       TIM2->CNTRH=0;                                        //计数器清空
  19.       TIM2->CNTRL=0;               
  20.        
  21. }
复制代码

一周热门 更多>