STM32f4输入捕获实验代码

发布者:Jinyu521最新更新时间:2018-10-05 来源: eefocus关键字:STM32f4  输入捕获 手机看文章 扫描二维码
随时随地手机看文章

我们来看看 timer.c文件中,我们添加的两个函数的内容:

TIM_ICInitTypeDef  TIM5_ICInitStructure;

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

//arr:自动重装值(TIM2,TIM5 是 32位的!!)        psc:时钟预分频数

void TIM5_CH1_Cap_Init(u32 arr,u16 psc)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

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

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //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_PinSource0,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_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端  IC1 映射到TI1上

     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); //初始化 TIM5输入捕获参数

    

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

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

 

       NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;

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

  NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//响应优先级0

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

  NVIC_Init(&NVIC_InitStructure);  //根据指定的参数初始化VIC 寄存器、

}

//捕获状态

//[7]:0,没有成功的捕获;1,成功捕获到一次.

//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.

//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)

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

u32  TIM5CH1_CAPTURE_VAL;  //输入捕获值(TIM2/TIM5是 32位)

//定时器 5中断服务程序    

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=0XFFFFFFFF;

        }else TIM5CH1_CAPTURE_STA++;

      }    

    }

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

    {  

      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;

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

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

           TIM_SetCounter(TIM5,0); //计数器清空

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

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

      }         

    }                                 

    }

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

}

此部分代码包含两个函数,其中TIM5_CH1_Cap_Init函数用于 TIM5通道 1的输入捕获设置,其设置和我们上面讲的步骤是一样的,这里就不多说,特别注意:TIM5 是 32 位定时器,所以 arr是u32 类型的。接下来,重点来看看第二个函数。

TIM5_IRQHandler 是 TIM5 的中断服务函数,该函数用到了两个全局变量,用于辅助实现高电平捕获。其中TIM5CH1_CAPTURE_STA,是用来记录捕获状态,该变量类似我们在usart.c里面自行定义的USART_RX_STA 寄存器(其实就是个变量,只是我们把它当成一个寄存器那样来使用)。TIM5CH1_CAPTURE_STA各位描述如表15.3.1所示:

TIM5CH1_CAPTURE_STA

bit7  bit6  bit5~0

捕获完成标志  捕获到高电平标志  捕获高电平后定时器溢出的次数

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

  这样,我们就完成一次高电平捕获了,只要TIM5CH1_CAPTURE_STA的第7位一直为1,那么就不会进行第二次捕获,我们在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA置零,就可以开启第二次捕获。

  timer.h头文件内容比较简单,主要是函数申明,这里我们不做过多讲解。   

接下来,我们看看main函数内容

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

extern u32  TIM5CH1_CAPTURE_VAL;  //输入捕获值   

int main(void)

{  

  long long temp=0;   

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

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

  uart_init(115200);//初始化串口波特率为115200

    TIM14_PWM_Init(500-1,84-1);  

//84M/84=1Mhz的计数频率计数到500,频率为1M/500=2Khz      

    TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);//以 84M/84=1Mhz的频率计数  

      while(1)

  {    delay_ms(10);

    TIM_SetCompare1(TIM14,TIM_GetCapture1(TIM14)+1);  

    if(TIM_GetCapture1(TIM14)==300)TIM_SetCompare1(TIM14,0);        

      if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平

    {

      temp=TIM5CH1_CAPTURE_STA&0X3F;  

      temp*=0XFFFFFFFF;          //溢出时间总和

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

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

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

    }

  }

}

该 main 函数是在 PWM 实验的基础上修改来的,我们保留了 PWM 输出,同时通过设置TIM5_Cap_Init(0XFFFFFFFF,84-1),将 TIM5_CH1 的捕获计数器设计为 1us 计数一次,并设置重装载值为最大以达到不让定时器溢出的作用(溢出时间为 232-1 us),所以我们的捕获时间精度为 1us。主函数通过 TIM5CH1_CAPTURE_STA 的第 7 位,来判断有没有成功捕获到一次高电平,如果成功捕获,则将高电平时间通过串口输出到电脑。至此,我们的软件设计就完成了。


关键字:STM32f4  输入捕获 引用地址:STM32f4输入捕获实验代码

上一篇:STM32f4电容触摸按键实验代码(02)
下一篇:STM32f4 PWM输出实验代码

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

STM32F4学习笔记13——ADC part1
ADC 简介 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。 ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。 ADC 主要特性 ● 可配置 12 位、10 位、8 位或 6 位分辨率 ● 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断 ● 单次和连续转换模式 ● 用于自动将通道 0 转换为通道“n”的扫描模式 ● 数据对齐以保持内置数据一致性 ●
[单片机]
<font color='red'>STM32F4</font>学习笔记13——ADC part1
STM32F429 >> 19. RTC_实时时钟
简介 RTC—Eeal Time Clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个 32bit 的时间寄存器,可直接输出时分秒,星期、月、日、年。 功能框图 1. 时钟源 RTC 时钟源 —RTCCLK 可以从 LSE、LSI 和 HSE_RTC 这三者中得到。其中使用最多的是 LSE。 LSE 由一个外部的 32.768KHZ(6PF 负载)的晶振提供,精度高,稳定,RTC首选; LSI 是芯片内部的 30KHZ 晶体,精度较低,会有温漂,一般不建议使用; HSE_RTC由 HSE 分频得到,最高是 4M,使用的也较少。 2. 预分频器 预分频
[单片机]
<font color='red'>STM32F4</font>29 >> 19. RTC_实时时钟
STM32F4】读取芯片ID和芯片Flash Size
首先声明,手册上给出的FlashSize地址是错误的,正确的应该是0x1FFF7A20,取高16位。确切说应该是(0x1FFF7A23,0x1FFF7A22两个字节), 芯片的这96位ID是产品唯一身份标识。可以从特定的寄存器中读出来。FlashSize表示内部flash的大小,也是固化在芯片内部的。 手册上讲的ChipID的基地址是0x1FFF7A10,ChipSize的基地址也是0x1FFF7A10。肯定是不对的 谷歌了半天才发现真正的ChipSize地址0x1FFF7A20。知道了地址,直接读取地址中的数据就OK了。操作相当简单 读取FlashSize uint16_t cpuGetFlashSize(void) { r
[单片机]
【<font color='red'>STM32F4</font>】读取芯片ID和芯片Flash Size
STM32F4_引领入门
Ⅰ、概述 该文写给那些想学ST芯片开发(或初级学习)的朋友,文章着重细节,或许有点简单。 笔者想告诉那些刚开始学习ST的朋友,不管你使用哪一个系列(F0、F1、F2),哪一种型号芯片,其实学习的方法和原理都是差不多的。或许不同系列,不同型号的芯片,它们之间确实存在一定的差异,但万变不离其宗,设计芯片的厂家都是按照常理(而且是人们习惯性的思维)来设计芯片,及其开发原理。 笔者在这里告诉大家吧,ST的芯片不管是硬件(引脚),还是软件(寄存器、库等)它们的兼容性都是很好的,有可能不同系列,不同型号的芯片,硬件换了,软件不换,可以达到同样的效果(笔者已经尝试过的,如:STM32F205VC和STM32F417VE,除了明显一点的速度有
[单片机]
<font color='red'>STM32F4</font>_引领入门
STM32F407-外部中断
一.基本概念 STM32F4的每个IO都可以作为外部中断输入。 STM32F4的中断控制器支持22个外部中断/事件请求: EXTI线0~15:对应外部IO口的输入中断。 EXTI线16:连接到PVD输出。 EXTI线17:连接到RTC闹钟事件。 EXTI线18:连接到USB OTG FS唤醒事件。 EXTI线19:连接到以太网唤醒事件。 EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。 EXTI线21:连接到RTC入侵和时间戳事件。 EXTI线22:连接到RTC唤醒事件。 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。
[单片机]
<font color='red'>STM32F4</font>07-外部中断
STM32输入捕获模式设置并用DMA接收数据
参考: STM32的PWM输入模式设置并用DMA接收数据 Input capture mode The input stage samples the corresponding TIx input to generate a filtered signal TIxF. Then, an edge detector with polarity selection generates a signal (TIxFPx) which can be used as trigger input by the slave mode controller or as the capture command. It is presca
[单片机]
STM32<font color='red'>输入</font><font color='red'>捕获</font>模式设置并用DMA接收数据
stm32输入捕获捕获高电平
输入捕获就是用定时器检测引脚上的电平时间,可以检测高电平时间和低电平时间,然后可以算引脚上信号的频率和占空比。 基本思路就是利用定时器的输入捕获功能。 定时器捕获到高电平或低电平就会进入捕获中断 例如: 我们要捕获高电平时间 0 设置定时器计数频率和装载值,一般设置1MHz,65535 1 设置定时器捕获为高电平捕获 2 进入捕获中断后,获取CNT计数值或CCRx值,定时器捕获到电平后会把CNT的值保存到CCRx。 设置成低电平捕获。 3 再次进入捕获中断,获取CNT计数值-上次的CNT值=总高电平时间。 设置成高电平捕获。 4 重复2-3即可完成下一次捕获。当然还要考虑溢出的情况,
[单片机]
stm32<font color='red'>输入</font><font color='red'>捕获</font>,<font color='red'>捕获</font>高电平
STM32F407高速USB口速度测试
STM32F407高速USB口速度测试 1, 高速USB口,直接接USB3.0 U盘,金士顿DataTraveler G4,16G。读写文件长度3226157571字节。XP32系统。固件使用HS Device下的DualCore。 l 文件拷贝到U盘,用时3分钟。平均速度17.9MB/s=143Mbit/s l 从U盘拷出,用时2分钟。平均速度26.9MB/s=215Mbit/s l 文件从C盘拷贝,粘贴,用时2分钟。 可以看出,此时读写U盘已经是最大速度,这跟整个系统、U盘都有关系。USB操作应该没有经过MCU处理,直接用的USB缓冲区。 2, 高速USB口,连SD卡(大卡)
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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