STM32的输入捕获

实验目的:

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


实验步骤:





实验程序:


 
 
  1. /*******************************timer.c********************************/
  2. #include "sys.h"
  3. #include "stm32f4xx.h"
  4. extern u8 TIM5CHA1_CAPTURE_STA;
  5. extern u16 TIM5CHA1_CAPTURE_VAL;
  6. /*
  7. 本示例的作用就是,
  8. 当按键按下时,每次输入捕获的时间差,
  9. 然后从串口调试助手中打印出其时间差;
  10. */
  11. /*
  12. 关于输入捕获的操作可参考寄存器版的步骤
  13. */
  14. /*
  15. 定时器输入捕获的初始化函数:
  16. 主要是关于寄存器的相关配置
  17. */
  18. /*初始化定时器5为输入捕获*/
  19. void TIM5_Init(void){
  20. /*************************
  21. 定时器输入捕获的设置:
  22. *************************/
  23. /*将按键KEY_UP复用*/
  24. /*1.使能GPIO端口时钟*/
  25. RCC->AHB1ENR |= 1;
  26. /*这里还需要将其配置成下拉,
  27. 因为在输入捕获中,将通过上升沿来触发;
  28. */
  29. GPIOA->PUPDR |= 0X2;
  30. /*2.使能复用外设时钟*/
  31. RCC->APB1ENR |= 1<< 3;
  32. /*3.端口模式配置为复用功能*/
  33. GPIOA->MODER |= 0X2;
  34. /*4.配置GPIOx_AFRL或者GPIOx_AFRH寄存器,
  35. 将IO连接到所需的复用外设*/
  36. GPIOA->AFR[ 0] |= 0X2;
  37. /*设置定时器5的输入捕获*/
  38. //设置TIM5的分频和自动重装
  39. TIM5->PSC = 84 -1;
  40. TIM5->ARR = 0XFFFF -1; //芯片手册上写着是16位,
  41. //设置滤波/映射/分频
  42. TIM5->CCMR1 |= 0X1;
  43. //设置上升沿触发并使能捕获
  44. TIM5->CCER |= 0X1;
  45. //使能更新中断和使能捕获中断
  46. TIM5->DIER |= 0X3;
  47. //使能计数器
  48. TIM5->CR1 |= 1;
  49. //设置中断优先级
  50. SCB->AIRCR |= 0x5 << 8; //设置分组
  51. NVIC->IP[ 50] |= 0; //设置优先级,具体可分析MY_NVIC_Init()函数;
  52. //只要涉及中断,最后一定记得使能中断;
  53. //若不使能,则中断不会发生
  54. NVIC->ISER[ 1] |= 1<< 18; //使能中断;
  55. }
  56. /*每次在按键按下时,输入捕获按键,
  57. 然后每产生两次中断,就在在中断里边
  58. 算出两次捕获之间的时间差;
  59. */
  60. void TIM5_IRQHandler(void){
  61. /*
  62. 中断处理函数:
  63. */
  64. if((TIM5CHA1_CAPTURE_STA & 0x80) != 0x80){ //说明一次完整的输入捕获还没有结束;
  65. if((TIM5->SR & 0X1) == 0X1){ //说明是溢出标志发生
  66. if((TIM5CHA1_CAPTURE_STA & 0x40) == 0x40){ //只有捕获到高电平之后,
  67. //我们才累计计数计数器的值
  68. if((TIM5CHA1_CAPTURE_STA & 0x3f)== 0x3f){ //说明能累计的计数器已满;
  69. //在这里,高电平持续的时间最多为4s
  70. TIM5CHA1_CAPTURE_STA |= 0x80;
  71. TIM5CHA1_CAPTURE_VAL = 0xffff;
  72. } else{
  73. TIM5CHA1_CAPTURE_STA++;
  74. }
  75. }
  76. }
  77. if((TIM5->SR & 0X2) == 0X2){ //说明上升沿或下降沿已捕获
  78. if((TIM5CHA1_CAPTURE_STA & 0x40) == 0x40){ //说明下降沿已触发
  79. TIM5CHA1_CAPTURE_STA |= 0x80 ; //说明上升沿和下降沿一个周期的捕获已完成 ;
  80. TIM5CHA1_CAPTURE_VAL = TIM5->CCR1; //保存发生下降沿触发时计数器的值;
  81. //设置上升沿触发并使能捕获
  82. TIM5->CCER &= ~( 1<< 1);
  83. } else{ //说明上升沿已捕获
  84. //禁止定时器5的计数器
  85. TIM5->CR1 &= ~( 1);
  86. //让计数器的值为0,以便计算从0到下一次下降沿捕获的值之间的计算;
  87. TIM5->CNT = 0;
  88. //设置输入捕获为下降沿触发
  89. TIM5->CCER &= ~( 0XF);
  90. TIM5->CCER |= 0X3;
  91. //初始化要计数的值;
  92. TIM5CHA1_CAPTURE_STA = 0;
  93. TIM5CHA1_CAPTURE_STA |= 0X40;
  94. TIM5CHA1_CAPTURE_VAL = 0;
  95. //使能计数器
  96. TIM5->CR1 |= 1;
  97. }
  98. }
  99. }
  100. /*
  101. 在中断里边最后记得清中断标志:
  102. */
  103. TIM5->SR &= ~( 0x3);
  104. }



 
 
  1. /*******************************timer.h*********************************/
  2. #ifndef _EXTI_H
  3. #define _EXTI_H
  4. void TIM5_Init(void);
  5. #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. u8 TIM5CHA1_CAPTURE_STA;
  10. u32 TIM5CHA1_CAPTURE_VAL;
  11. int main(void){
  12. u8 i = 0;
  13. long long temp = 0; //这里的值比较大,所以选择long long
  14. Stm32_Clock_Init( 336, 8, 2, 7); //设置时钟,168Mhz
  15. delay_init( 168); //初始化延时函数
  16. LED_Init();
  17. Beep_Init();
  18. TIM5_Init();
  19. UART_Init();
  20. while( 1){
  21. PFout( 9) = 0;
  22. delay_ms( 500);
  23. PFout( 9) = 1;
  24. delay_ms( 500);
  25. if((TIM5CHA1_CAPTURE_STA & 0x80) == 0x80){ //若一个完整的捕获周期(上升沿和下降沿)
  26. i = TIM5CHA1_CAPTURE_STA & 0x3f;
  27. printf( "TIM5:%d\r\n",i);
  28. //计算累计的时间(高电平到低电平的之间的时间差)
  29. temp = (TIM5CHA1_CAPTURE_STA & 0x3f)* 0xffff;
  30. temp += TIM5CHA1_CAPTURE_VAL;
  31. printf( "temp:%lld us\r\n",temp); //思考printf()函数是如何做的;
  32. //重新初始化
  33. TIM5CHA1_CAPTURE_STA = 0;
  34. TIM5CHA1_CAPTURE_VAL = 0;
  35. }
  36. }
  37. }



实验分析:

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



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

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


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

<1>


<2>


<3>


<4>


<5>



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



注意事项:

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值