使用STM32F103RBT6处理器,使用PA7管脚对应的TIM3_CH2进行输入捕获,捕获一段负电平长度(负电平结束时会直接跳变到+3V左右)。
由于硬件电路设计,我的程序“任务2”用来产生一段负电平,但是这段负电平维持一段时间后(毫秒级)会自动跳变到高电平,所以我想用TIM3_CH2的上升沿捕获这段电平的长度,即从任务2开始之后打开定时器3,然后阻塞程序直到上升沿到来,然后在定时器中断中捕获这段负电平长度。一直没有成功,而且出现了一些比较奇怪的现象:为了调试,我在定时器3的中断中加入了一些打印信息,我是在while循环里打开定时器3的,但无论是否注释掉这一句,第一次循环的时候都会在固定位置(任务1后边)打印定时器3中断的信息……
部分代码如下:
//定时器3通道2输入捕获初始化
void TIM3_Cap_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1; //TIM3 时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0X0FFFFFFF; //PA7 清除之前设置
GPIOA->CRL|=0X80000000; //PA7 输入
GPIOA->ODR|=1<<7; //PA7 上拉
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器
TIM3->CCMR1|=1<<8; //CC2S=01 选择输入端 IC2映射到TI2上
TIM3->CCMR1|=0<<12; //IC2F=0000 配置输入滤波器 不滤波
TIM3->CCMR1|=0<<10; //IC2PSC=00 配置输入分频,不分频
TIM3->CCER|=0<<5; //CC2P=1 上升沿捕获
TIM3->CCER|=1<<4; //CC2E=1 允许捕获计数器的值到捕获寄存器中
TIM3->DIER|=1<<2; //使能捕获中断
TIM3->DIER|=1<<0; //使能更新中断
TIM3->CR1&=0x00; //关闭定时器3
MY_NVIC_Init(2,0,TIM3_IRQChannel,2);//抢占2,子优先级0,组2
}
u8 TIM3CH2_CAPTURE_STA=0; //输入捕获状态
u16 TIM3CH2_CAPTURE_VAL=0; //输入捕获值
//定时器3中断服务程序
u8 T3_Num = 0;
void TIM3_IRQHandler(void)
{
u16 tsr;
printf("AD Capture\n");
tsr=TIM3->SR;
if(0 == T3_Num)
{
T3_Num++;//第一次开定时器会产生中断,避过这次中断
}
else {
if((TIM3CH2_CAPTURE_STA&0X1)==0)//main函数中将TIM3CH2_CAPTURE_VAL置零才能开启下一次捕获
{
printf("AD Capture 1\n");
// if(tsr&0x02)//捕获1发生捕获事件
if(tsr&0x04)//捕获2发生捕获事件
{
TIM3CH2_CAPTURE_STA = 1; //标记为一次捕获
printf("AD Capture 2\n");
TIM3CH2_CAPTURE_VAL = TIM3->CCR2; //获取捕获值
printf("Capture_value:%f\n",TIM3CH1_CAPTURE_VAL);
}
}
TIM3->SR=0;//清除中断标志位
TIM3->CR1 &= 0x00;
}
}
//主程序
extern u8 TIM3CH2_CAPTURE_STA;
extern u16 TIM3CH2_CAPTURE_VAL;
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,115200);
TIM3_Cap_Init(19999,7199);
while(1)
{
任务1();
任务2();
TIM3->CR1 |= 0x01; //开启定时器3
while(0 == TIM3CH2_CAPTURE_STA);
}
} |