STM32最大中断处理频率
STM32 maximum interrupt handling frequency
我正在尝试实现我自己的从 FPGA 到 STM 的 SPI 通信,其中我的 FPGA 作为 MASTER 并生成芯片启用和通信时钟。 FPGA在其上升沿发送数据并在其下降沿接收数据我的FPGA代码工作正常。
在 STM 端,我在中断时捕获此主时钟并在其上升沿接收数据并在其下降沿传输但如果我将时钟速度从 250khz 提高,通信将无法正常工作
根据我的理解,STM 在 168 Mega hz 下工作,我根据 168Mhz 设置时钟设置,处理 1mhz 中断不是一个大问题所以你能指导我如何在 STM 中处理这个高速时钟吗
我的代码写在下面
/*
* Project name:
EXTI_interrupt (EXTI interrupt test)
* Copyright:
(c) Mikroelektronika, 2011.
* Revision History:
20111226:
- Initial release;
* Description:
This code demonstrates how to use External Interrupt on PD10.
PD10 is external interrupt pin for click1 socket.
receive data from mosi line in each rising edge.
* Test configuration:
MCU: STM32F407VG
http://www.st.com/st-web-
ui/static/active/en/resource/technical/document/datasheet/DM00037051.pdf
dev.board: EasyMX PRO for STM32
http://www.mikroe.com/easymx-pro/stm32/
Oscillator: HSI-PLL, 140.000MHz
Ext. Modules: -
SW: mikroC PRO for ARM
http://www.mikroe.com/mikroc/arm/
* NOTES:
receive 32 bit data from mosi line in each rising edge
*/
//D10 clk
//D2 ss
//C0 MOSI
//C1 FLAG
int read=0;
int flag_int=0;
int val=0;
int rec_data[32];
int index_rec=0;
int display_index=0;
int flag_dint=0;
void ExtInt() iv IVT_INT_EXTI15_10 ics ICS_AUTO {
EXTI_PR.B10 = 1; // clear flag
flag_int=1; //Flag on interrupt
}
TFT_Init_ILI9340();
void main() {
GPIO_Digital_Input(&GPIOD_BASE, _GPIO_PINMASK_10);
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_13); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_12); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_14); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_15); // Set PORTD as
digital output
GPIO_Digital_Input(&GPIOA_IDR, _GPIO_PINMASK_0); // Set PA0 as
digital input
GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_0); // Set PA0 as
digital input
GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_2); // Set PA0 as
digital input
GPIO_Digital_Output(&GPIOC_IDR, _GPIO_PINMASK_1); // Set PA0 as
digital input
//interupt register
SYSCFGEN_bit = 1; // Enable clock for alternate pin
functions
SYSCFG_EXTICR3 = 0x00000300; // Map external interrupt on PD10
EXTI_RTSR = 0x00000000; // Set interrupt on Rising edge
(none)
EXTI_FTSR = 0x00000400; // Set Interrupt on Falling edge
(PD10)
EXTI_IMR |= 0x00000400; // Set mask
//NVIC_IntEnable(IVT_INT_EXTI15_10); // Enable External interrupt
while(1)
{
//interrupt is not enable until i push the button
if((GPIOD_ODR.B2==0)&&(flag_dint==0))
{ if (Button(&GPIOA_IDR, 0, 1, 1))
{
Delay_ms(100);
GPIOC_ODR.B1=1; //Status for FPGA
NVIC_IntEnable(IVT_INT_EXTI15_10); // Enable External interrupt
}
}
if(flag_int==1)
{
//functionality on rising edge
flag_int=0;
if(index_rec<31)
{
//display data on led
GPIOD_ODR.B13= GPIOC_IDR.B0;
//save data in an array
rec_data[index_rec]= GPIOC_IDR.B0;
//read data
index_rec=index_rec+1;
}
else
{
flag_dint=1;
NVIC_IntDisable(IVT_INT_EXTI15_10);
}
} // Infinite loop
}
}
无需深入了解您的具体代码,请参阅 PeterJ_01 的评论,时钟速率问题可以通过您假设中对吞吐量的误解来解释。
你假设你的 STM 设备有一个 168Mhz 的时钟,它可以维持相同的中断吞吐量,你似乎保守地放宽到 1Mhz。
然而,它能够支持的中断吞吐量是设备处理每个中断所用时间的倒数。此时间包括处理器进入服务路由(即检测中断、中断当前代码并解析从向量 table 跳转到的位置)所花费的时间以及执行服务例程所花费的时间。
让我们超级乐观地说,进入例程需要 1 个周期,路由本身需要 3 个(2 个用于您设置的标志,1 个用于跳出例程)。这给出 4 个周期在 168Mhz 是 23.81ns,取反 42Mhz。这也可以通过将您将达到的最大频率 (168Mhz) 除以处理所花费的周期数来计算。
因此我们真正乐观的界限是 42Mhz,但实际上会更低。为了获得更准确的估计,您应该测试您的实施时间并深入研究您的设备文档以查看中断响应时间。
我正在尝试实现我自己的从 FPGA 到 STM 的 SPI 通信,其中我的 FPGA 作为 MASTER 并生成芯片启用和通信时钟。 FPGA在其上升沿发送数据并在其下降沿接收数据我的FPGA代码工作正常。
在 STM 端,我在中断时捕获此主时钟并在其上升沿接收数据并在其下降沿传输但如果我将时钟速度从 250khz 提高,通信将无法正常工作
根据我的理解,STM 在 168 Mega hz 下工作,我根据 168Mhz 设置时钟设置,处理 1mhz 中断不是一个大问题所以你能指导我如何在 STM 中处理这个高速时钟吗
我的代码写在下面
/*
* Project name:
EXTI_interrupt (EXTI interrupt test)
* Copyright:
(c) Mikroelektronika, 2011.
* Revision History:
20111226:
- Initial release;
* Description:
This code demonstrates how to use External Interrupt on PD10.
PD10 is external interrupt pin for click1 socket.
receive data from mosi line in each rising edge.
* Test configuration:
MCU: STM32F407VG
http://www.st.com/st-web-
ui/static/active/en/resource/technical/document/datasheet/DM00037051.pdf
dev.board: EasyMX PRO for STM32
http://www.mikroe.com/easymx-pro/stm32/
Oscillator: HSI-PLL, 140.000MHz
Ext. Modules: -
SW: mikroC PRO for ARM
http://www.mikroe.com/mikroc/arm/
* NOTES:
receive 32 bit data from mosi line in each rising edge
*/
//D10 clk
//D2 ss
//C0 MOSI
//C1 FLAG
int read=0;
int flag_int=0;
int val=0;
int rec_data[32];
int index_rec=0;
int display_index=0;
int flag_dint=0;
void ExtInt() iv IVT_INT_EXTI15_10 ics ICS_AUTO {
EXTI_PR.B10 = 1; // clear flag
flag_int=1; //Flag on interrupt
}
TFT_Init_ILI9340();
void main() {
GPIO_Digital_Input(&GPIOD_BASE, _GPIO_PINMASK_10);
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_13); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_12); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_14); // Set PORTD as
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_15); // Set PORTD as
digital output
GPIO_Digital_Input(&GPIOA_IDR, _GPIO_PINMASK_0); // Set PA0 as
digital input
GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_0); // Set PA0 as
digital input
GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_2); // Set PA0 as
digital input
GPIO_Digital_Output(&GPIOC_IDR, _GPIO_PINMASK_1); // Set PA0 as
digital input
//interupt register
SYSCFGEN_bit = 1; // Enable clock for alternate pin
functions
SYSCFG_EXTICR3 = 0x00000300; // Map external interrupt on PD10
EXTI_RTSR = 0x00000000; // Set interrupt on Rising edge
(none)
EXTI_FTSR = 0x00000400; // Set Interrupt on Falling edge
(PD10)
EXTI_IMR |= 0x00000400; // Set mask
//NVIC_IntEnable(IVT_INT_EXTI15_10); // Enable External interrupt
while(1)
{
//interrupt is not enable until i push the button
if((GPIOD_ODR.B2==0)&&(flag_dint==0))
{ if (Button(&GPIOA_IDR, 0, 1, 1))
{
Delay_ms(100);
GPIOC_ODR.B1=1; //Status for FPGA
NVIC_IntEnable(IVT_INT_EXTI15_10); // Enable External interrupt
}
}
if(flag_int==1)
{
//functionality on rising edge
flag_int=0;
if(index_rec<31)
{
//display data on led
GPIOD_ODR.B13= GPIOC_IDR.B0;
//save data in an array
rec_data[index_rec]= GPIOC_IDR.B0;
//read data
index_rec=index_rec+1;
}
else
{
flag_dint=1;
NVIC_IntDisable(IVT_INT_EXTI15_10);
}
} // Infinite loop
}
}
无需深入了解您的具体代码,请参阅 PeterJ_01 的评论,时钟速率问题可以通过您假设中对吞吐量的误解来解释。
你假设你的 STM 设备有一个 168Mhz 的时钟,它可以维持相同的中断吞吐量,你似乎保守地放宽到 1Mhz。
然而,它能够支持的中断吞吐量是设备处理每个中断所用时间的倒数。此时间包括处理器进入服务路由(即检测中断、中断当前代码并解析从向量 table 跳转到的位置)所花费的时间以及执行服务例程所花费的时间。
让我们超级乐观地说,进入例程需要 1 个周期,路由本身需要 3 个(2 个用于您设置的标志,1 个用于跳出例程)。这给出 4 个周期在 168Mhz 是 23.81ns,取反 42Mhz。这也可以通过将您将达到的最大频率 (168Mhz) 除以处理所花费的周期数来计算。
因此我们真正乐观的界限是 42Mhz,但实际上会更低。为了获得更准确的估计,您应该测试您的实施时间并深入研究您的设备文档以查看中断响应时间。