图片及文章内容摘自江科大自化协B站视频
前言
这一部分的学习完全不知道原理是很难写好代码的,这篇博客主要通过代码实现的方式叙述,在不需要理解原理的部分直接套用模板代码,按照模板书写容易出错的地方我会加以说明,目的是能在最少时间理解原理的条件下快速的使用STM32。
一、输入捕获基本结构
这个结构只使用了一个通道,目前只能测量频率。最开始要先把右上角的时基单元配置好,启动定时器。这时候CNT就会在时钟驱动下不断的自增,经过预分频之后这个位置的时钟频率就是驱动CNT的标准频率fc。标准频率 = 72M / 预分频系数。在这之后输入捕获通道1的GPIO口,输入左上图的方波信号,经过滤波器和边缘检测,选择TI1FP1为上升沿触发,输入选择直连的通道,分频器选择不分频,当TI1FP1出现上升沿之后,CNT的当前计数值转运到CCR1里,同时出发源选择,选中TI1FP1为触发信号,从模式选择复位操作,这样TI1FP1的上升沿,会通过TI1FP1上面这一路触发CNT清零(一定是先捕获,后清零)。在左上角图上升沿中,CCR1 = CNT,把CNT的值转运到CCR1里面去,这是输入捕获自己进行的,然后的CNT = 0,清零计数器,这是从模式自动执行的,然后再一个周期执行之内,CNT在标准时钟的驱动下,不断自增,每次的CNT也会清零,所以CNT每次都是从上升沿开始从0计数,一直++知道下一次上升沿的来临,最后再CCR1 = CNT,CNT = 0。这个电路工作时,CCR1的值始终保持为最新一个周期的计数值,这个计数值是下图的N,只需要读取CCR1得到N,在计算fc/N就行了,这里的ARR和CNT最大值为65535(这里要注意信号频率太低导致的CNT溢出)。从主从模式的触发源选择里只有TI1FP1和TI2FP2,没有TI3和TI4的型号,所以从模式自动清零CNT的功能只能通过通道1和通道2实现,通道3和通道4只能开启捕获中断,在中断3和中断4里想实现这种功能就只能开启捕获中断并在中断里手动清零,但是这样会大量的触发中断所以一般不使用。
* 这里的fc = 72M/(PSC + 1)
二、使用步骤
2、GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式
3、配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
4、配置输入捕获单元
5、选择从模式的触发源
6、选择触发之后执行的操作
7、调用TIM_Cmd函数,开启定时器
三.初始化源码
此处用的是测周法公式
1. #include "stm32f10x.h" // Device header 2. 3. void IC_Init(void) 4. { 5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 7. 8. GPIO_InitTypeDef GPIO_InitStructure; 9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 12. GPIO_Init(GPIOA, &GPIO_InitStructure); 13. 14. TIM_InternalClockConfig(TIM3); 15. 16. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; 17. TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 18. TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; 19. TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR 20. TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC 21. TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; 22. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); 23. 24. TIM_ICInitTypeDef TIM_ICInitStructure; 25. TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 26. TIM_ICInitStructure.TIM_ICFilter = 0xF;//滤波器 27. TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升、下降、上升下降都触发三种模式 28. TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频系数 29. TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//触发信号从直连通道还是交叉通道输入 30. TIM_ICInit(TIM3, &TIM_ICInitStructure); 31. 32. TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);//选择触发源 33. TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);//从模式配置 34. 35. TIM_Cmd(TIM3, ENABLE);//启动 36. } 37. 38. uint16_t IC_GetFreq(void)//读取当前的频率 39. { 40. return 1000000 / (TIM_GetCapture1(TIM3) + 1); //fx = fc / N fc = 72M/(PSC + 1) fx是频率 N是读取到的CCR的值 41. }