在和朋友听网易云,然后随便学学写写
第一次写博客 写着玩。
简介
输入捕获用于测量脉冲宽度或者频率,以我浅短的学识来理解,就是测量一个上升沿到另一个下降沿 或 一个下降沿到另一个上升沿中间的时间。
寄存器就先不深入,了解一下即可,重在库函数的运用。
如何测量
运用通用定时器,除TIM6和TIM7其余定时器都有输入捕获的功能,也许TIM6和TIM7是基本定时器吧。
为什么不用高级定时器?因为我不会。而且通用定时器应该方便些噻。
代码
首先第一步肯定是使能时钟。
选用TIM5,也可以换成其他的,然后使能准备去捕获的GPIOA口
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能 TIM5 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟
第二步
接下就去初始化我们的GPIO口和定时器。
毕竟心急吃不了热豆腐 从最开始的工作做起
GPIO初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
为什么要设置为下拉,说句老实话我也不知道,还没学模电数电啥的。但是我们可以看下面这张图
不过看了下资料,好像是WK UP右方连接了一个电阻,电阻下接入了一个GND,保持WK UP平时为低电平,而当KEY_UP按下后,接入VCC则输入了高电平,应该是这样才能达到按键按下后输入电平相反的效果。
定时器初始化
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
其中TIM_ClockDivision 这个东西似乎不怎么用,咱们就这样配置就行了
Period是计数值,达到该计数值后溢出
Prescaler是预分频系数
同时补充一下,定时器最终的定时时间公式是(psc+1)*(arr+1)/Tclk(主频)
第三步
既然我们要去捕获,我们就需要去设置TIM5的捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00; //不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
TIM_Channel
找了很久才找到,TIM5_CH1通道1映射到PA0上.
TIM_ICSelection
这个我也不是很清楚,但是我们可以看其中的三个选项
可以知道这是设置某个模式。就先这样记住吧。
不分频,不滤波,在特殊情况再进行调整吧
第四步
即为最后的使能,以及打开中断
TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新和捕获中断
TIM_Cmd(TIM5,ENABLE );
至于这个TIM_IT_CC1,肯定就是允许通道1的中断,即之前配置定时器捕获的这个函数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1;
还有一个
就是NVIC优先级的分组,这个就不多说了
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级 2 级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级 0 级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
最后再主函数中加入这个函数即可。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
所以最终的代码
void ShuruBuhuo_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能 TIM5 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //下拉
GPIO_Init(GPIOA, &GPIO_InitStruct);
TIM_TimeBaseInitStruct.TIM_Period = arr;
TIM_TimeBaseInitStruct.TIM_Prescaler =psc;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStruct);
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频
TIM_ICInitStruct.TIM_ICFilter = 0; //不滤波
TIM_ICInit(TIM5, &TIM_ICInitStruct);
NVIC_InitStruct.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级 2 级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //从优先级 0 级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新和捕获中断
TIM_Cmd(TIM5,ENABLE );
}