历史上的今天
返回首页

历史上的今天

今天是:2025年03月29日(星期六)

2020年03月29日 | stm32---输入捕获

2020-03-29 来源:eefocus

输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能。STM32 的输入捕获,简单地说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中。

1. 相关寄存器介绍

1) 捕获/比较模式寄存器 (TIMx_CCMRx) 


当在输入捕获模式下使用的时候,对应上图的第二行描述,从图中可以看出,TIMx_CCMR1 明显是针对 2 个通道的配置,低八位[7:0]用于捕获/比较通道 1 的控制,而高八位[15:8]则用于捕获/比较通道 2 的控制。同理,CCMR2 这个寄存器用来控制通道 3 和通道 4。今天的实验,我们用到的是 TIM5 的捕获/比较通道 1。


 (1)CC1S[1:0],这两个位用于 CCR1 的通道配置,这里我们设置 CC1S[1:0]=01,也就是配置 IC1 映射在 TI1 上。如果不理解没有关系,看图就知道了。


从图中可以知道,IC1有三个输入源,分别是TI1,TI2,TRC。

TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 这是通过库函数配置,映射到TI1。

头文件(stm32f10x_tim.h)定义如下:

#define TIM_ICSelection_DirectTI           ((uint16_t)0x0001) 
#define TIM_ICSelection_IndirectTI         ((uint16_t)0x0002) 
#define TIM_ICSelection_TRC                 ((uint16_t)0x0003)

(2)IC1F[3:0]


表格中的f_ck_int 是定时器的输入频率(TIMxCLK),f_dts 则是根据 TIMx_CR1 的 CKD[1:0]来确定。



上图就是TIMx_CR1寄存器。

#define TIM_CKD_DIV1                       ((uint16_t)0x0000)
#define TIM_CKD_DIV2                       ((uint16_t)0x0100)
#define TIM_CKD_DIV4                       ((uint16_t)0x0200)

假定选IC1F[3:0]=0101,即采样频率为fDTS/2, N=8;

选CKD[1:0]=01,即 tDTS = 2 × tCK_INT;并假定 fCK_INT=72MHz。  

这时可以算出,采样频率为72MHz/2/2=18MHz.

1/(18MHz)*8 = 0.4444us = 444.4ns.

因为N=8,所以滤波器可以滤除掉输入端小于444.4ns的脉冲。 

“数字滤波器由一个事件计数器组成,它记录到N个事件后会产生一个输出的跳变”,这句话可以这样理解:

当滤波器连续采样到N个有效电平时,就输出这个有效电平。 
当滤波器没有连续采样到N个有效电平时,再从0开始计数,输出一直保持上一次输出的有效电平。

例如:滤波器上一次输出是高电平,本次连续采样到(N-1)个高电平,但第N个是个低电平,那么滤波器仍然保持上次输出的高电平,并重新开始计数,记录1次低电平,如果其后采样的(N-1)个也是低电平,此时滤波才输出低电平,于是一个下降沿才出现在IC1上。

(3)IC1PSC[1:0]


这里的“事件”指的是上升沿或者下降沿,具体是哪个由TIMx_CCER寄存器的CCxP位决定。

2)捕获/比较使能寄存器:TIMx_CCER


所以,要使能输入捕获,必须设置 CC1E=1,而 CC1P 则根据自己的需要来配置(捕获发生在上升沿还是下降沿)。 

3) DMA/中断使能寄存器(TIMx_DIER) 


在实验中,我们需要允许位0和位1的中断。

#define TIM_IT_Update                      ((uint16_t)0x0001)
#define TIM_IT_CC1                         ((uint16_t)0x0002)
#define TIM_IT_CC2                         ((uint16_t)0x0004)
#define TIM_IT_CC3                         ((uint16_t)0x0008)
#define TIM_IT_CC4                         ((uint16_t)0x0010)

对应的库函数是:TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);

4) 捕获/比较寄存器 (TIMx_CCRx) 


该寄存器用来存储捕获发生时,TIMx_CNT的值,我们从 TIMx_CCR1 就可以读出通道 1 捕获发生时刻的 TIMx_CNT 值,通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度。

2. 实验设计

通过TIM3产生一路PWM(从PB5输出),把PB5连接到PA0上,PA0和 TIM5_CH1是同一个管脚。利用TIM5_CH1的输入捕获功能,测量出PWM的宽度。


3. 参考代码

[cpp] view plain copy

  1. //TIM5_CH1输入捕获配置  

  2. void TIM5_Cap_Init(u16 arr,u16 psc)  

  3. {      

  4.     TIM_ICInitTypeDef  TIM5_ICInitStructure;  

  5.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  

  6.     NVIC_InitTypeDef NVIC_InitStructure;  

  7.   

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

  9.       

  10.     //TIM5的配置  

  11.     TIM_TimeBaseStructure.TIM_Period = arr;     //重装载值  

  12.     TIM_TimeBaseStructure.TIM_Prescaler =psc;   //分频系数   

  13.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;      //tDTS = tCK_INT  

  14.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数  

  15.     TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);   

  16.     

  17.     //TIM5输入捕获配置  

  18.     TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //我们用通道1  

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

  20.     TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1  

  21.     TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;   //无预分频器   

  22.     TIM5_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 ,无滤波器  

  23.     TIM_ICInit(TIM5, &TIM5_ICInitStructure);  

  24.       

  25.     //中断优先级配置  

  26.     NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;    

  27.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;    

  28.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    

  29.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   

  30.     NVIC_Init(&NVIC_InitStructure);    

  31.       

  32.     TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//打开更新中断和捕获中断  

  33.       

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

  35.      

  36. }  


[cpp] view plain copy

  1. #define START          0X01  

  2. #define WAIT_RISING    0X02  

  3. #define WAIT_FALLING   0X03  

  4.   

  5.                           

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

  7. u32 a[500] = {0};           //存放电平宽度  

  8. u32 i = 0; //数组下标  

  9. u8 overflow = 0;    //记录定时器更新中断的次数  

  10. u8 state = START;  

  11.   

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

  13. void TIM5_IRQHandler(void)  

  14. {   

  15.   

  16.     if(i<500)  

  17.     {       

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

  19.         {         

  20.             ++overflow;  

  21.         }  

  22.           

  23.         if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获事件  

  24.         {     

  25.             if(state == START)      //初始状态                

  26.             {     

  27.                 overflow = 0;  

  28.                 TIM_SetCounter(TIM5,0);  

  29.                 state = WAIT_FALLING;  

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

  31.             }     

  32.             else if(state == WAIT_RISING)    //等待上升沿  

  33.             {  

  34.                 TIM5CH1_CAPTURE_VAL = TIM_GetCapture1(TIM5);  

  35.                 a[i++] = TIM5CH1_CAPTURE_VAL + overflow*65536;  

  36.                   

  37.                 overflow = 0;  

  38.                 TIM_SetCounter(TIM5,0);  

  39.                 state = WAIT_FALLING;  

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

  41.                   

  42.             }  

  43.             else // wait falling  

推荐阅读

史海拾趣

DDK公司的发展小趣事

人才是企业发展的根本。DDK公司深知人才的重要性,因此一直致力于人才培养和引进。公司建立了完善的人才培养机制,通过内部培训、外部引进等多种方式,不断吸引和培养了一批批优秀的电子工程师、研发人员和管理人才。这些人才为公司的发展提供了强大的智力支持和人才保障。

Forge Europa Ltd公司的发展小趣事

在全球化布局的同时,Forge Europa Ltd公司也注重在中国市场的本土化深耕。公司在中国设立了研发中心和生产基地,以更好地服务中国市场并融入本土产业链。通过深入了解中国市场的需求和特点,Forge Europa不断调整产品策略,推出了一系列符合中国市场需求的LED灯带产品。此外,公司还积极与中国本土企业合作,共同推动LED照明技术的发展和应用。

EREM公司的发展小趣事

随着电子行业的不断发展,EREM公司也面临着越来越多的挑战。为了保持市场领先地位,EREM投入大量资金进行技术研发,推出了一系列具有创新性的产品。其中,一种新型的高硬度碳化钨合金剪钳因其卓越的耐用性和精度而备受好评。这一技术突破不仅为EREM赢得了更多客户,也进一步巩固了其在电子行业中的地位。

华瓷(Chinocera)公司的发展小趣事

随着公司实力的增强和市场份额的扩大,华瓷开始将目光投向国际市场。公司积极参加国际陶瓷及电子行业的展会,与国际同行交流学习,同时大力推广自身的品牌和产品。通过多年的努力,华瓷的陶瓷材料在国际市场上获得了广泛的认可,成功打入欧洲、北美等高端市场。

Conditioning Semiconductor Devices Corp公司的发展小趣事

随着半导体行业的竞争加剧,价格战和技术更新速度不断加快。CSDC面临着巨大的市场压力。为了应对这些挑战,公司决定调整战略,专注于高端市场的开发。通过加大研发投入,提升产品质量和性能,CSDC逐渐在高端市场站稳了脚跟,实现了业务的稳步增长。

方舟(ARKLED)公司的发展小趣事

方舟公司不仅关注经济效益,还积极履行社会责任。公司积极参与环保事业,推动绿色生产,减少能源消耗和废弃物排放。同时,方舟公司还关注社会公益事业,捐资助学、扶贫济困,为社会和谐发展贡献了一份力量。

问答坊 | AI 解惑

负载性质对继电器触点浪涌的影响

负载性质对继电器触点浪涌的影响 选择合适的继电器,除了根据使用环境(主要指温度、湿度), 输入信号大小,还需要根据负载情况来选择,不同的负载,触点的电流浪涌小和时间也不同,因此选择继电器时候,要根据负载的性质,选择合适的触点容量的 ...…

查看全部问答>

POST MMS时分组传送问题

我用的GPRS模块每次发送的数据包最长只有1024字节,所以在POST MMS时,需要分几次发送。MMS文件再加上WSP,WTP头是超过1024字节的,所以我先发送第一个1024字节,但是我还没来得及发送第2个1024字节,WAP网关已经返回了m-send.cnf了,终端收到的MMS ...…

查看全部问答>

用驱动精灵备份的驱动为什么一定要用驱动精灵恢复,还有其他办法吗?

我在网上查了很多方法都行不同 http://shenke2000.3322.org/setup.rar 这个 麻烦大家看一下  小弟叫救命了…

查看全部问答>

急啊,在mc9s12dg128芯片AD问题

我们把AD都做好了,程序也写好了,但是每次读结果状态寄存器的值后,状态寄存器 的值没有改变,这是为什么呀?…

查看全部问答>

8.4【每周讨论】如何提高编程的技巧与编程能力

       请各位大牛将自己的一些编程细想和编程技巧与大家分享一下,最好细细说说,这样有助于初学者入门,有利于入门者提高,我就觉得自己一直在一个编程的瓶颈时期,现在就在艰苦的摸索中      ...…

查看全部问答>

上传一份安捷伦线性电源的资料

上传一份线性电源的资料,以供DIY线性电源的筒子们参考…

查看全部问答>

超高频RFID读卡一体机

好了就这样吧,期待能用上吧,实在不行要上公司的AP-Module了。…

查看全部问答>

软件编程和电源设计两个都想搞

小生就职于某公司,做的是电源监控工程师的活。尚处实习阶段,主要工作是配合电源工程师设计软件方面的控制,如MCU的选型,外围电路的设计,程序编写等。       眼下对我的职业规划有点困惑,发个小贴以求论坛诸位大师指条明 ...…

查看全部问答>

zigbee路由协议

想对zigbee本身路由协议进行入进设计 ,由于 刚刚接触这个,什么都不太懂,请问本身的路由协议可以在哪弄到?…

查看全部问答>