STM32F446 SPI DMA

问题描述 投票:0回答:1

我使用SPI1 DMA将数据从STM32F446RET6发送到Nokia5110 LCD。但这不起作用。当我尝试不使用 DMA 时,它可以工作。难道我的程序错了?完整的程序可以通过以下链接下载。可以用STM32 Cube IDE打开。 https://easyupload.io/m78pr9

static void initSPI1(void)
{
    // PA5, PA6, PA7 AS AF7
    RCC->AHB1ENR |= 1<<0;
    GPIOA->MODER &= ~(1<<10 | 1<<12 | 1<<14);
    GPIOA->MODER |= 1<<11 | 1<<13 | 1<<15;
    GPIOA->AFR[0] |= 1<<20 | 1<<22 | 1<<24 | 1<<26 | 1<<28 | 1<<30;

    // SPI1 CONFIG
    RCC->APB2ENR |= 1<<12;
    SPI1->CR1 |= 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<8 | 1<<9;
    SPI1->CR2 |= 1<<1; // ENABLE TX DMA
    SPI1->CR1 |= 1<<6; // ENABLE SPI1

    // DMA2 CONFIG
    RCC->AHB1ENR |= 1<<22;
    DMA2_Stream3->CR |= 1<<4 | 1<<6 | 1<<8 | 1<<10 | 1<<25 | 1<<26;
}

static void sendChar(char character)
{
    GPIOA->ODR &= ~(1<<0); // CS_PIN_LOW

    DMA2_Stream3->NDTR = 1;
    DMA2_Stream3->PAR = (uint32_t) &SPI1->DR;
    DMA2_Stream3->M0AR = (uint32_t) character;
    DMA2_Stream3->CR |= 1<<0;

    while(!(DMA2->LISR & 1<<27));
    DMA2_Stream3->CR &= ~(1<<0);
    DMA2->LIFCR |= 1<<27;

//  send char without dma
//  SPI1->DR = character;
//  while(!(SPI1->SR & 1<<1));
//  while(SPI1->SR & 1<<7);
//
//  (void) SPI1->DR;
//  (void) SPI1->SR;

    GPIOA->ODR |= 1<<0; // CS_PIN_HIGH
}
stm32 spi dma stm32f4
1个回答
0
投票

查看在注册表中为带有 DMA 的 SPI 编写的示例代码,似乎您需要启用 DMA 中断。您的代码可读性较差,因此请尝试使用下面的代码片段自行检查您是否正确完成了所有寄存器配置。

/**
  * @brief  This function :
             - Enables GPIO clock
             - Configures the SPI1 pins on GPIO PA4 PA5 PA6 PA7
  * @param  None
  * @retval None
  */
    __INLINE void Configure_GPIO_SPI1(void)
{
  /* Enable the peripheral clock of GPIOA */
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    
  /* (1) Select AF mode (10) on PA4, PA5, PA6, PA7 */
  /* (2) AF0 for SPI1 signals */
  GPIOA->MODER = (GPIOA->MODER 
                  & ~(GPIO_MODER_MODER4 | GPIO_MODER_MODER5 | \
                      GPIO_MODER_MODER6 | GPIO_MODER_MODER7))\
                  | (GPIO_MODER_MODER4_1 | GPIO_MODER_MODER5_1 |\
                     GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); /* (1) */
  GPIOA->AFR[0] = (GPIOA->AFR[0] & \
                   ~(GPIO_AFRL_AFRL4 | GPIO_AFRL_AFRL5 |\
                     GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)); /* (2) */
}

/**
  * @brief  This function configures DMA for SPI1.
  * @param  None
  * @retval None
  */
__INLINE void Configure_DMA1_SPI1(void)
{
  /* Enable the peripheral clock DMA11 */
  RCC->AHBENR |= RCC_AHBENR_DMA1EN;
  
  /* DMA1 Channel3 SPI1_TX config */
  /* (5) Peripheral address */
  /* (6) Memory address */
  /* (7) Memory increment */
  /*     Memory to peripheral*/
  /*     8-bit transfer */
  DMA1_Channel3->CPAR = (uint32_t)&(SPI1->DR); /* (5) */
  DMA1_Channel3->CMAR = (uint32_t)stringtosendwSPI1; /* (6) */
  DMA1_Channel3->CCR |= DMA_CCR_MINC | DMA_CCR_DIR; /* (7) */
  
  /* Configure IT */
  /* (8) Set priority for DMA1_Channel2_3_IRQn */
  /* (9) Enable DMA1_Channel2_3_IRQn */
  NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0); /* (8) */
  NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); /* (9) */
}

我还建议您使用 stm32cubeMX 工具进行代码生成,以获得简单的代码来处理您的任务。

© www.soinside.com 2019 - 2024. All rights reserved.