历史上的今天
返回首页

历史上的今天

今天是:2025年04月15日(星期二)

正在发生

2018年04月15日 | STM32学习笔记之定时器输入捕获实验

2018-04-15 来源:eefocus

实验目的:

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


实验步骤:





实验程序:

  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.按键那块,处理不是很好,有时会一连打出好几串数字;

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


推荐阅读

史海拾趣

Daito Communication Apparatus Co Ltd公司的发展小趣事

随着微电子学的快速发展,电子设备对元器件的要求也越来越高。Daito公司敏锐地捕捉到了这一市场趋势,决定对保险丝进行进一步的创新。在1995年,他们成功开发出了适用于电路板安装的高精度小型报警保险丝。这一产品的推出,不仅满足了市场对小型化、高精度保险丝的需求,也进一步巩固了Daito公司在电子行业中的领先地位。

随后,Daito公司又针对微电子学的进一步发展,推出了可以连续自动安装的方形微型保险丝。这一产品的推出,大大提高了生产效率,降低了成本,同时也为客户提供了更加便捷的使用体验。近年来,随着面安装技术的兴起,Daito公司又迅速推出了适用于面安装技术的片状保险丝,再次展示了他们在电子行业中的创新实力。

请注意,由于篇幅限制,以上仅为两个故事示例。如果需要更多故事,可以进一步深入研究和探索Daito公司在电子行业中的发展历程和创新实践。

APEM公司的发展小趣事

随着公司规模的扩大,APEM开始实施国际化发展战略。1975年,APEM在欧洲创建了首家附属公司,随后又在英国、突尼斯、比利时、荷兰和卢森堡等地成立分公司。这些举措不仅扩大了APEM的市场份额,也提升了其在国际市场的知名度。

Display Elektronik GmbH公司的发展小趣事

随着环保意识的日益增强,Display Elektronik GmbH将绿色环保理念融入到了公司的发展中。公司采用环保材料和生产工艺,减少了对环境的污染。同时,Display Elektronik GmbH还积极推广绿色显示技术,为客户提供更加环保、节能的显示解决方案。这种对环保的关注和投入,让Display Elektronik GmbH在行业中树立了良好的形象。

D3公司的发展小趣事

面对全球电子市场的巨大潜力,D3公司积极实施全球化战略。公司不仅在国内市场深耕细作,还积极拓展海外市场。通过与国外知名企业的合作,D3公司的产品逐渐进入国际市场,并在多个国家和地区取得了良好的销售业绩。同时,公司还加强了对海外市场的调研和分析,以更好地满足当地消费者的需求。这种全球化战略的实施,为D3公司的长远发展奠定了坚实的基础。

HEC Inc公司的发展小趣事

D3公司始终将产品质量放在首位。公司建立了严格的质量管理体系,从原材料采购到产品生产、检验,每一个环节都严格把控。这种对品质的执着追求,使得D3公司的产品在市场上赢得了良好的口碑。同时,公司还注重售后服务,为消费者提供全方位的支持和保障。这种以品质为核心的发展策略,让D3公司在电子行业中树立了良好的品牌形象。

Alpha Industries公司的发展小趣事

随着电子技术的飞速发展,军事装备也在不断升级。Alpha Industries敏锐地捕捉到了这一趋势,开始将电子技术应用于其军事服装设计中。例如,公司研发了一款带有GPS定位功能的飞行夹克,帮助飞行员在复杂环境中快速定位。此外,Alpha Industries还利用电子传感器技术,开发出能够监测士兵体温和心率的战地风衣,为军队提供更为全面的保障。

问答坊 | AI 解惑

电子竞赛的各类题目

本帖最后由 paulhyde 于 2014-9-15 09:10 编辑 这是各类题目的报告,很有用的,,要好好用哦  …

查看全部问答>

合众达dsp2812的烧写程序

我们用的是ccsv2版本 ,打算烧写dsp2812的程序,但是一直在合众达光盘里面没有找到烧写的插件啊 不知道是否可以提供? 只找到了帮助手册:…

查看全部问答>

光强传感器资料

那位大侠有元器件的的好网站啊,推荐一个,想找找这方面的资料。。。。。 谢谢…

查看全部问答>

蓄电池刚发明时,蓄电池的充电方式是什么?

在写一篇小论文,突然想到这个,不大清楚,望高手说一下~~谢谢了先!!…

查看全部问答>

音箱?储钱罐??

上面图里的小东西是音箱,还是储钱罐?如果真这么简单,岂不是枉费我大过节的敲了这么多字? 不卖关子,直接揭迷底,这是一个不需要任何按钮的MP3播放器,通过“动作”控制。 这年头,如果说自己的MP3播放器花XX钱是买来的,已经不会带来 ...…

查看全部问答>

nV/√Hz是什么意思?

信号频率如何测量 还有有个噪声的单位nV/√Hz是什么意思呢?…

查看全部问答>

wince下,如何修改菜单栏的高度啊?

wince系统下,在注册表里修改了菜单栏里的字体,但是菜单栏的高度不知如何修改,文字只显示了一半。请问,如何修改菜单栏的高度啊???…

查看全部问答>

lpc2106外部中断问题

在《ARM微控制器基础与实践》一书中,当讲到外部中断标志寄存器EXTINT时,其中有几句话我实在不能理解。请各位高手进来帮我看看。此话如下:    “ 当外部中断EINT0引脚变为低电平并且EINT0映射到它相关的引脚时,该位置位。当对应引脚 ...…

查看全部问答>

共同开发,共同投资,共同收获

市场前景广阔之项目,要求合作者精通嵌入式开发,USB接口编程(PC端+设备端),能进行网站设计更好。必须投入部分资金,风险共担。 有益者联系:QQ6669231…

查看全部问答>

请大家帮忙找找一个做字库的工具

现在我遇到一个难题,问题在于客户需要在我的项目中加韩语,方案的接口给出了定义,但需要先将一个turetype font(.ttf)文件使用他们给出的bin2c转成.c文件。 现在问题是如果我直接拿下载回来的turetype font(.ttf)字库的话,那太大了,flash不够, ...…

查看全部问答>