void TIM2_Cap_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0;
//TIM2 时钟使能
RCC->APB2ENR|=1<<2;
//使能PORTA时钟
GPIOA->CRL&=0XFFFFFFF0;
//PA0 清除之前设置
GPIOA->CRL|=0X00000008;
//PA0 输入 输入模式 1000
GPIOA->ODR|=1<<0; //PA0 下拉
TIM2->ARR=arr;
//设定计数器自动重装值
TIM2->
SC=psc;
//预分频器
TIM2->CCMR1|=1<<0;
//CC1S=01
选择输入端 IC1映射到TI1上
TIM2->CCMR1|=0<<4;
//IC1F=0000 配置输入滤波器 不滤波
TIM2->CCMR1|=0<<10;
//IC2PS=00
配置输入分频,不分频
TIM2->CCER|=1<<1; //CC1P=0
上升沿捕获
TIM2->CCER|=1<<0;
//CC1E=1
允许捕获计数器的值到捕获寄存器中
TIM2->DIER|=1<<1;
//允许捕获中断
TIM2->DIER|=1<<0;
//允许更新中断
TIM2->CR1|=0x01;
//使能定时器2
MY_NVIC_Init(2,0,TIM2_IRQChannel,2);//抢占2,子优先级0,组2
}
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获高电平后溢出的次数
u8 TIM2CH1_CAPTURE_STA=0;
//输入捕获状态
u16
TIM2CH1_CAPTURE_VAL;
//输入捕获值
//定时器2中断服务程序
void TIM2_IRQHandler(void)
{
u16 tsr;
//u16 temp;
tsr=TIM2->SR;
if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{
if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM2CH1_CAPTURE_VAL=0XFFFF;
}else TIM2CH1_CAPTURE_STA++;
}
}
if(tsr&0x02)//捕获1发生捕获事件
{
if(TIM2CH1_CAPTURE_STA&0X40)
//捕获到一个下降沿
{
TIM2CH1_CAPTURE_STA|=0X80;
//标记成功捕获到一次高电平脉宽
TIM2CH1_CAPTURE_VAL=TIM2->CCR1;
//获取当前的捕获值.
//TIM2CH1_CAPTURE_VAL-=temp;
TIM2->CCER&=~(0<<1); //CC1P=0 设置为上升沿捕获
}else
//还未开始,第一次捕获上升沿
{
TIM2CH1_CAPTURE_STA=0;
//清空
TIM2CH1_CAPTURE_VAL=0;
//temp=TIM2->CCR1;
TIM2CH1_CAPTURE_STA|=0X40;
//标记捕获到了上升沿
TIM2->CNT=0;
//计数器清空
TIM2->CCER|=0<<1; //CC1P=1 设置为下降沿捕获
}
}
}
TIM2->SR=0;//清除中断标志位
}
为什么设置成
先上升沿再下降沿就能
正确测量高电平脉宽,可我按红 {MOD}标记的地方更改设置成
先下降沿再上升沿后就不能测量低电平脉宽,而是周期时间,麻烦原子哥帮我看下!
---------------------------------
原子哥,我想问一下,为什么我把捕获通道改为3、4都不行,改成1、2就可以了?我用的是TIM4,另外我对 TIM4_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC1S=01 选择输入端 IC1映射到TI1上
和 TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
不是很理解,希望得到你的帮助,谢谢~
一周热门 更多>