STM32的输入捕获

发布者:平安心境最新更新时间: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. }   

  164. /*******************************timer.h*********************************/  

  165. #ifndef _EXTI_H  

  166. #define _EXTI_H  

  167.   

  168.   

  169. void TIM5_Init(void);  

  170.   

  171.   

  172. #endif  

  173. /*******************************test.c***********************************/  

  174. #include "sys.h"  

  175. #include "delay.h"  

  176. #include "beep.h"  

  177. #include "exti.h"  

  178. #include "led.h"  

  179. #include "uart.h"  

  180. #include "usart.h"  

  181.   

  182.   

  183.   

  184. u8 TIM5CHA1_CAPTURE_STA;  

  185. u32  TIM5CHA1_CAPTURE_VAL;  

  186.   

  187.   

  188. int main(void){  

  189.       

  190.     u8 i = 0;  

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

  192.       

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

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

  195.     LED_Init();  

  196.     Beep_Init();  

  197.     TIM5_Init();  

  198.     UART_Init();  

  199.       

  200.       

  201.     while(1){  

  202.           

  203.         PFout(9) = 0;  

  204.         delay_ms(500);  

  205.         PFout(9) = 1;  

  206.         delay_ms(500);  

  207.           

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

  209.   

  210.   

  211.             i = TIM5CHA1_CAPTURE_STA & 0x3f;  

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

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

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

  215.             temp += TIM5CHA1_CAPTURE_VAL;  

  216.   

  217.               

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

  219.                   

  220.                 //重新初始化  

  221.                 TIM5CHA1_CAPTURE_STA = 0;  

  222.                 TIM5CHA1_CAPTURE_VAL = 0;  

  223.   

  224.         }  

  225.               

  226.     }  

  227. }  





实验分析:

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



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

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


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

<1>


<2>


<3>


<4>


<5>



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



注意事项:

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

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

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


关键字:STM32  输入捕获 引用地址:STM32的输入捕获

上一篇:STM32学习笔记之定时器输入捕获实验
下一篇:STM32的定时器中断

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

STM32入门系列-创建寄存器模板
介绍如何使用 KEIL5 软件创建寄存器模板, 方便之后使用寄存器方式来操作STM32开发板上的LED,让大家创建属于自己的寄存器工程模板。 获取工程模板的基础文件 首先我们在电脑任意位置创建一个文件夹,命名为“寄存器模板创建”,然后在其下面新建 2 个文件夹,如下: Obj 文件夹: 用于存放编译产生的 c/汇编/链接的列表清单、 调试信息、hex文件、预览信息、封装库等文件。 User 文件夹: 用于存放用户编写的 main.c、 STM32F1 启动文件、stm32f10x.h头文件。 我们需要将寄存器工程模板所需的基础文件 main.c、STM32F1 启动文件及stm32f10x.h 头文件放入到
[单片机]
<font color='red'>STM32</font>入门系列-创建寄存器模板
stm32编译出问题解决
.FWlibincstm32f10x_conf.h(33): warning: #14-D: extra text after expected end of preprocessing directive 额外的文本在在预处理命令后面出现 #include stm32f10x_dma.h */ 出问题的地方就是这个 */ 仿照原子自己建立工程的时候出现的问题修改: 问题及修改: 1)..SYSTEMdelaydelay.c(27): error: #20: identifier SysTick_CLKSource_HCLK_Div8 is undefined 解决方法:在delay.c中添加
[单片机]
STM32的AFIO口简介
1、STM32上有很多I/O口,也有很多的内置外设I2C,ADC,ISP,USART ,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。 2、为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其它引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上。 3、只有使用了AFIO的事件控制寄存器、AFIO的重映射功能以及外部中断(EXTI)控制寄存器才需要开启AFIO的时钟。
[单片机]
STM32学习笔记一时钟和定时器
由于近期在准备海洋航行器比赛,正好趁此机会学习一下ARM,看到周围很多同学都在使用32,所以我也买了一块STM32F103ZET6,准备好好地学习一下。 STM32的时钟系统相当的复杂,包含了5个时钟源,分别是HSI HSE LSI LSE PLL,HSI是高速内部时钟、RC振荡器,频率为8M,HSE是高速外部时钟,即晶振,我的核心板上晶振为8M。LSI为低速内部时钟、RC振荡器,频率40k,LSE为低速外部时钟,接32.768kHz晶振,作为RTC时钟源。PLL为锁相环倍频输出,最大不超过72M。 我在学习定时器时先看的是TIM3,它挂载在APB1分频器上,APB1上面挂载的是低速外设,APB2上挂载高速外设。 在
[单片机]
吐槽51与STM32
接触STM32之后,有种相见恨晚的强烈感觉。51在属于他的那个年代,不可否认他在嵌入式领域的丰功伟绩。但今天,这里的战场不属于51,。要不是因为伟大的中国教育机构总能 跟上时代的步伐 ,51真应该出现在博物馆。 如果你用过51,我保证你只要你和STM32擦肩而过,你会深深爱上这家伙,一发不可收拾,真的。 硬件。 速度上。51与STM32的区别就是牛拉车与法拉利的区别,这个说得够明显了,你懂的。51来个12M就算是一种奢侈了,代码量稍稍大一点,就来不起,让你不得优化这里优化哪里;说真的,51这家伙总喜欢给工程师们绕裹脚。STM32,知道有多HAPPY,动不动就是72M、100M,代码跑的如此开心、如此欢
[单片机]
STM32笔记(一)---串口ISP模式下载原理
-------------------------- –串口ISP模式下载原理– -------------------------- 先放几张火哥的教程截图: 图1 图2 图3 图4 通过图1可以了解到,不同的下载方式中所需要的不同启动模式: 在项目实际应用中的Boot设置: 默认使用程序代码存储在主闪存存储器,配置方式:BOOT0=0,BOOT1=0,但是要预留boot0上拉电阻工位,便于将其电平拉高,实现串口烧录。 如图3所示,只需要通过改变RTS电位使S8550是否导通,导通时实现图2的电路效果将Boot0拉高,否则Boot0为低电位。 一旦完成Boot0与Boot1的10设置后,需要
[单片机]
<font color='red'>STM32</font>笔记(一)---串口ISP模式下载原理
STM32串口通信乱码详细处理方法
STM32串口通信以及温度采集搞定,其中主要遇到STM32系列单片机时钟树的问题,串口通信遇到串口调试助手能够接收到数据但出现乱码现象,开始一直以为是串口配置和程序代码问题,因为是第一次上电在线调试STM32板子,后面主要查串口波特率配置和收发函数程序段,如下图: 波特率设置成115200没问题,试着降低波特率改成9600和4800但问题依旧没有解决,紧接着如下处理: 将重定向函数注释,单独写串口发送字节和字符串函数,依旧失败。最后锁定到系统时钟配置上,由于手上的STM32开发板改用了12M的晶振,根据单片机时钟树的理解和解读,一般采用外部时钟HSE,系统时钟配置成72M,8*9=72,,12*6=72,对于 SYSCLK、
[单片机]
基于STM32内置ADC实现简易示波器的程序设计与实现
  做一个数字采样示波器一直是我长久以来的愿望,不过毕竟这个目标难度比较大,涉及的方面实在太多,模拟前端电路、高速ADC、单片机、CPLD/FPGA、通讯、上位机程序、数据处理等等,不是一下子就能成的,慢慢一步步来呗,呵呵,好歹有个目标,一直在学习各方面的知识,也有动力:)由于高速ADC涉及到采样后的数据存储问题,大量的数据涌入使得单片机无法承受,因此通常需要用外部高速RAM加CPLD配合,或者干脆用大容量的 FPGA做数据存储处理等,然后通知单片机将数据发送出去。这部分实在是难度比较大,电路非常复杂,自己是有心无力啊,还得慢慢地技术积累。。。   正好ST新推出市场的以CORTEX-M3为核心的STM32,内部集成了2个1M
[测试测量]
基于<font color='red'>STM32</font>内置ADC实现简易示波器的程序设计与实现
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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