打印
[STM32F1]

IO口1S内中断最大次数

[复制链接]
1345|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fq1110|  楼主 | 2016-5-4 16:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
IO, TI, pi, ni, GPIO
本帖最后由 fq1110 于 2016-5-4 17:13 编辑

大家好,我做了一个定时器,时间间隔1S,在这一秒内,我做了一个IO口上升沿中断检测,不断统计IO口上升沿的个数。另外我用了一个信号发生器产生3M左右方波信号,占空比50%左右,接入这个IO口上,但是发现1S内检测到的中断个数只有1点几M,将信号发生器频率调至2M,基本能测到1.98M左右。4M/5M测出来都是2M左右。以下是主要代码:

//中断配置
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;        
        GPIO_Init(GPIOB, &GPIO_InitStructure);               

        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Line = EXTI_Line6;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//EXTI_Trigger_Falling;//
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
        EXTI_ClearFlag(EXTI_Line6);
         NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
         NVIC_Init(&NVIC_InitStructure);
//中断函数
volatile u32 Num=0;
void EXTI9_5_IRQHandler(void)
{
        //if(EXTI->PR & 0x40)
        {
                EXTI->PR = 0x40;
                Num++;               
        }
}
//1S定时器内设置断点,并去检查这个Num的值,以检测实际测的IO口中断次数,同时并重新清零Num
在软件设计时,我考虑了中断函数的执行时间,没有使用函数库,并且屏蔽了一些不必要的判断。大家能帮我看看中断函数还能优化吗?我希望能达到4M左右的高频较精确的检测。
从理论上讲,72M频率,1.25MIPS/Mhz 1.25*72=90Mips,如果中断函数中的运行周期超过40,则中断的次数最多90M/40=2.25M。
请大家指导,IO口中断频率最大能达到多少,在软件设计上还有什么需要注意的地方?我这的中断函数中的指令到底用了多少个时钟周期,大家有没有关于此方面的介绍,网上没有找到。
非常感谢大家。



io中断汇编.png (30.79 KB )

io中断汇编.png
沙发
JY-DX-JY| | 2016-5-4 17:05 | 只看该作者
中断处理也需要时间的,压栈出栈等操作。

使用特权

评论回复
板凳
fq1110|  楼主 | 2016-5-4 17:15 | 只看该作者
JY-DX-JY 发表于 2016-5-4 17:05
中断处理也需要时间的,压栈出栈等操作。

JY-DX-JY,非常感谢,我这段代码哪些还能优化一下呢?能减少中断运行时间。我之间没优化之前,才能检测到600k左右,优化之后,基本能测到2M左右,但是还是不够。
你有什么好建议吗?

使用特权

评论回复
地板
JY-DX-JY| | 2016-5-4 17:32 | 只看该作者
感觉你的中断程序已经很简单啦

使用特权

评论回复
5
lovecat2015| | 2016-5-4 22:02 | 只看该作者
中断次数太多会不会导致CPU没有时间对数据进行处理呢

使用特权

评论回复
6
yklstudent| | 2016-5-5 07:33 | 只看该作者
基本就干处理中断的事情了,累死MCU了

使用特权

评论回复
7
3htech| | 2016-5-5 07:45 | 只看该作者
使用计数器模式是否可行?
使用一个定时器来定时打开或关闭计数器。

使用特权

评论回复
8
shdjdq| | 2016-5-5 07:49 | 只看该作者
应该还是从目的要要求进行优化或改进。单一的比拚速度没有太大的意义

使用特权

评论回复
9
airwill| | 2016-5-5 08:25 | 只看该作者
最大的问题还是中断进入和退出的开销.
假设 MCU 的主频为 72MHz, 那么计算出每次中断大概是 36 个周期.
查阅手册, 进出中断各需要 12个周期, 就已经 24 个周期了, 剩下的

           EXTI->PR = 0x40;
                Num++;               

应该还有 12 个周期. 这已经很精炼了. 如果还想再优化, 你可以采用强制寄存器变量. 比如让 Num 就是 R7. 可以省去装载地址, 装载和存储指令(只剩+1 指令)
当然, 要想得到更快的速度, 你还有别的办法
1. 中断服务里采样多个中断信号.
2. 直接使用查询的办法

使用特权

评论回复
10
mcu5i51| | 2016-5-5 08:50 | 只看该作者
如果只是计数,使用定时器外部计数就好,不知SPI行不,外部输入时钟,看等到多少SPI数据,这样就可以8(或指定BIT)分频

使用特权

评论回复
11
airwill| | 2016-5-5 13:02 | 只看该作者
是的, 如果有定时器可用, 可以使用定时器外部时钟信号引脚, 让定时器去计数.

使用特权

评论回复
12
shdjdq| | 2016-5-5 13:23 | 只看该作者
你的程序放到RAM中运行,可能会快些。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

530

帖子

1

粉丝