本帖最后由 zhcj66 于 2018-6-8 14:32 编辑
调试了2天了如题"STM8S103F外部触发捕获/比较寄存器更新了,但无法中断"不知道咋回事,是程序的问题还是芯片的问题
- //程序设置如下
- void TIM1_Init(void)
- {
-
- GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_FL_IT);
-
- TIM1->CNTRH = 0x00;//清零计数器高8位
- TIM1->CNTRL = 0x00;//清零计数器低8位
-
- TIM1->ARRH = 0xFF; //自动重装载的值 255
- TIM1->ARRL = 0xFF; //自动重装载的值 255
- TIM1->PSCRH = 0x00;
- TIM1->PSCRL = 0xA0-1; //160分频 正好是10us
-
- TIM1->CCER2 &= ~0x01;//清零CCxE,之后才可配置CCMR
- TIM1->CCMR3 = 0x01;//IC3映射在TI3FP3;无分频;无滤波
- TIM1->CCER2 &= ~0x02;//上升沿或高电平有效
- TIM1->IER |= 0x08; //使能CC3IE中断
- TIM1->CCER2 |= 0x01;//输入捕获使能
- TIM1->CR1 = 0x01; //启动定时器
- }
- INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
- {//程序无法进入这个中断
- TIM1_ClearITPendingBit(TIM1_IT_CC3);
- }
复制代码
中断标志寄存器也置位了,可是就是无法进入中断寄存器;可以确定的是全局中断已经打开,因为定时器2正常工作着.
TIM1_IER值为0x08应该标志位置位后就可以进入中断的,可是就是进不去,在触发的时候TIM1_CCR3也有数据更新
问题已经解决
问题出在IO设置上 应该设置成GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT); 上拉无中断,结果设置成了中断 因此无法进入定时的的IC中断
- //本程序可以通过检测脉冲的上升沿和下降沿,来判断脉冲的占空比
- #include <stdio.h>
- #include "stm8s.h"
- #include "sys.h"
- #define TLI_VECTOR 0
- #define AWU_VECTOR 1
- #define CLK_VECTOR 2
- #define EXTI_PA_VECTOR 3
- #define EXTI_PB_VECTOR 4
- #define EXTI_PC_VECTOR 5
- #define EXTI_PD_VECTOR 6
- #define EXTI_PE_VECTOR 7
- #define CAN_RX_VECTOR 8
- #define CAN_TX_VECTOR 9
- #define SPI_VECTOR 10
- #define TIM1_UPD_OVF_VECTOR 11
- #define TIM1_CAP_COM_VECTOR 12
- #define TIM2_UPD_OVF_VECTOR 13
- #define TIM2_CAP_COM_VECTOR 14
- #define TIM3_UPD_OVF_VECTOR 15
- #define TIM3_CAP_COM_VECTOR 16
- #define UART1_TX_VECTOR 17
- #define UART1_RX_VECTOR 18
- #define I2C_VECTOR 19
- #define UART23_TX_VECTOR 20
- #define UART23_RX_VECTOR 21
- #define ADC_VECTOR 22
- #define TIM4_UPD_OVF_VECTOR 23
- #define FLASH_VECTOR 24
- //16MHz/800/1000=2Hz
- void TIM1_Init(void)
- {
-
- // GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);
- GPIOC->DDR&=~(1<<3);//PD3 输入模式
- GPIOC->CR1|=1<<3; //PD3,上拉
- GPIOC->CR2&=~(1<<3);//PD3,不使用中断(注意这里必须设置对)
-
- TIM1->CNTRH = 0x00;//清零计数器高8位
- TIM1->CNTRL = 0x00;//清零计数器低8位
-
- TIM1->ARRH = 0xFF; //自动重装载的值 255
- TIM1->ARRL = 0xFF; //自动重装载的值 255
- TIM1->PSCRH = 0x00;
- TIM1->PSCRL = 0xA0-1; //160分频 正好是10us
-
- //配置通道3
- TIM1->CCMR3 = 0x01;//IC3映射在TI3FP3;无分频;无滤波
- TIM1->CCER2 &= ~0x02;//上升沿或高电平有效
- TIM1->CCER2 |= 0x01;//输入捕获使能
-
- //配置通道4
- TIM1->CCMR4 = 0x02;//IC3映射在TI3FP3;无分频;无滤波
- TIM1->CCER2 |= 1<<5;//下降沿或低电平有效
- TIM1->CCER2 |= 0x10;//输入捕获使能
-
- TIM1->SR1 &=0<<3; // 清除捕获标志
- TIM1->SR2 &=0<<3 ; // 清除重复捕获标志
-
- TIM1->SR1 &=0<<4; // 清除捕获标志
- TIM1->SR2 &=0<<4 ; // 清除重复捕获标志
-
- TIM1->CR1 |= 1<<7; //预装载使能
-
- TIM1->IER |= 1<<3; //使能CC3IE中断
- TIM1->IER |= 1<<4; //使能CC3IE中断
-
- TIM1->CR1 |= 1<<0; //启动定时器
- }
- //16MHz/512/15625=2Hz
- void TIM2_Init(void)
- {
- GPIOD->DDR&=~(1<<3);//PD3 输入模式
- GPIOD->CR1|=1<<3; //PD3,上拉
- GPIOD->CR2&=~(1<<3);//PD3,不使用中断
-
-
- CLK->PCKENR1|=1<<5; //开启TIM2时钟
- TIM2->PSCR=3; //2^psc次方分频
- TIM2->ARRH=0XFF; //必须先设置ARR的高字节
- TIM2->ARRL=0XFF;//再设置低字节
-
-
- /**********************************通道1配置*********************/
- TIM2->CCMR1|=0X02;//映射通道2
- TIM2->CCER1&=0<<1;//捕获上升沿
- TIM2->CCER1|=1<<0;//IC1使能
- /**********************************通道2配置*********************/
- TIM2->CCMR2|=0X01<<0;//映射通道2
- TIM2->CCER1|=1<<5; //捕获下降沿
- TIM2->CCER1|=1<<4; //IC2输入捕获使能,允许捕获计数器的值到捕获寄存器中
-
- TIM2->SR1 &=0<<2; // 清除捕获标志
- TIM2->SR2 &=0<<2 ; // 清除重复捕获标志
-
- TIM2->CR1|=1<<7; //预装载使能
- //TIM2->IER|=1<<2; //通道2捕获中断使能
- TIM2->IER|=0X03<<1;//通道1,通道2捕获中断使能
- TIM2->CR1|=1<<0; //使能TIM2
-
- }
- //Timer1 Capture/Compare Interrupt routine
- INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
- {
- TIM1->SR1&=~(1<<4);//清除通道2捕获中断标志位
- TIM1->SR1&=~(1<<3);
- }
- INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14)
- {
- TIM1->SR1&=~(1<<1);//清除通道2捕获中断标志位 TIM2_ClearITPendingBit(TIM2_IT_CC1);
- TIM1->SR1&=~(1<<2);//TIM2_ClearITPendingBit(TIM2_IT_CC2);
-
- }
- int main( void )
- {
- __disable_interrupt();
- CLK->CKDIVR&= (uint8_t)(~0x18);/*时钟复位*/
- CLK->CKDIVR|= (uint8_t)0x00;/*设置时钟为内部16M高速时钟*/
- TIM1_Init();
- TIM2_Init();
- __enable_interrupt();
- while(1)
- {
- }
- }
复制代码- /*****************************************************************************************************************************/
- //定时器2.输入捕获初始化代码
- //输入捕获计数频率: Fmaster/(2^psc)
- //输入捕获最大值:arr
- //psc:分配系数,0~15;分频系数为:2^psc,最大为2^15=32768分频
- //arr:自动重装载值,0~65535
- void TIM2_CAP_Init(u8 psc,u16 arr)
- {
-
- GPIOD->DDR&=~(1<<3);//PD3 输入模式
- GPIOD->CR1|=1<<3; //PD3,上拉
- GPIOD->CR2&=~(1<<3);//PD3,不使用中断
-
-
- CLK->PCKENR1|=1<<5; //开启TIM2时钟
- TIM2->PSCR=psc; //2^psc次方分频
- TIM2->ARRH=arr>>8; //必须先设置ARR的高字节
- TIM2->ARRL=arr&0XFF;//再设置低字节
-
- //TIM2->CNTRH=0; //计数器清空
- //TIM2->CNTRL=0;
-
- /**********************************通道1配置*********************/
- TIM2->CCMR1|=0X02;//映射通道2
- TIM2->CCER1&=0<<1;//捕获上升沿
- TIM2->CCER1|=1<<0;//IC1使能
- /**********************************通道2配置*********************/
- TIM2->CCMR2|=0X01<<0;//映射通道2
- TIM2->CCER1|=1<<5; //捕获下降沿
- TIM2->CCER1|=1<<4; //IC2输入捕获使能,允许捕获计数器的值到捕获寄存器中
-
- TIM2->SR1 &=0<<2; // 清除捕获标志
- TIM2->SR2 &=0<<2 ; // 清除重复捕获标志
-
- TIM2->CR1|=1<<7; //预装载使能
- //TIM2->IER|=1<<2; //通道2捕获中断使能
- TIM2->IER|=0X03<<1;//通道1,通道2捕获中断使能
- TIM2->CR1|=1<<0; //使能TIM2
- }
复制代码可以啊,这个是项目中用过的
看看我的中断函数没错吧,
- //TIM2捕获中断服务函数
- INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, TIM2_CAP_COM_VECTOR)
- {
- uint16_t data;
- if(TIM2->SR1&0x04)//捕获2发生捕获事件
- {
- data=(TIM2->CCR2H<<8)+TIM2->CCR2L;
- printf("进入中断下降沿
");
- TIM2->SR1&=~(1<<2);//清除通道2捕获中断标志位
- }
-
- if(TIM2->SR1&0X02){
- data=(TIM2->CCR1H<<8)+TIM2->CCR1L;
- printf("进入中断上升沿中断
");
- TIM2->SR1&=~(1<<1);//清除通道1捕获中断标志位
- }
-
- TIM2->CNTRH=0; //计数器清空
- TIM2->CNTRL=0;
-
- }
复制代码一周热门 更多>