OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12475|回复: 19

TIM2CH1_CAPTURE_STA的通俗理解,分享下我的理解

[复制链接]

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-10
在线时间
0 小时
发表于 2015-4-10 19:49:06 | 显示全部楼层 |阅读模式
以下是输入捕获实验的理解


//定时器5中断服务程序  
void TIM2_IRQHandler(void)

/*第一个if很关键,最后看第三步:   
 捕获完成后 请问TIM2CH1_CAPTURE_STA第七位状态几何?我们的目的是什么?
 获取高电平时间后是不是要显示,显示后还需不需要再次捕获呢?
 捕获后 TIM2CH1_CAPTURE_STA为1,无法进行下列if判断,无法进入中断判断,
 故TIM2CH1_CAPTURE_STA=0需要清零,main函数有所体现。

 会有人问 if((TIM2CH1_CAPTURE_STA&0X80)==0)可不可以不要,我认为可以。
 原因每次捕获都是从上升沿开始再捕获下降沿,可以下降沿读取捕获值
 主函数中if(TIM2CH1_CAPTURE_STA&0X80)改为TIM2CH1_CAPTURE_STA&0x40即可
*/
  if((TIM2CH1_CAPTURE_STA&0X80)==0) //还未成功捕获
{  
/* 再看 第二步

从下面看:读取溢出标号,在捕获上升沿后,没来得及捕获下降沿时发生溢出。说明什么?
溢出必发生在高电平 IM2CH1_CAPTURE_STA&0X40表示已经捕获到高电平(上升沿阶段)。
来一次溢出,则(TIM2CH1_CAPTURE_STA&0X3F)++,表示溢出次数。
溢出超出了,怎么办?
TIM_APR 16位预装载值,即CNT>65536-1时溢出。 
0X3F个65536共4128768单位,约4128768/72=58ms 即最大值。 程序是不是就完了了?

没有,若超过最大值,不作处理则形成bug 。
(TIM2CH1_CAPTURE_STA&0X3F)++等于0x40 ,溢出数等于清0,结果有出现没发生溢出情况下的脉宽值TIM2CH1_CAPTURE_VAL
 所以必须做处理,可以做强制结束该次捕获,设为测量范围的最大值,超过就不准了,一杆秤最大只能称多重的一样,超过范围则无法使用。
 TIM2CH1_CAPTURE_VAL=0XFFFF;


*/

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
 
{    
if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM2CH1_CAPTURE_VAL=0XFFFF;
}else TIM2CH1_CAPTURE_STA++;
}  
}

/* 先看 第一步

从下面看:TIM2CH1_CAPTURE_STA=0 默认为0,TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 
发生第一次捕获肯定是上升沿无疑,
进入中断程序 判断if(TIM2CH1_CAPTURE_STA&0X40) 第6位必为0,
也就是说第6位为0表示捕获上升沿,为了方便计数高电平,由高电平开始计数,即清零工作。
为了下次进中断程序 TIM2CH1_CAPTURE_STA第6位还为0,难道还捕获上升沿吗?
故TIM2CH1_CAPTURE_STA|=0X40,也就是说第6位为1表示准备捕获下升沿,标号没有
实际作用,接着用TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling)来体现第6位表示实际作用功能(0:上。1:下)。
至此,一次高电平完成,TIM2CH1_CAPTURE_STA|=0X80用第7位表示,完成的作用意义就是读取捕获值(高电平) 存放TIM2CH1_CAPTURE_VAL。
也就是说第7位的作用是读捕获值(0:不读。1:读)。
最后用TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising)来进入第2或第3等多次捕获跳转。

注意:这里用到了TIM2CH1_CAPTURE_STA第7位表示,读取捕获值 存放TIM2CH1_CAPTURE_VAL。这里的捕获没考虑溢出的情况
*/
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
{
if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿
{  
TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
  TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM2CH1_CAPTURE_STA=0; //清空
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}    
}           
  }
 
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
学以致用,尽其所能
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2018-3-27
在线时间
5 小时
发表于 2018-3-27 02:21:23 | 显示全部楼层
以下是个人对此段代码的理解:
unsigned char   TIM4CH1_CAPTURE_STA=0;        //输入捕获状态                                                   
unsigned int          TIM4CH1_CAPTURE_VAL;          //输入捕获值
/*
注: TIM4CH1_CAPTURE_STA 为自定义的一个寄存器,用以表示定时器4的通道1的‘输入捕获’状态位
其中
7位表示:‘边沿触发’后半段标识,捕获到了则为1,无则为0
6位表示:‘边沿触发’前半段标识,捕获到了有则为1,无则为0
5-0表示:定时器溢出的总次数,为对付长脉冲而生
*/
       
/*
1、第一段if用来处理因为‘更新’而触发的定时器中断溢出,第二段if用来处理‘输入捕获’而触发的中断
2、从未检测过信号时,中断中应该不做实际工作。做实际工作时,一定先触发‘输入捕获’
3、应加入锁定功能,防止要采集的‘脉冲时间’被后续脉冲信号刷掉
*/


void TIM4_IRQHandler(void) //定时器4用作输入捕获‘一个脉冲信号’时间的中断函数(默认‘边沿触发’前半段为‘下降沿’)
{

        if((TIM4CH1_CAPTURE_STA&0X80)==0)//从未测量过一次脉冲信号的长度时,才进行if内的操作,测过一次的不可再测。此if语句的作用是锁定
        {          
               
                if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//发生捕获事件,接下来需要判断是‘边沿触发’前半段还是后半段
                        {       
                                if((TIM4CH1_CAPTURE_STA&0X40) == 0)                //‘前半段’为零,说明这是首次捕获                                          
                                {                 
                                        TIM4CH1_CAPTURE_STA = 0;                        //初始化标识位,开始计时工作 m_m
                                        TIM4CH1_CAPTURE_VAL = 0;      //将自定义的计数器清零
                                        TIM_SetCounter(TIM4,0);       //将TIM4的计数器清零,使TIM4计数寄存器的数值与自定义的‘TIM4CH1_CAPTURE_VAL’相等
                                        TIM4CH1_CAPTURE_STA |= 0X40;        //将‘边沿触发’前半段标识为‘1’
                                        TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Rising);                //因为本次试验采用的是端口上拉‘按键检测’,所以‘边沿触发’前半段为‘下降沿’,后半段自然是‘上升沿’,所以此处要对TIM4的通道1进行一次边沿的极性转换
                                       
                    }else                          //如果已经捕获过了‘边沿触发’前半段,则这次捕获的肯定是‘边沿触发’后半段
                                {
                                       
                                        TIM4CH1_CAPTURE_STA |= 0X80;                //标记成功捕获‘边沿触发’后半段,至此,完成一次脉冲时间的测量
                                        TIM4CH1_CAPTURE_VAL = TIM_GetCapture1(TIM4); //获得脉冲时间
                                        TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Rising); // 切换会默认极性
                                }                    
                        }       
                       
                if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //时间到了,本次循环没有检测到‘边沿触发’,定时器溢出
                 
                {            
                        if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到‘边沿触发’前半段才进行‘定时器溢出计数器’自加操作
                        {
                                if((TIM4CH1_CAPTURE_STA&0X3F) == 0X3F)//脉冲信号太长,TIM4CH1_CAPTURE_STA中的‘5-0’位表示的‘定时器溢出计数器’也装不下时,应强制结束此次测量,保持最大时间
                                {
                                        TIM4CH1_CAPTURE_STA |= 0X80;//强制标记捕获‘边沿触发’后半段,完成一次脉冲时间的测量
                                        TIM4CH1_CAPTURE_VAL= 0XFFFF;//将自定义的计数器强制设为最大
                                }else TIM4CH1_CAPTURE_STA++;
                        }         
                }                       
        }

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位       
}


最后向代码作者致敬

回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-4-10 22:18:16 | 显示全部楼层
谢谢分享....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 1 反对 0

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-10
在线时间
0 小时
 楼主| 发表于 2015-4-10 21:09:45 | 显示全部楼层
0X3F个65536共4128768单位,约4128768/72*72=4s  即最大值    因72分频
学以致用,尽其所能
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-10
在线时间
0 小时
 楼主| 发表于 2015-4-10 22:33:11 | 显示全部楼层
原子哥,向你学习,呵呵,刚开始有点困惑,自己亲自写后,再看你的代码就很好理解了
学以致用,尽其所能
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-4-10 22:55:09 | 显示全部楼层
回复【4楼】stm32学习源:
---------------------------------
祝您早日学会stm32
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-10
在线时间
0 小时
 楼主| 发表于 2015-4-10 23:08:12 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
谢谢
学以致用,尽其所能
回复 支持 反对

使用道具 举报

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2015-4-18
在线时间
1 小时
发表于 2015-4-23 02:21:20 | 显示全部楼层
回复【2楼】stm32学习源:
---------------------------------
我有个不理解的地方,定义的TIM2CH1_CAPTURE_STA这个变量是如何作为寄存器使用的,如果有单片机里有一个固定的寄存器,捕捉到了自动置1,这样能理解。TIM2CH1_CAPTURE_STA直接与0x80来判断到底有没有捕捉。实在不能理解,能否指点下
回复 支持 反对

使用道具 举报

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2015-4-18
在线时间
1 小时
发表于 2015-4-23 02:21:49 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
我有个不理解的地方,定义的TIM2CH1_CAPTURE_STA这个变量是如何作为寄存器使用的,如果有单片机里有一个固定的寄存器,捕捉到了自动置1,这样能理解。TIM2CH1_CAPTURE_STA直接与0x80来判断到底有没有捕捉。实在不能理解,能否指点下
回复 支持 反对

使用道具 举报

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2015-4-18
在线时间
1 小时
发表于 2015-4-23 02:27:52 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
这个变量虽然被定义成了 一个寄存器。。但是我在中文参考手册里也找了,没有这个寄存器啊
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-4-25 22:34:57 | 显示全部楼层
回复【9楼】chenshoubao:
---------------------------------
这就是个变量。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

32

主题

230

帖子

0

精华

高级会员

Rank: 4

积分
508
金钱
508
注册时间
2016-4-14
在线时间
113 小时
发表于 2016-5-19 10:56:42 | 显示全部楼层

之前觉得原子写的好难理解啊~看多了之后发现原子是真心牛!赞一个,开发板是我见过最骚的~赞一个
回复 支持 反对

使用道具 举报

32

主题

230

帖子

0

精华

高级会员

Rank: 4

积分
508
金钱
508
注册时间
2016-4-14
在线时间
113 小时
发表于 2016-5-19 11:03:14 | 显示全部楼层
chenshoubao 发表于 2015-4-23 02:27
回复【5楼】正点原子:
---------------------------------
这个变量虽然被定义成了 一个寄存器。。但 ...

不是寄存器只是当做寄存器来用,边用边赋值的
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2017-11-11
在线时间
3 小时
发表于 2017-11-28 16:53:30 | 显示全部楼层
其实为什么要除以72.。。
回复 支持 反对

使用道具 举报

13

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2017-3-23
在线时间
52 小时
发表于 2017-12-23 16:56:47 | 显示全部楼层
楼主大赞~~
回复 支持 反对

使用道具 举报

6

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
101
金钱
101
注册时间
2018-4-2
在线时间
17 小时
发表于 2018-4-2 10:15:19 | 显示全部楼层
chenshoubao 发表于 2015-4-23 02:21
回复【3楼】正点原子:
---------------------------------
我有个不理解的地方,定义的TIM2CH1_CAPTURE_STA ...

你好 这个问题您现在懂了吗? 我也是对这个有疑问
回复 支持 反对

使用道具 举报

5

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
281
金钱
281
注册时间
2018-1-3
在线时间
44 小时
发表于 2018-7-15 08:53:01 | 显示全部楼层
我也是不理解自己定义的那个寄存器
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2019-4-18
在线时间
0 小时
发表于 2019-4-18 09:17:19 来自手机 | 显示全部楼层
楼主或者哪位大佬,解答一下怎么捕获低电平
回复 支持 反对

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2018-10-24
在线时间
11 小时
发表于 2019-7-13 16:37:48 | 显示全部楼层
xcf0038 发表于 2019-4-18 09:17
楼主或者哪位大佬,解答一下怎么捕获低电平

你解决了吗
回复 支持 反对

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2020-3-13
在线时间
56 小时
发表于 2020-3-22 14:32:51 | 显示全部楼层
太感谢了,懂了!!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 05:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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