OpenEdv-开源电子网

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

关于输入捕获计算频率最大采集频率

[复制链接]

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
发表于 2021-10-27 16:03:18 | 显示全部楼层 |阅读模式
30金钱
需要采集1K-4M的脉冲信号,采集出频率。目前使用程序测试只能到500K,再加频率这个采集到的频率就不变了。采用72Mhz,不分频,理论上是可以的。不知道原因,请教一下
       

TIM5_Cap_Init(0XFFFF,0);        //72-1以1Mhz的频率计数
void TIM5_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
           NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);        //使能TIM5时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  //PA0 清除之前设置  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_0);                                                 //PA0 下拉
       
        //初始化定时器5 TIM5         
        TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;         //预分频器   
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        //初始化TIM5输入捕获参数
        TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01         选择输入端 IC1映射到TI1上
          TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
          TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM5, &TIM5_ICInitStructure);
       
        //中断分组初始化
        NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
       
        TIM_ITConfig(TIM5,TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断       
       
           TIM_Cmd(TIM5,ENABLE );         //使能定时器5



}



u8  TIM5CH1_CAPTURE_STA=0;        //输入捕获状态                                                   
u16        TIM5CH1_CAPTURE_VAL=0;        //输入捕获值
u16        TIM5CH1_CAPTURE_VAL1=0;        //输入捕获值
u8 state=0;
u16 hz=0;
float hz1;
//定时器5中断服务程序         
void TIM5_IRQHandler(void)
{

/
        if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
                {       
                          TIM_ClearITPendingBit(TIM5, TIM_IT_CC1); //清除中断标志位
                        if(state==0)                //捕获到一个下降沿                
                        {                                 
                       
                                state=1;
                                TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);
                                  

                       
                        }else
             if(state==1)                //捕获到一个下降沿
                        {
                                state=0;
                                TIM5CH1_CAPTURE_VAL1=TIM_GetCapture1(TIM5);
                                if(TIM5CH1_CAPTURE_VAL1>TIM5CH1_CAPTURE_VAL)
                                {
                                        hz=TIM5CH1_CAPTURE_VAL1-TIM5CH1_CAPTURE_VAL;
                                }else
                                        if(TIM5CH1_CAPTURE_VAL1<TIM5CH1_CAPTURE_VAL)
                                        {
                                                hz=(0xffff-TIM5CH1_CAPTURE_VAL)+TIM5CH1_CAPTURE_VAL;
                                        }else
                                        hz=0;
                                       
                                        hz1=1000000*72/hz/1000;
                        }                               
                }                                                                                   
       



}




最佳答案

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

中断的开销是进入 12个时钟, 退出又是另外12时钟, 所以你根本不可能用这种方法处理4MHz的信号 用捕获+DMA, 然后在主程序轮询DMA的Half及Comp标志处理数据吧,采集4Mhz的信号是没问题的, 但要同时要实时处理4MHz的信号就近乎不可能了, 当然这还要看你处理数据的耗时。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1906

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4100
金钱
4100
注册时间
2018-8-14
在线时间
695 小时
发表于 2021-10-27 16:03:19 | 显示全部楼层
中断的开销是进入 12个时钟, 退出又是另外12时钟, 所以你根本不可能用这种方法处理4MHz的信号

用捕获+DMA, 然后在主程序轮询DMA的Half及Comp标志处理数据吧,采集4Mhz的信号是没问题的, 但要同时要实时处理4MHz的信号就近乎不可能了, 当然这还要看你处理数据的耗时。
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-27 16:04:14 | 显示全部楼层
只能到500K,信号源再加频率,采集就在500K不动了。
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8206
金钱
8206
注册时间
2020-5-11
在线时间
3700 小时
发表于 2021-10-27 16:44:20 | 显示全部楼层
捕获中断怕是太过频繁,确定你的中断服务函数执行够快?
外部时钟源模式考虑一下。
专治疑难杂症
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2676
金钱
2676
注册时间
2018-11-8
在线时间
431 小时
发表于 2021-10-27 18:12:06 | 显示全部楼层
3楼说得有道理 频率太高的话单测一次高电平的时间不是很准 可以把待测信号当成定时器的外部时钟 记录单位时间内定时器的计数值就好了
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-28 09:01:18 | 显示全部楼层
LcwSwust 发表于 2021-10-27 16:44
捕获中断怕是太过频繁,确定你的中断服务函数执行够快?
外部时钟源模式考虑一下。

我在CPU里面制作这件事。把所有资源用来采集,这中断时间应该是6个时钟周期
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8206
金钱
8206
注册时间
2020-5-11
在线时间
3700 小时
发表于 2021-10-28 09:14:24 | 显示全部楼层
feiyang0725 发表于 2021-10-28 09:01
我在CPU里面制作这件事。把所有资源用来采集,这中断时间应该是6个时钟周期

可以测一下:主循环写一下 while(1){端口取反}
示波器看看端口波形。
就算资源足够,这种模式的性价比也低了些。
专治疑难杂症
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-10-28 09:22:03 | 显示全部楼层
你的中断处理就用了6个时钟周期????
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-28 13:22:45 | 显示全部楼层
LcwSwust 发表于 2021-10-28 09:14
可以测一下:主循环写一下 while(1){端口取反}
示波器看看端口波形。
就算资源足够,这种模式的性价比 ...

采集频率只是一个关键参数,但不是全部。
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-28 13:23:33 | 显示全部楼层
阿侑kevin 发表于 2021-10-28 09:22
你的中断处理就用了6个时钟周期????

我是查资料说中断反应需要几个时钟周期
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-10-28 14:43:45 | 显示全部楼层
feiyang0725 发表于 2021-10-28 13:23
我是查资料说中断反应需要几个时钟周期

那是指响应时间,你中断处理没结束的话就会导致中断触发信号丢失
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-29 14:30:54 | 显示全部楼层
阿侑kevin 发表于 2021-10-28 14:43
那是指响应时间,你中断处理没结束的话就会导致中断触发信号丢失

我在中断里面除了获取当前计数和计算当前频率就没有其他了
回复

使用道具 举报

63

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1136
金钱
1136
注册时间
2015-11-29
在线时间
146 小时
 楼主| 发表于 2021-10-29 14:38:29 | 显示全部楼层
阿侑kevin 发表于 2021-10-28 14:43
那是指响应时间,你中断处理没结束的话就会导致中断触发信号丢失

这个频率比较快拿出去算,可能算不准
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-10-29 15:44:40 | 显示全部楼层
本帖最后由 阿侑kevin 于 2021-10-29 15:45 编辑
feiyang0725 发表于 2021-10-29 14:38
这个频率比较快拿出去算,可能算不准

中断里面你有除法肯定算不快的,可以做缓存,然后几个脉冲后在外面算平均啊
回复

使用道具 举报

0

主题

1

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2019-7-23
在线时间
45 小时
发表于 2023-3-15 17:17:41 | 显示全部楼层
问题解决了么,用mb501分频器芯片 频段1Mhz-500Mhz都可以,反应灵敏相应速度快测试准  步进100
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 14:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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