STM32学习笔记之定时器输入捕获实验

发布者:NexusDream最新更新时间:2018-04-15 来源: eefocus关键字:STM32  定时器输入  捕获实验 手机看文章 扫描二维码
随时随地手机看文章

实验目的:

在串口调试助手上打印出按键按下的时间


实验步骤:





实验程序:

  1. /*******************************timer.c********************************/  

  2. #include "sys.h"  

  3. #include "stm32f4xx.h"  

  4.   

  5.   

  6. extern u8 TIM5CHA1_CAPTURE_STA;  

  7. extern u16  TIM5CHA1_CAPTURE_VAL;  

  8.   

  9.   

  10. /* 

  11. 本示例的作用就是, 

  12. 当按键按下时,每次输入捕获的时间差, 

  13. 然后从串口调试助手中打印出其时间差; 

  14. */  

  15.   

  16.   

  17. /* 

  18. 关于输入捕获的操作可参考寄存器版的步骤 

  19. */  

  20.   

  21.   

  22. /* 

  23. 定时器输入捕获的初始化函数: 

  24. 主要是关于寄存器的相关配置 

  25. */  

  26.   

  27.   

  28. /*初始化定时器5为输入捕获*/  

  29. void TIM5_Init(void){  

  30.       

  31.     /************************* 

  32.     定时器输入捕获的设置:  

  33.     *************************/  

  34.       

  35.     /*将按键KEY_UP复用*/  

  36.     /*1.使能GPIO端口时钟*/  

  37.     RCC->AHB1ENR |= 1;  

  38.     /*这里还需要将其配置成下拉, 

  39.     因为在输入捕获中,将通过上升沿来触发; 

  40.     */  

  41.     GPIOA->PUPDR |= 0X2;  

  42.       

  43.     /*2.使能复用外设时钟*/  

  44.     RCC->APB1ENR |= 1<<3;  

  45.       

  46.     /*3.端口模式配置为复用功能*/  

  47.     GPIOA->MODER |= 0X2;  

  48.       

  49.     /*4.配置GPIOx_AFRL或者GPIOx_AFRH寄存器, 

  50.     将IO连接到所需的复用外设*/  

  51.     GPIOA->AFR[0] |= 0X2;  

  52.       

  53.       

  54.       

  55.     /*设置定时器5的输入捕获*/  

  56.       

  57.     //设置TIM5的分频和自动重装  

  58.     TIM5->PSC = 84-1;  

  59.     TIM5->ARR = 0XFFFF-1;   //芯片手册上写着是16位,  

  60.                               

  61.     //设置滤波/映射/分频  

  62.     TIM5->CCMR1 |= 0X1;  

  63.       

  64.       

  65.     //设置上升沿触发并使能捕获  

  66.     TIM5->CCER |= 0X1;  

  67.       

  68.     //使能更新中断和使能捕获中断  

  69.     TIM5->DIER |= 0X3;  

  70.       

  71.     //使能计数器  

  72.     TIM5->CR1 |= 1;  

  73.       

  74.       

  75.     //设置中断优先级  

  76.     SCB->AIRCR |= 0x5 << 8; //设置分组  

  77.     NVIC->IP[50] |= 0; //设置优先级,具体可分析MY_NVIC_Init()函数;  

  78.       

  79.     //只要涉及中断,最后一定记得使能中断;  

  80.     //若不使能,则中断不会发生  

  81.     NVIC->ISER[1] |= 1<<18;  //使能中断;  

  82.       

  83. }  

  84.   

  85.   

  86.   

  87. /*每次在按键按下时,输入捕获按键, 

  88. 然后每产生两次中断,就在在中断里边 

  89. 算出两次捕获之间的时间差; 

  90. */  

  91. void TIM5_IRQHandler(void){  

  92.       

  93.     /* 

  94.     中断处理函数: 

  95.     */  

  96.       

  97.       

  98.     if((TIM5CHA1_CAPTURE_STA & 0x80) != 0x80){  //说明一次完整的输入捕获还没有结束;  

  99.           

  100.           

  101.           

  102.         if((TIM5->SR & 0X1) == 0X1){  //说明是溢出标志发生  

  103.               

  104.               

  105.             if((TIM5CHA1_CAPTURE_STA & 0x40) == 0x40){  //只有捕获到高电平之后,  

  106.                                                         //我们才累计计数计数器的值  

  107.                 if((TIM5CHA1_CAPTURE_STA & 0x3f)==0x3f){  //说明能累计的计数器已满;  

  108.                                                         //在这里,高电平持续的时间最多为4s  

  109.                     TIM5CHA1_CAPTURE_STA |= 0x80;  

  110.                     TIM5CHA1_CAPTURE_VAL = 0xffff;  

  111.                       

  112.                       

  113.                 }else{  

  114.                   

  115.                     TIM5CHA1_CAPTURE_STA++;  

  116.                 }  

  117.                   

  118.                   

  119.             }  

  120.               

  121.         }  

  122.         if((TIM5->SR & 0X2) == 0X2){  //说明上升沿或下降沿已捕获  

  123.               

  124.               

  125.             if((TIM5CHA1_CAPTURE_STA & 0x40) == 0x40){   //说明下降沿已触发  

  126.                   

  127.                 TIM5CHA1_CAPTURE_STA |= 0x80 ; //说明上升沿和下降沿一个周期的捕获已完成 ;  

  128.                 TIM5CHA1_CAPTURE_VAL = TIM5->CCR1;//保存发生下降沿触发时计数器的值;  

  129.           

  130.                 //设置上升沿触发并使能捕获  

  131.                 TIM5->CCER &= ~(1<<1);  

  132.                   

  133.             }else{     //说明上升沿已捕获  

  134.                   

  135.                 //禁止定时器5的计数器  

  136.                 TIM5->CR1 &= ~(1);  

  137.                   

  138.                 //让计数器的值为0,以便计算从0到下一次下降沿捕获的值之间的计算;  

  139.                 TIM5->CNT = 0;  

  140.                   

  141.                 //设置输入捕获为下降沿触发  

  142.                 TIM5->CCER &= ~(0XF);  

  143.                 TIM5->CCER |= 0X3;  

  144.                   

  145.                 //初始化要计数的值;  

  146.                 TIM5CHA1_CAPTURE_STA = 0;  

  147.                 TIM5CHA1_CAPTURE_STA |= 0X40;  

  148.                 TIM5CHA1_CAPTURE_VAL = 0;  

  149.                   

  150.                 //使能计数器  

  151.                 TIM5->CR1 |= 1;  

  152.               

  153.             }  

  154.               

  155.         }  

  156.           

  157.     }  

  158.       

  159.     /* 

  160.     在中断里边最后记得清中断标志: 

  161.     */  

  162.     TIM5->SR &= ~(0x3);  

  163. }   


  1. /*******************************timer.h*********************************/  

  2. #ifndef _EXTI_H  

  3. #define _EXTI_H  

  4.   

  5.   

  6. void TIM5_Init(void);  

  7.   

  8.   

  9. #endif  



  1. /*******************************test.c***********************************/  

  2. #include "sys.h"  

  3. #include "delay.h"  

  4. #include "beep.h"  

  5. #include "exti.h"  

  6. #include "led.h"  

  7. #include "uart.h"  

  8. #include "usart.h"  

  9.   

  10.   

  11.   

  12. u8 TIM5CHA1_CAPTURE_STA;  

  13. u32  TIM5CHA1_CAPTURE_VAL;  

  14.   

  15.   

  16. int main(void){  

  17.       

  18.     u8 i = 0;  

  19.     long long  temp = 0;  //这里的值比较大,所以选择long long  

  20.       

  21.     Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz    

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

  23.     LED_Init();  

  24.     Beep_Init();  

  25.     TIM5_Init();  

  26.     UART_Init();  

  27.       

  28.       

  29.     while(1){  

  30.           

  31.         PFout(9) = 0;  

  32.         delay_ms(500);  

  33.         PFout(9) = 1;  

  34.         delay_ms(500);  

  35.           

  36.         if((TIM5CHA1_CAPTURE_STA & 0x80) == 0x80){  //若一个完整的捕获周期(上升沿和下降沿)  

  37.   

  38.   

  39.             i = TIM5CHA1_CAPTURE_STA & 0x3f;  

  40.             printf("TIM5:%d\r\n",i);  

  41.             //计算累计的时间(高电平到低电平的之间的时间差)    

  42.             temp = (TIM5CHA1_CAPTURE_STA & 0x3f)*0xffff;  

  43.             temp += TIM5CHA1_CAPTURE_VAL;  

  44.   

  45.               

  46.             printf("temp:%lld us\r\n",temp);  //思考printf()函数是如何做的;  

  47.                   

  48.                 //重新初始化  

  49.                 TIM5CHA1_CAPTURE_STA = 0;  

  50.                 TIM5CHA1_CAPTURE_VAL = 0;  

  51.   

  52.         }  

  53.               

  54.     }  

  55. }  





实验分析:

1.定时器的框图及输入捕获框图的放大版



注:通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,

将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。


2.输入捕获的工作流程分析:

<1>


<2>


<3>


<4>


<5>



3.中断处理函数部分的提示



注意事项:

1.只要涉及到中断,在最后一定都要记得使能中断

2.按键那块,处理不是很好,有时会一连打出好几串数字;

更准确的说是按键有时会有些抖动,就相当于按了好几下,但没有滤掉波段较小的那一部分;


关键字:STM32  定时器输入  捕获实验 引用地址:STM32学习笔记之定时器输入捕获实验

上一篇:STM32学习笔记之__attribute__ ((at())绝对定位分析
下一篇:STM32的输入捕获

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

STM32 外部中断 易出错总结
前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark。 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发; 二:外部中断分组 STM32 的每一个GPIO都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。 STM32 分组和对应中断处理函数分配: 管脚 中断标志
[单片机]
STM32中的ADC有什么功能?
ADC简介 STM32F103系列有3个ADC,精度为12位,每个ADC最多有16个外部通道。其中ADC1和ADC2都有16个外部通道,ADC3一般有8个外部通道,各通道的A/D转换可以单次、连续、扫描或间断执行,ADC转换的结果可以左对齐或右对齐储存在16位数据寄存器中。ADC的输入时钟不得超过14MHz,其时钟频率由PCLK2分频产生。 ADC功能框图讲解 学习STM32开发板上的外设时首先要了解其外设的功能框图,如下: 功能框图可以大体分为7部分,下面一一讲解: 电压输入范围 ADC所能测量的电压范围就是VREF- ≤ VIN ≤ VREF+,把 VSSA 和 VREF-接地,把 VREF+和 VDDA 接 3V3,
[单片机]
<font color='red'>STM32</font>中的ADC有什么功能?
STM32独立看门狗IWDG与窗口看门狗WWDG研究
1.看门狗介绍 看门狗这东西虽然简单,但我相信绝大多程序员没有足够重视它。使用看门狗保证系统正常地运行是非常有必要的。我们在设计产品时,代码以及硬件设计缺陷或是外界电磁干扰都有可能使系统死机,如果不能正常对其进行复位,系统的可靠性将大打折扣。看门狗分为软件看门狗和硬件看门狗两类,其原理都是使用一个独立定时器来计时,超出时间就会产生复位信号,主要区别看是否具有独立的硬件结构,如果有,就是硬件看门狗,如果是一个普通定时器实现的那么就是软件看门狗。STM32F407片内有两个看门狗:独立看门狗IWDG以及窗口看门狗WWDG,下面来讨论各自的特点和用法。 2.IWDG的特点以及使用 IWDG是一个独立看门狗,具有独立于系统的时钟,与片
[单片机]
基于stm32的HC-SR04超声波测距模块使用
1 工作原理 使用超声波模块之前,先了解其IO口和工作原理: 1.1 IO说明 VCC: 供5V电源 GND: 为地线 TRIG: 触发控制信号输入 ECHO: 回响信号输出 1.2 基本工作原理: 认真看好以下工作原理,后面的代码就是基于工作原理来实现的。 (1)采用IO口TRIG触发测距,给最少10us的高电平信号。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2 时序图: 2 程序编写 2.1 外设配置 根据两个信号引脚来配置两个单片机的IO口
[单片机]
基于<font color='red'>stm32</font>的HC-SR04超声波测距模块使用
STM32精确延时函数
#include stm32f10x_systick.h //使用SysTick的普通计数模式对延迟进行管理 //包括delay_us,delay_ms //修正了中断中调用出现死循环的错误 //防止延时不准确,采用do while结构! static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数 //初始化延迟函数 void delay_init(u8 SYSCLK) // 系统时钟是72M 即SYSCLK 取72 ,其他类推 { SysTick- CTRL&=0xfffffffb;//选择内部时
[单片机]
stm32 外部中断库函数实现全程分析
前题:   闭门造车,两周了,经过各种的思考和求问,反复阅读了 M3权威指南 和 stm32不完全手册 的相关章节,以及开发板厂商的实验例程,对stm32这块中断终有所悟,是以记之。   至于中断的什么优先级,什么优先级分组,使能之类的原理,就不再赘述。这里主要是记载以下如何使用中断,以及中断配置函数的实现过程,其中并叙述我曾经的疑惑和感悟。   我的开发板里的中断例程是用按键控制一个灯亮和灭的两个状态。   这个例程的实现过程如下描述: 第一步,将一个I/O口配置成中断输入模式。      这里需要注意的是,GPIO本身是没有中断功能神马的。如果硬要使他产生中断输入方式,就得将相应的端口映射到相应的外部事件上去。而
[单片机]
<font color='red'>stm32</font> 外部中断库函数实现全程分析
stm32 系统时钟配置
HSE:72M,HSE:64M,HSI:64M 代码实现: // 时钟设置 //#define MAINCLOCK_72M // HSE,外部时钟 //#define MAINCLOCK_64M_EXTERN // HSE #define MAINCLOCK_64M_INTERAL // HSI /** System Clock Configuration */ void SystemClock_Config(void) { RCC_OSCInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; /**Init
[单片机]
STM32电机矢量控制】记录9——状态观测器与锁相环
状态观测器: 理论依据:根据控制理论,如果一个系统能够完全通过其检测到的输出值来重构其系统状态,则认为该系统是可观测的。其作用于无传感器转子的位置和速度的检测反馈,再作用到PARK变换和转矩磁链控制上。 Luenberger观测器的离散化: (其观测器的闭环参数为经验验证值) 引入估测电流( iα,iβ )的反馈值并离散化(T 为采样时间),可得当前的反向电动势 eα 和eβ; 再由反向电动势 eα 和eβ 的计算出转子的位置角。 可以将其定义式相除,可得到转子位置角,但是这方法是开环的,对耦合在反电动势里的干扰非常敏感,它会使反电动势成为非正弦信号) 程序中使用的是锁相环方式,以PI闭环方式调节ωr以保持其输入为0 (电角度领先
[单片机]
【<font color='red'>STM32</font>电机矢量控制】记录9——状态观测器与锁相环
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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