STM32F103学习笔记 (九) 输入捕获实验

发布者:平凡幸福最新更新时间:2017-09-24 来源: eefocus关键字:STM32F10  输入捕获 手机看文章 扫描二维码
随时随地手机看文章

这个实验是用 TIM5 的通道 1( PA0) 来做输入捕获, 捕获 PA0 上高电平的脉宽(用 WK_UP 按键输入高电平),通过串口打印高电平脉宽时间。

初始化里边先设置上升沿为输入捕捉,进入捕捉中断后,记录TIM5_CNT的值,然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM5_CNT 值。这样,前后两次 TIM5_CNT 之差,就是高电平的脉宽,
同时 TIM5 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。


相应的配置步骤为:

(1)开启TIM5时钟和GPIO时钟,设置PA0为下拉输入


  1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能 TIM5 时钟  

  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟  


(2)初始化 TIM5,设置 TIM5 的 ARR 和 PSC。(3)设置 TIM5 的输入比较参数,开启输入捕获。(4)使能捕获和更新中断(设置 TIM5 的 DIER 寄存器) (5)设置中断分组,编写中断服务函数 。


  1. if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//判断是否为更新中断  

  2. if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件  

  3. TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位  


(6)使能定时器(设置 TIM5 的 CR1 寄存器)


  1. TIM_Cmd(TIM5,ENABLE ); //使能定时器 5  



timer.c中:


  1. //定时器 5 通道 1 输入捕获配置  

  2. TIM_ICInitTypeDef TIM5_ICInitStructure;  

  3. void TIM5_Cap_Init(u16 arr,u16 psc)  

  4. {  

  5. GPIO_InitTypeDef GPIO_InitStructure;  

  6. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

  7. NVIC_InitTypeDef NVIC_InitStructure;  

  8. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //①使能 TIM5 时钟  

  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //①使能 GPIOA 时钟  

  10. 215  

  11. //初始化 GPIOA.0 ①  

  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //PA0 设置  

  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  

  14. GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化 GPIOA.0  

  15. GPIO_ResetBits(GPIOA,GPIO_Pin_0);  //PA0 下拉  

  16. //②初始化 TIM5 参数  

  17. TIM_TimeBaseStructure.TIM_Period = arr;  //设定计数器自动重装值  

  18. TIM_TimeBaseStructure.TIM_Prescaler =psc;  //预分频器  

  19. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TDTS = Tck_tim  

  20. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数模式  

  21. TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //初始化 TIMx  

  22. //③初始化 TIM5 输入捕获通道 1  

  23. TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1 映射到 TI1 上  

  24. TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  //上升沿捕获  

  25. TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上  

  26. TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //配置输入分频,不分频  

  27. TIM5_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器 不滤波  

  28. TIM_ICInit(TIM5, &TIM5_ICInitStructure); //初始化 TIM5 输入捕获通道 1  

  29. //⑤初始化 NVIC 中断优先级分组  

  30. NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3 中断  

  31. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级 2 级  

  32. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级 0 级  

  33. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //IRQ 通道被使能  

  34. NVIC_Init(&NVIC_InitStructure);   //初始化 NVIC  

  35. TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//④允许更新中断捕获中断  

  36. TIM_Cmd(TIM5,ENABLE );  //⑥使能定时器 5  

  37. }  

  38. u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态   

  39. u16 TIM5CH1_CAPTURE_VAL;//输入捕获值  

  40. //⑤定时器 5 中断服务程序  

  41. void TIM5_IRQHandler(void)  

  42. {  

  43. if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获  

  44. {   

  45. if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)  

  46. {   

  47. 216  

  48. if(TIM5CH1_CAPTURE_STA&0X40) //已经捕获到高电平了  

  49. {  

  50. if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了  

  51. {  

  52. TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获了一次  

  53. TIM5CH1_CAPTURE_VAL=0XFFFF;  

  54. }else TIM5CH1_CAPTURE_STA++;  

  55. }  

  56. }  

  57. if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) //捕获 1 发生捕获事件  

  58. {  

  59. if(TIM5CH1_CAPTURE_STA&0X40)  //捕获到一个下降沿  

  60. {   

  61. TIM5CH1_CAPTURE_STA|=0X80;  //标记成功捕获到一次上升沿  

  62. TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);  

  63.  TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置为上升沿捕获  

  64. }else  //还未开始,第一次捕获上升沿  

  65. {  

  66. TIM5CH1_CAPTURE_STA=0;  //清空  

  67. TIM5CH1_CAPTURE_VAL=0;  

  68. TIM_SetCounter(TIM5,0);  

  69. TIM5CH1_CAPTURE_STA|=0X40;  //标记捕获到了上升沿  

  70.  TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //设置为下降沿捕获  

  71. }   

  72. }     

  73. }  

  74.  TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位  

  75. }  



其中重要的是TIM5 的中断服务函数,TIM5CH1_CAPTURE_STA,是用来记录捕获状态:

设置 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里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置 TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器值到 TIM5CH1_CAPTURE_VAL 里面,最后设置为上升沿捕获,回到初始状态。

main.c:


  1. extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态   

  2. extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值  

  3. int main(void)  

  4. {  

  5. u32 temp=0;  

  6. delay_init();   //延时函数初始化   

  7. NVIC_Configuration();  //设置 NVIC 中断分组 2  

  8. uart_init(9600);  //串口初始化波特率为 9600  

  9. LED_Init();  //LED 端口初始化  

  10. TIM3_PWM_Init(899,0); //不分频。 PWM 频率=72000/(899+1)=80Khz  

  11. TIM5_Cap_Init(0XFFFF,72-1); //以 1Mhz 的频率计数  

  12.  while(1)  

  13. {  

  14. delay_ms(10);  

  15. TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)+1);  

  16. if(TIM_GetCapture2(TIM3)==300)  

  17. TIM_SetCompare2(TIM3,0);  

  18. if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿  

  19. {  

  20. temp=TIM5CH1_CAPTURE_STA&0X3F;  

  21. 218  

  22. temp*=65536;//溢出时间总和  

  23. temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间  

  24. printf("HIGH:%d us\r\n",temp); //打印总的高点平时间  

  25. TIM5CH1_CAPTURE_STA=0; //开启下一次捕获  

  26. }  

  27. }  

  28. }  



如果用杜邦线把PB5和PA0连起来,就会看到串口助手里以固定的时间宽度输出。


关键字:STM32F10  输入捕获 引用地址:STM32F103学习笔记 (九) 输入捕获实验

上一篇:关于PWM模式
下一篇:STM32F103学习笔记 (八) PWM输出

推荐阅读最新更新时间:2024-03-16 15:38

STM32F4_TIM输入波形捕获 (脉冲频率、占空比)
Ⅰ、概述 本文基于上一篇文章“TIM输入波形捕获(脉冲频率)”的基础上进行拓展,上一篇文章主要是捕获波形的频率,本文主要拓展捕获波形的占空比。 笔者实验测试的方法和上一篇文章一样,通过信号发生器产生PWM信号,通过串口发送频率和占空比到上位机(上位机串口助手显示其数值)。(没有信号发生器的朋友可以结合上一篇文章PWM输出做信号源;在同一块板子上也可以使用不同定时器,将PWM输出引脚接在捕获输入引脚) 实验现象:不同频率的实验现象请看上一篇文章(该文章提供的工程笔者也是进行了大量不同频率的测试,误差在几Hz属正常范围)。 1000Hz、20% - 80%占空比现象: 1000Hz、51% - 58%占空比现象: 关于
[单片机]
STM32F4_TIM<font color='red'>输入</font>波形<font color='red'>捕获</font> (脉冲频率、占空比)
STM32F10XXX 双通道ADC数据采集,TIM2触发采集
/********** (C) COPYRIGHT 2007 STMicroelectronics *********** *STM32F10XXX 双通道ADC数据采集 *环境:keil for arm mdk 4.71a 官方V3.5库 *STM32数据采集部分 * 1、ADC1/ADC2实现并行同时数据采集,12BIT最高可达1MSPS采样速度并通过STM32的DMA传输放入内存中 * 2、TIM2 CC2实现对ADC采样的触发,ADC_Sample_Frequency_Set函数实现自定义TIM2 CC2频率输出, * 3、采样的频率和采样个数通过接收到的UDP控制命令来指定
[单片机]
STM32之通用定时器输入捕获模式
#include stm32f10x.h /* RCC时钟配置 */ void RCC_config() { ErrorStatus HSEStartUpStatus; /* RCC寄存器设置为默认配置 */ RCC_DeInit(); /* 打开外部高速时钟 */ RCC_HSEConfig(RCC_HSE_ON); /* 等待外部高速时钟稳定 */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /* 设置HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_
[单片机]
TIM通用定时器:PWM输入捕获模式
一、概念理解 PWM输入捕获模式是输入捕获模式的特例,自己理解如下 1. 每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。且IC1 IC2一组,IC3 IC4一组。并且可是设置管脚和寄存器的对应关系。 2. 同一个TIx输入映射了两个ICx信号。 3. 这两个ICx信号分别在相反的极性边沿有效。 4. 两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。 5. 当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获 一个PWM周期(即连续的两个上升沿或下降沿) ,它等于包含TIM 时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。 6. 同样另一个捕获通道捕获触发信号和下一个相
[单片机]
STM32f4输入捕获,比原子更简单的写法
有没有谁和我一样,感觉正点原子的输入捕获函数看不懂 可能是我太笨了哈哈,所以参考网上资料自己写了一个 用的是正点原子stm32f4探索者板子。按键GPIO口是A5 代码测试过很多次,绝对没问题 //基本定时器里的配置, //84-1是分频为1微秒1次。 //2000000-1是2s就溢出 tim5.TIM_Prescaler=84-1; tim5.TIM_Period=2000000-1; /// u8 BUHUO_Flag=0;//捕获状态初始值为0,检测到上升沿后为1 u8 update_times=0;//记录更新/溢出次数 u32 VAL1=0,VAL2=0,Sum_tim=0;//上升沿的值,下降沿的
[单片机]
STM32F10 OLED液晶显示(IIC)
2019年7月27日 做小车的第六天。 今天我实现了一个新的功能 OLED显示汉字。 刚开始学习这个显示汉字的时候也是一头污水,代码啊大部分看不懂,看OLED讲解的那个视频反复看了好几遍。还是没什么思路。 但是那自己慢慢的开始修改自带的源代码,尝试的去做,从显示点、线、字符、字符串一步步的开始进行,随着这个一步步的学会,显示汉字那,哈哈,原理也是差不多。 大致思路也就是调用.c中的函数,设置里面的变量,去调出自己想要的字符,汉字的代码(这些代码都是在一个数组里) 先说说重要的,怎么显示出汉字: 比如我们想让OLED显示屏显示一个字符串:“CODE”, 主函数是这么两条语句: OLED_ShowString(63,48
[单片机]
<font color='red'>STM32F10</font> OLED液晶显示(IIC)
STM32CubeMX系列 | 输入捕获
1. 输入捕获简介 输入捕获模式可以用来测量脉冲宽度或者测量频率,下图以测量脉宽为例来说明输入捕获的原理 假定定时器工作在向上计数模式,图中t1-t2的时间就是我们需要测量的低电平时间。测量方法为:首先设置定时器通道x为下降沿捕获,在t1时刻就会捕获到当前的CNT值,然后立即清零CNT,并设置通道x为上升沿捕获,到t2时刻又会发送捕获事件,得到此时的CNT值(记为CCRx2)。在t1-t2之间可能产生N次定时器溢出,因此需要对定时器溢出做处理,防止低电平太长导致数据不准确。 t1-t2之间计数的次数为:N * ARR + CCRx2,再乘以CNT计数周期即可得到低电平持续时间 2. 硬件设计 本实验通过TIM5的通道1输入
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved