×
单片机 > 单片机程序设计 > 详情

STM32F103学习笔记 (九) 输入捕获实验

发布时间:2020-08-27 发布时间:
|

这个实验是用 TIM5 的通道 1( PA0) 来做输入捕获, 捕获 PA0 上高电平的脉宽(用 WK_UP 按键输入高电平),通过串口打印高电平脉宽时间。

初始化里边先设置上升沿为输入捕捉,进入捕捉中断后,记录TIM5_CNT的值,然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM5_CNT 值。这样,前后两次 TIM5_CNT 之差,就是高电平的脉宽,
同时 TIM5 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。


相应的配置步骤为:

(1)开启TIM5时钟和GPIO时钟,设置PA0为下拉输入


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

  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟  


(2)初始化 TIM5,设置 TIM5 的 ARR 和 PSC。(3)设置 TIM5 的输入比较参数,开启输入捕获。(4)使能捕获和更新中断(设置 TIM5 的 DIER 寄存器) (5)设置中断分组,编写中断服务函数 。


  1. if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//判断是否为更新中断  

  2. if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件  

  3. TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位  


(6)使能定时器(设置 TIM5 的 CR1 寄存器)


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



timer.c中:


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

  2. TIM_ICInitTypeDef TIM5_ICInitStructure;  

  3. void TIM5_Cap_Init(u16 arr,u16 psc)  

  4. {  

  5. GPIO_InitTypeDef GPIO_InitStructure;  

  6. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

  7. NVIC_InitTypeDef NVIC_InitStructure;  

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

  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //①使能 GPIOA 时钟  

  10. 215  

  11. //初始化 GPIOA.0 ①  

  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //PA0 设置  

  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  

  14. GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化 GPIOA.0  

  15. GPIO_ResetBits(GPIOA,GPIO_Pin_0);  //PA0 下拉  

  16. //②初始化 TIM5 参数  

  17. TIM_TimeBaseStructure.TIM_Period = arr;  //设定计数器自动重装值  

  18. TIM_TimeBaseStructure.TIM_Prescaler =psc;  //预分频器  

  19. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TDTS = Tck_tim  

  20. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数模式  

  21. TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //初始化 TIMx  

  22. //③初始化 TIM5 输入捕获通道 1  

  23. TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1 映射到 TI1 上  

  24. TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  //上升沿捕获  

  25. TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上  

  26. TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //配置输入分频,不分频  

  27. TIM5_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器 不滤波  

  28. TIM_ICInit(TIM5, &TIM5_ICInitStructure); //初始化 TIM5 输入捕获通道 1  

  29. //⑤初始化 NVIC 中断优先级分组  

  30. NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3 中断  

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

  32. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级 0 级  

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

  34. NVIC_Init(&NVIC_InitStructure);   //初始化 NVIC  

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

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

  37. }  

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

  39. u16 TIM5CH1_CAPTURE_VAL;//输入捕获值  

  40. //⑤定时器 5 中断服务程序  

  41. void TIM5_IRQHandler(void)  

  42. {  

  43. if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获  

  44. {   

  45. if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)  

  46. {   

  47. 216  

  48. if(TIM5CH1_CAPTURE_STA&0X40) //已经捕获到高电平了  

  49. {  

  50. if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了  

  51. {  

  52. TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获了一次  

  53. TIM5CH1_CAPTURE_VAL=0XFFFF;  

  54. }else TIM5CH1_CAPTURE_STA++;  

  55. }  

  56. }  

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

  58. {  

  59. if(TIM5CH1_CAPTURE_STA&0X40)  //捕获到一个下降沿  

  60. {   

  61. TIM5CH1_CAPTURE_STA|=0X80;  //标记成功捕获到一次上升沿  

  62. TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);  

  63.  TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置为上升沿捕获  

  64. }else  //还未开始,第一次捕获上升沿  

  65. {  

  66. TIM5CH1_CAPTURE_STA=0;  //清空  

  67. TIM5CH1_CAPTURE_VAL=0;  

  68. TIM_SetCounter(TIM5,0);  

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

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

  71. }   

  72. }     

  73. }  

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

  75. }  



其中重要的是TIM5 的中断服务函数,TIM5CH1_CAPTURE_STA,是用来记录捕获状态:

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

  • extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值  

  • int main(void)  

  • {  

  • u32 temp=0;  

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

  • NVIC_Configuration();  //设置 NVIC 中断分组 2  

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

  • LED_Init();  //LED 端口初始化  

  • TIM3_PWM_Init(899,0); //不分频。 PWM 频率=72000/(899+1)=80Khz  

  • TIM5_Cap_Init(0XFFFF,72-1); //以 1Mhz 的频率计数  

  •  while(1)  

  • {  

  • delay_ms(10);  

  • TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)+1);  

  • if(TIM_GetCapture2(TIM3)==300)  

  • TIM_SetCompare2(TIM3,0);  

  • if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿  

  • {  

  • temp=TIM5CH1_CAPTURE_STA&0X3F;  

  • 218  

  • temp*=65536;//溢出时间总和  

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

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

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

  • }  

  • }  

  • }  



  • 如果用杜邦线把PB5和PA0连起来,就会看到串口助手里以固定的时间宽度输出。


    关键字:STM32F10  输入捕获 

    『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

    热门文章 更多
    用中断方式.实现PIC单片机的串口传输