关于N32L430输入捕获方式。
主要是为了读取水流传感器的频率变化,捕获一个上升沿和一个下降沿,就可以得到一个周期T,单位是毫秒。1000ms/T=f (HZ)了。
我用的传感器是水流越大,频率越高。
我使用的PB10 口,在定时器2的通道3。下面代码:
1.配置PB10成输入下拉模式。
GPIO_InitStructure.Pin=QSSL_DEF_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Input;//输入模式
GPIO_InitStructure.GPIO_Pull=GPIO_Pull_Down;
GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM2;
GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
2.打开外设
RCC_EnableAPB2PeriphClk(QSSL_DEF_CLK,ENABLE);
RCC_EnableAPB1PeriphClk(QSSL_DEF_TIM_CLK,ENABLE);
3.配置TIM2定时器
TIM_TimeBaseStructure.Period=QSSL_DEF_Period; //周期
TIM_TimeBaseStructure.Prescaler=QSSL_DEF_Prescaler;//分频因子,1000KZ,1ms
TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;//向上计数
TIM_InitTimeBase(QSSL_DEF_TIM, &TIM_TimeBaseStructure);
4.配置定时器输入捕获模式
TIM_ICInitStructure.Channel = TIM_CH_3;
TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_RISING;
TIM_ICInitStructure.IcSelection = TIM_IC_SELECTION_DIRECTTI;//直连
TIM_ICInitStructure.IcPrescaler = TIM_IC_PSC_DIV1;
TIM_ICInitStructure.IcFilter = 0x0;
TIM_ICInit(TIM2,&TIM_ICInitStructure);
TIM_Enable(TIM2, ENABLE); //定时器使能
TIM_ConfigInt(TIM2, TIM_INT_CC3, ENABLE)//CCR寄存使能中断
TIM_ClearFlag(TIM2,TIM_FLAG_CC3);//清除标志
TIM_ClrIntPendingBit(TIM2,TIM_FLAG_CC3);
5.配置中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
配置完成后,开始写中断函数
void TIM2_IRQHandler(void)
{
if((tim2_ch_status[0].Cap_Flag)==0)//开始捕获
{
if(TIM_GetIntStatus(TIM2,TIM_INT_CC3) != RESET)//捕获1发生捕获事件
{
if(tim2_ch_status[0].Polarity_Flag==2)//第二次捕获上升沿
{
TIM_SetCnt(TIM2,0);
tim2_ch_status[0].L_Cnt=TIM_GetCap3(TIM2);//获取低电平时间
tim2_ch_status[0].Cap_Flag=1;//捕获结束
//printf("3333 =%d \r\n",tim2_ch_status[0].L_Cnt);
}
if(tim2_ch_status[0].Polarity_Flag==1)//第一次捕获到下降沿
{
TIM_SetCnt(TIM2,0);
tim2_ch_status[0].Polarity_Flag=2;//
tim2_ch_status[0].H_Cnt=TIM_GetCap3(TIM2);//获取TIM2_CH3的CCR值,高电平的值
TIM_ConfigOc3Polarity(TIM2,TIM_IC_POLARITY_RISING);//上升捕获
//printf("2222 =%d \r\n",tim2_ch_status[0].H_Cnt);
}
if(tim2_ch_status[0].Polarity_Flag==0)//第一次捕获到上升沿
{
//TIM_ClearFlag(TIM2,TIM_FLAG_CC3);
TIM_SetCnt(TIM2,0);
tim2_ch_status[0].Polarity_Flag=1;//
tim2_ch_status[0].H_Cnt=0;//高电平时间
tim2_ch_status[0].L_Cnt=0;//低电平时间
TIM_ConfigOc3Polarity(TIM2,TIM_IC_POLARITY_FALLING);//下降捕获
}
}
}
TIM_ClrIntPendingBit(TIM2,TIM_INT_CC3);//清空中断标志
//TIM_ClrIntPendingBit(TIM2,TIM_INT_UPDATE);//清空中断标志
}
中断函数只获取标志,程序不要在中断执行,我放在100ms定时扫描任务里面
u16 Get_QSSL_Vol(void)//获取清水水流量,频率越高,水流越大
{
u8 Hz=0;//频率
if(tim2_ch_status[0].Cap_Flag==1)//捕获成功
{
Hz=1000/(tim2_ch_status[0].H_Cnt + tim2_ch_status[0].L_Cnt);//毫秒
tim2_ch_status[0].Polarity_Flag=0;//准备第一次上升沿检测
tim2_ch_status[0].Cap_Flag=0; //准备下一次捕获
rt_kprintf("TIM2_CH3= %d Hz\r\n",Hz);
}
return Hz;
}
好了,可以读取频率了。