stm32 输入捕获学习(二)
来源:互联网 发布:c语言做游戏 编辑:程序博客网 时间:2024/05/18 15:23
(本文参考STM32 开发指南 V1.3 —— ALIENTEK 战舰 STM32 开发板库函数教程 )
1. 实验设计
我们用 TIM5 的通道 1(PA0)来做输入捕获,捕获 PA0 上高电平的脉宽(用 WK_UP 按键输入高电平),通过串口打印高电平脉宽时间。
2. 原理说明
基本原理可以参考上一篇博文,在上个实验的基础上,我们稍作修改,就可以实现功能。
1)增加GPIO的配置。
这里我们使用的是KEY_UP按键,WK_UP右端连接PA0. 我们把PA0配置为下拉输入,这样不按键PA0就是低电平,按键的话PA0就是高电平。
2)修改中断处理程序
TIM5_IRQHandler 是 TIM5 的中断服务函数,该函数用到了两个全局变量,用于辅助实现高电平捕获。其中TIM5CH1_CAPTURE_STA,是用来记录捕获状态。TIM5CH1_CAPTURE_STA 各位描述如下图所示:
另外一个变量 TIM5CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM5_CNT的值。
现在我们来介绍一下,捕获高电平脉宽的思路:
首先,设置 TIM5_CH1 为上升沿捕获(这在TIM5_Cap_Init 函数中就设置好了),等待上升沿中断到来。此时如果 TIM5CH1_CAPTURE_STA 的第 6 位为 0,则表示还没有捕获到上升沿,这时把 TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL 和 TIM5->CNT 清零,然后再设置TIM5CH1_CAPTURE_STA 的第 6 位为 1,表示已经捕获到高电平,最后设置为下降沿捕获,等待下降沿到来。
当下降沿到来的时候,先设置 TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时定时器值到 TIM5CH1_CAPTURE_VAL 里面(等待主函数处理),最后设置为上升沿捕获,回到初始状态。
如果等待下降沿到来的期间,定时器发生了溢出,就在 TIM5CH1_CAPTURE_STA里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿),并且设置TIM5CH1_CAPTURE_VAL为最大值0XFFFF,最后设置成上升沿捕获,回到初始状态。
这样,我们就完成一次高电平捕获,只要 TIM5CH1_CAPTURE_STA 的第 7 位一直为 1,就不会进行第二次捕获。我们在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA置零,就可以开启第二次捕获。
3. 参考代码
GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 下拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);上面这段代码增加到 void TIM5_Cap_Init(u16 arr,u16 psc) 函数中。
中断处理如下
u8 TIM5CH1_CAPTURE_STA = 0; u16TIM5CH1_CAPTURE_VAL;//保存TIM5的值 void TIM5_IRQHandler(void){ if((TIM5CH1_CAPTURE_STA&0X80)==0)//主函数已经处理完了捕获{ if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //定时器更新中断{ if(TIM5CH1_CAPTURE_STA & 0X40) //已经捕获到高电平{if((TIM5CH1_CAPTURE_STA & 0X3F)==0X3F)//高电平的时间太长,强制捕获完成{TIM5CH1_CAPTURE_STA |= 0X80; //标记捕获完成TIM5CH1_CAPTURE_VAL = 0XFFFF; TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置为上升沿捕获}else{TIM5CH1_CAPTURE_STA++;}} }if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) //捕获中断{if(TIM5CH1_CAPTURE_STA & 0X40)//此时捕获下降沿{ TIM5CH1_CAPTURE_STA|=0X80;//标记捕获完成TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置为上升沿捕获}else //捕获到了上升沿{TIM5CH1_CAPTURE_STA=0;TIM5CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM5,0);TIM5CH1_CAPTURE_STA|=0X40;//标记捕获到了上升沿 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//设置为下降沿捕获} } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志 }
主函数代码:
extern u8 TIM5CH1_CAPTURE_STA; extern u16TIM5CH1_CAPTURE_VAL;int main(void){u32 temp = 0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(9600); //串口初始化,波特率9600TIM5_Cap_Init(0XFFFF,72-1);//1MHz 计数频率 while(1){if(TIM5CH1_CAPTURE_STA & 0X80) //成功捕获到一个高脉冲{temp = TIM5CH1_CAPTURE_STA & 0X3F; //定时器溢出次数temp *= 65536; //溢出时间总和temp += TIM5CH1_CAPTURE_VAL; //算出高电平的时间printf("HIGH:%d us\r\n",temp); //串口打印TIM5CH1_CAPTURE_STA=0; //开启下一次捕获};}}3.实验结果
- stm32 输入捕获学习(二)
- stm32 输入捕获学习(一)
- stm32库函数学习篇---通用定时器(输入捕获功能)
- stm32库函数学习篇---通用定时器(输入捕获功能)
- 寒假学习之stm32(9)----PWM进行输入捕获
- stm32库函数学习篇---通用定时器(输入捕获功能)
- stm32学习笔记(十)输入捕获实验
- STM32输入捕获
- STM32 输入捕获
- STM32输入捕获简介
- STM32输入捕获简介
- STM32输入捕获简介
- STM32输入捕获简介
- STM32定时器输入捕获
- STM32的输入捕获
- STM32输入捕获模式
- stm32 输入捕获
- Stm32-输入捕获
- MRF,马尔科夫随机场
- spring 依赖注入注解配置原理解析
- 【mfc】不同对话框之间互相操控、全局变量与日期控件
- 操作格子
- 浅谈标准I/O缓冲区
- stm32 输入捕获学习(二)
- 排序算法一:冒泡排序
- ipc连接时出来这个提示: 不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接。中断与此服务器或共享资源的连接,然后在试一次...
- uva1160 ADT
- Java-基础篇-5.28-梅森素数
- Oracle中随机函数的常规用法
- 【瞎搞】 ZOJ 3041 City Selection
- 阿兰·麦席森·图灵
- HDU 1847 Good Luck in CET-4 Everybody!(SG的简单运用)