初级会员
- 积分
- 110
- 金钱
- 110
- 注册时间
- 2017-9-30
- 在线时间
- 32 小时
|
5金钱
STM32F407VET6输入捕获模式下测频率,1k开始频率就不对了?利用的是上升沿触发中断,记录一下定时器的计数,第二次上升沿触发中断,再记录一下定时器计数,然后用定时器时间除以两次计数的差值。中断程序如下:
//定时器5通道1输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)//84M
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM5_ICInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); //PA0复用位定时器5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
//初始化TIM5输入捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输入端 IC2映射到TI2上
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
}
u8 state=0; //输入捕获状态
u32 timecount; //输入捕获值(TIM2/TIM5是32位)
u32 timecount1; //输入捕获值(TIM2/TIM5是32位)
u32 test; //输入捕获值(TIM2/TIM5是32位)
float fq;
//定时器5中断服务程序
void TIM5_IRQHandler(void)
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//溢出
{
printf("\r\n溢出\r\n");
TIM_Cmd(TIM5,DISABLE); //使能定时器5
}
if(TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//捕获1发生捕获事件
{
if(state==0) //捕获第一个上升沿
{
state=1;
timecount=TIM_GetCapture2(TIM5); //记录第一次上升沿的CNT值
printf("\r\n数值1=%d\r\n",timecount);
}
else if(state==1) //捕获第二个上升沿
{
state=0;
timecount1=TIM_GetCapture2(TIM5); //记录第二次上升沿的CNT值
printf("\r\n数值2=%d\r\n",timecount1);
if(timecount<timecount1)
{
test=timecount1-timecount; //两次上升沿的差值
}
else if(timecount>timecount1)
{
test=(0xffffffff-timecount)+timecount1; //两次上升沿的差值
}
fq=(float)1000000/test; //脉冲的频率
printf("\r\n频率=%f\r\n",fq);
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位
}
|
最佳答案
查看完整内容[请看2#楼]
不要在中断里printf,串口9600波特率发送一字节约占用1ms时间,你的一个printf要占多少时间你算一下。
中断里可以置标志,主循环检测标志再printf.
|