OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 3849|回复: 8

STM32F103RCT6利用定时器2实现多路捕获

[复制链接]

  离线 

2

主题

4

帖子

0

精华

新手入门

积分
33
金钱
33
注册时间
2015-10-24
在线时间
0 小时
发表于 2015-12-6 22:29:24 | 显示全部楼层 |阅读模式
5金钱
STM32F103RCT6利用定时器2实现四路输入捕获,根据官方例程单路捕获没有问题,想改一下做成四路捕获,自己稍微改了下void TIM2_Cap_Init(u16 arr,u16 psc)的程序,发现都不行了,理论上应该是可以的我把程序贴一下请各位帮忙看看

最佳答案

查看完整内容[请看2#楼]

首先要开启对应的中断,你的程序中少了这一步。然后也是最重要的一步,要清楚输入捕获的原理:1.对应寄存器的原理:在捕获到边沿时CCR寄存器会锁存计数器当前的值,所以在使用TIM_GetCaptureX(TIMY)的时候读取的是对应定时器(Y)的对应通道(X)CCR锁存的值而并非是当前的计数器的值,这就保证了捕获的精确度;但使用你的驱动程序(也是大家都使用的)时,有个前提,就是计数器在接收到上升沿(起始边沿,这个根据你要捕获的是高电平 ...
回复

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-7-6
在线时间
0 小时
发表于 2015-12-6 22:29:25 | 显示全部楼层
本帖最后由 霜月 于 2018-7-6 18:22 编辑

首先要开启对应的中断,你的程序中少了这一步。然后也是最重要的一步,要清楚输入捕获的原理:1.对应寄存器的原理:在捕获到边沿时CCR寄存器会锁存计数器当前的值,所以在使用TIM_GetCaptureX(TIMY)的时候读取的是对应定时器(Y)的对应通道(X)CCR锁存的值而并非是当前的计数器的值,这就保证了捕获的精确度;但使用你的驱动程序(也是大家都使用的)时,有个前提,就是计数器在接收到上升沿(起始边沿,这个根据你要捕获的是高电平还是低电平时间有关),计数器的值必须为0,以保证准确度,所以使用了TIM_SetCounter(TIMY, 0);这个函数来设置对应的计数器(Y)的值为零。2.捕获时间的计算:当然我们启动了两个中断(在单一捕获的时候),一个是溢出出触发的(功能:计算时间),一个是接收到边沿触发的(功能:设定何时计时何时停止),通过记录定时器的溢出次数来决定“大时间”(由于此时计数器中可能还有值,所以溢出次数*定时的时间得到的值是不准的,由于比较大所以是“大时间”),由定时器的值来决定“小时间”(计数器的值是很关键的因为在收到下降沿(末边沿,这个也根据要捕获的电平来决定)的时候,定时器极有可能没有刚好溢出,所以这部分的时间也要加上,由于比较短所以是“小时间”)。

通过实验可以发现在启动了4个通道的中断,并且都初始化后,程序是能够正常运行的,但是捕获的时间是有很大的误差的,关键点在于“以保证准确度,所以使用了TIM_SetCounter(TIMY, 0);这个函数来设置对应的计数器(Y)的值为零。”,看到这里请再看一遍原理。由于在任何一个、任何一个、任何一个(重要的事情说3遍)通道收到了上升沿(起始边沿)的时候会调用这个函数,所以其他的几个通道的“大时间”和“小时间”全都乱了(不管是溢出次数还是最后计算“小时间”用的计数器的值)。所以关键点在于这个函数的改写,之所以在这里设置定时器的值为0,是为了在计算“小时间”的时候方便(计算公式应该是:小时间=计数器值-起始计数器值,因为在起始的时候就设定了计数器的值为0,所以在计算小时间的值就直接等于CCR的值(想想其实这个也不精确)),但现在有至多有4个通道,所以不能用这么简单的方式,应该和记录溢出次数和状态的方式一样,有多少通道就设多少个变量来存储各个通道在收到上升沿(起始边沿)时的计数器的值来替代这个函数,所以小时间的计算方式就是:收到下降沿(末边沿)时的计数器的值-上升沿(起始边沿)的计数器的值(这个值应该存储在一个全局变量里或是静态变量里)不难理解,假设计数到10溢出,如果起始是5,末是3,那么小时间应该是(5-3)*T)。

结论:只需替换TIM_SetCounter(TIMY, 0)函数,并且加入4个变量用来记录上升沿(起始边沿)时计数器的值即可,通过小时间的计算公式就可以得到准确的捕获时间。
注意问题:我在调试的过程中会出现溢出次数少1的情况,这种情况只会出现在上升沿时计数器的值很大的时候,如0xFFE2,0xFFC0等等,通过调试我人为可能是由于两个中断的时间间隔很短导致的。
回复

使用道具 举报

  离线 

508

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
132710
金钱
132710
注册时间
2010-12-1
在线时间
1240 小时
发表于 2015-12-6 22:54:44 | 显示全部楼层
帮顶.....
回复

使用道具 举报

  离线 

3

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2015-10-18
在线时间
1 小时
发表于 2016-11-3 19:02:42 | 显示全部楼层
同问 我也是这个问题 我用的TIM5
回复

使用道具 举报

  离线 

3

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2015-10-18
在线时间
1 小时
发表于 2016-11-3 20:28:47 | 显示全部楼层
我知道了  定时器可以多通道PWM输出 但是只能单通道捕获
回复

使用道具 举报

  离线 

1

主题

5

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-2-27
在线时间
8 小时
发表于 2017-3-15 14:10:52 | 显示全部楼层
你只打开了第一路的捕获中断,其它三路怎么能捕获得了呢?
回复

使用道具 举报

  离线 

10

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-1-29
在线时间
23 小时
发表于 2017-6-20 12:40:22 | 显示全部楼层
请问你的多路输入捕获程序调试完成了吗?怎么才能实现多路输入捕获呢,谢谢。
回复

使用道具 举报

  离线 

0

主题

4

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2013-11-30
在线时间
7 小时
发表于 2017-7-19 17:46:11 | 显示全部楼层
本帖最后由 海上浮萍 于 2017-7-20 13:49 编辑

//定时器2通道1输入捕获配置
//arr:自动重装值
//psc:时钟预分频数
void TIM2_Cap_Init(u16 arr,u16 psc)
{                 
        RCC->APB1ENR|=1<<0;           //TIM2 时钟使能
        RCC->APB2ENR|=1<<2;            //使能PORTA时钟  
         
        GPIOA->CRL&=0XFFFF0000;        //PA0 清除之前设置  
        GPIOA->CRL|=0X00008888;        //PA0 输入   
        GPIOA->ODR|=0<<0;                //PA0 下拉
         
         TIM2->ARR=arr;                  //设定计数器自动重装值   
        TIM2->PSC=psc;                  //预分频器

        TIM2->CCMR1|=1<<0;                //CC1S=01         选择输入端 IC1映射到TI1上
         
        TIM2->CCMR1|=1<<8;                //CC2S=01         选择输入端 IC2映射到TI2上

        TIM2->CCMR2|=1<<0;                //CC3S=01         选择输入端 IC3映射到TI3上

        TIM2->CCMR2|=1<<8;                //CC4S=01         选择输入端 IC4映射到TI4上


        TIM2->CCER|=0<<1;                 //CC1P=0        上升沿捕获
        TIM2->CCER|=1<<0;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

        TIM2->CCER|=0<<5;                 //CC1P=0        上升沿捕获
        TIM2->CCER|=1<<4;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

        TIM2->CCER|=0<<9;                 //CC1P=0        上升沿捕获
        TIM2->CCER|=1<<8;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

        TIM2->CCER|=0<<13;                 //CC1P=0        上升沿捕获
        TIM2->CCER|=1<<12;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

        TIM2->DIER|=0x0f<<1;           //允许捕获中断                                
        TIM2->DIER|=1<<0;           //允许更新中断        
        TIM2->CR1|=0x01;            //使能定时器2
        MY_NVIC_Init(2,0,TIM2_IRQChannel,2);//抢占2,子优先级0,组2           
}

TIM_Cap_Dat_T TIM_Cap_Dat;
u32 RGB[18];//颜射传感器数据
//定时器2中断服务程序         
void TIM2_IRQHandler(void)
{         
        u16 tsr;
        tsr=TIM2->SR;

        if(tsr&0X01)//溢出中断
        {            
                TIM_Cap_Dat.cap_time[0] += 65536;
                TIM_Cap_Dat.cap_time[1] += 65536;
                TIM_Cap_Dat.cap_time[2] += 65536;
                TIM_Cap_Dat.cap_time[3] += 65536;
        }
        if(tsr&(1<<1))//捕获1发生捕获事件
        {        
                if(TIM_Cap_Dat.state.bit.cap1_state == 0)//判断是否是第一次捕获到高电平
                {

                }
                else//第二次捕获到上升延
                {
  
                }
        }                                                                                    
         if(tsr&(1<<2))//捕获2发生捕获事件
        {        
                if(TIM_Cap_Dat.state.bit.cap2_state == 0)//判断是否是第一次捕获到高电平
                {

                }
                else//第二次捕获到上升延
                {

                }
        }
         if(tsr&(1<<3))//捕获3发生捕获事件
        {        
                if(TIM_Cap_Dat.state.bit.cap3_state == 0)//判断是否是第一次捕获到高电平
                {
   
                }
                else//第二次捕获到上升延
                {

                }
        }
         if(tsr&(1<<4))//捕获4发生捕获事件
        {        
                if(TIM_Cap_Dat.state.bit.cap4_state == 0)//判断是否是第一次捕获到高电平
                {
      
                }
                else//第二次捕获到上升延
                {

                }
        }        
        TIM2->SR=0;//清除中断标志位            
}
回复

使用道具 举报

  离线 

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2017-10-31
在线时间
36 小时
发表于 2018-3-13 17:30:32 | 显示全部楼层
要开启通道2,3,4的捕捉中断
敬往事一杯酒,再爱也不回头
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




关闭

必看,必学:"原子哥”力荐上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-9-19 07:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */