STM32F767ZI外部中断处理

时间:2018-11-14 13:22:32

标签: c++ c interrupt stm32f7

我正在尝试为AD7768-4 ADC创建合适的SPI从接口。 ADC具有SPI接口,但不通过SPI输出转换。取而代之的是,有数据输出在单独的GPIO引脚上输出。因此,我基本上需要对数据进行位冲击处理,然后输出到SPI,以获得正确的从SPI接口。请不要问为什么我要这样做,它是分配给我的。

我遇到的问题是中断。我正在使用STM32F767ZI处理器-它以216 MHz运行,我的ADC数据必须以20 MHz输出。我已经设置了NMI,但是我没有看到的是系统调用或指向中断处理程序的位置。

我使用STMCubeMX软件分配了引脚并生成了设置代码,在stm32F7xx.c文件中,它显示了NMI_Handler()函数,但是在系统文件。我还在HAL_GPIO_EXTI_IRQHandler()中发现了无效的STM32F7xx_hal_gpio.c函数,该函数似乎要检查该引脚是否被置为有效,并清除所有挂起的位,但它不会重置中断标志,也不会再次检查该中断标志,我看不到此功能的指针。

为了使事情更复杂,我有10个时钟周期来确定设置哪个标志(一次两个),重置它,确定一个变量,并从GPIO寄存器中移动数据。我相信这是有可能的,但是同样,我不确定中断被触发后系统正在做什么。

是否有人在处理此处理器上的外部中断方面有任何经验,从而可以了解此特定系统的处理方式?再次-10个时钟周期来做我需要做的...移动数据只需要1-2个时钟周期,剩下8个时钟周期来处理中断...

编辑:

我们将DCLK速度更改为5.12 MHz(20.48 MHz MCLK / 4),因为在2.56 MHz时,我们有12.5微秒的时间来传出数据并为下一个DRDY脉冲进行设置,而80 kHz的速度恰好为我们提供了零余量。在5.12 MHz下,我有41个时钟周期来运行中断例程,如果我跳过检查第二个标志并仅处理传入数据,则可以略微减少。但是我觉得我至少必须使用DRDY标志检查,并使用例程来启用第二个中断,否则我将不断中断,因为ADC上的DCLK始终在运行。这使我可以在下一个DRDY脉冲之前读入6.12微秒的数据,并用6.25微秒对数据进行洗牌。我应该能够在32 MHz的SPI时钟(从机)上执行此操作,但最有可能在50MHz的条件下执行。这是我当前的中断代码:

void NMI_Handler(void)
{
    if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)         
     {
         count = 0;                                             
         __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);                  
         HAL_GPIO_EXTI_Callback(GPIO_PIN_0);                        
         //     __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);             

         HAL_NVIC_EnableIRQ(GPIO_PIN_1);                            
     }  
    else
  {  
        if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1) != RESET)         
          {
             data_pad[count] = GPIOF->IDR;                      
             count++;                                           
             if (count == 31)
              {
                data_send = !data_send;                     
                HAL_NVIC_DisableIRQ(GPIO_PIN_1);            
              }
        __  HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);         
        HAL_GPIO_EXTI_Callback(GPIO_PIN_1); 
//      __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0); 
          }
   }
}  

我仍然担心时钟周期,如果我以唯一会跳闸的其他EXTI标志为时钟引脚为前提,我相信只要检查DRDY标志就可以摆脱困境。尽管我怀疑如果SYS_TICK在后台运行,这将如何工作……我必须找出答案。

我们正在研究一种更快的处理器来处理位冲击,但是现在,如果PI3在Linux上运行,它似乎将无法对其进行处理,而且我不知道有太多的更快的处理器运行非常小的可靠的RTOS,或者可以在紧急状态下对裸机进行编程...

3 个答案:

答案 0 :(得分:3)

  

做我需要做的10个时钟周期...移动数据只需要1-2个时钟周期,剩下8个时钟周期来处理中断...

不可能。即使在Cortex-M7上,中断进入(推入寄存器,获取向量并填充管线)也需要10-12个周期。然后考虑一个非常简单的中断处理程序,只需将输入数据位移至缓冲区并清除中断标志即可:

uint32_t *p;
void handler(void) {
    *p++ = GPIOA->IDR;
    EXTI->PR = 0x10;
}

它被翻译成这样的东西

handler:
    ldr     r0, .addr_of_idr // load &GPIOA->IDR
    ldr     r1, [r0]         // load GPIOA->IDR
    ldr     r2, .addr_ofr_p  // load &p
    ldr     r3, [r2]         // load p
    str     r1, [r3]         // store the value from IDR to *p
    adds    r3, r3, #4       // increment p
    str     r3, [r2]         // store p
    ldr     r0, .addr_of_pr  // load &EXTI->PR
    movs    r1, #0x10
    str     r1, [r0]         // store 0x10 to EXTI->PR
    bx      lr
.addr_of_p:
    .word   p
.addr_of_idr
    .word   0x40020010
.addr_of_pr
    .word   0x40013C14

因此,这是11条指令,每个指令在中断输入后 至少需要一个周期。假设代码,向量表和堆栈都位于最快的RAM区域中。我不确定文字池是否完全可以在ITCM中工作,使用立即文字会增加3个周期。算了。

这必须通过硬件解决。

控制器具有6个SPI接口,请选择其中的4个。将DRDY连接到所有四个NSS引脚,将DCLK连接到所有SCK引脚,并将每个DOUT引脚连接到一个MISO引脚。现在,每个SPI接口只能处理一个通道,并且可以在其内部FIFO中收集多达32位。

然后,我将在NSS引脚之一的上升沿上设置一个中断(即使该引脚处于备用功能模式,EXTI仍然可以工作),并立即读取所有数据。

编辑

事实证明,STM32 SPI要求NSS下降和SCK上升之间的延迟量是AD7768无法提供的,因此它将不起作用。

Sigma-Delta接口

STM32F767具有DFSDM外设,旨在接收来自外部ADC的数据。它可以接收多达8个20 MHz串行数据通道,甚至可以进行应用程序可能需要的一些预处理。

问题在于DFSDM没有DRDY输入,我不完全知道如何同步数据传输。可以通过断言START#信号来重置通信来工作。

如果这不起作用,则可以尝试使用计时器和DMA启动DFSDM通道。将DRDY连接到TIM1TIM8的外部触发器(其他定时器不起作用,因为它们已连接到较慢的APB1总线和另一个DMA控制器),请在ETR的上升沿,并使其在约20 ns后生成DMA请求。然后,让DMA将启动通道所需的值写入DFSDM通道配置寄存器。重复其他三个频道。

答案 1 :(得分:0)

在编译之前会生成一个启动文件:startup_stm32f767xx.s-包含指向函数的所有指针。

标记g_pfnVectors:下的.word NMI_Handler指向用于处理非屏蔽中断的函数,另外两个指针.word EXTI0_IRQHandler.word EXTI1_IRQHandler作为指向外部的向量中断处理程序。在同一文件的最下方,是以下编译器指令:

.weak      NMI_Handler  
.thumb_set NMI_Handler,Default_Handler

.weak      EXTI0_IRQHandler         
.thumb_set EXTI0_IRQHandler,Default_Handler

.weak      EXTI1_IRQHandler         
.thumb_set EXTI1_IRQHandler,Default_Handler  

这就是我想要的信息,它能够以更高的精度和更少的时钟周期来控制我的中断。

答案 2 :(得分:0)

我仔细阅读了AD7768 DS,发现它可以将四个通道的数据存储到一个DOUT引脚。因此,我再次谈论串行音频接口(SAI)。

如果您可以将DCLK的频率降低至2.5MHz,而不是在完整的ADC时钟下以1:8的比率(从2.5 MHz到20 MHz的比率)降低采样率,则可以降低采样率。

如果将所有4个通道路由到一个输出DOUT0,则会以1:4的比率降低采样率。

AD7768-4 DS

第53页

  

在AD7768上,可以将接口配置为输出转换   DOUTx引脚之一,两个或八个上的数据。 DOUTx配置   使用FORMATx引脚选择AD7768的引脚(参见表33)。

第66页表34:(对于AD7768-4) 第67页图98:

  

FORMAT0 = 1所有通道在TDM输出中的DOUT0引脚上输出。仅使用DOUT0。

您可以将SAIFS = DRDY一起使用,并使用四个插槽(每插槽32位)