打印

GD32F470 DMA 写入SPI Flash,第一节多写入一个0

[复制链接]
849|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lslacteer|  楼主 | 2024-11-6 16:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        GD32F470 使用SPI 的DMA对SPI Flash写入时,写入位置的第一字节被写入了一个0,数据依次被写入到后面位置,如写入flash位置从0开始写入 100字节个数据(如 1,2,3.....100)。再从0位置读出100个,数据为(0,1,2,3...99) 第101个的位置为100。请问这个什么原因引起的。
SPI 与 DMA 的初始函数如下。

void DMA1_Channel3_IRQHandler(void)
{
    if(dma_interrupt_flag_get(DMA1, DMA_CH3, DMA_INT_FLAG_FTF))
    {
        // 清除中断标志位
        dma_interrupt_flag_clear(DMA1, DMA_CH3, DMA_INT_FLAG_FTF);
        // 在这里进行传输完成后的操作,例如关闭SPI Flash片选信号等
        SPI_FLASH_CS_HIGH();
                          printf("数据发送完成\n");
        // 可以进行其他数据处理或者触发下一次传输等操作
    }
}

void spi_flash_init(void)
{
    spi_parameter_struct spi_init_struct;

    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI0);

    /* SPI0_CLK(PB3), SPI0_MISO(PB4), SPI0_MOSI(PB5) GPIO pin configuration */
    gpio_af_set(GPIOB, GPIO_AF_5, GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);

    /* SPI0_CS(PE2) GPIO pin configuration */
          rcu_periph_clock_enable(RCU_GPIOE);
    gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* chip select invalid */
    SPI_FLASH_CS_HIGH();

    /* SPI0 parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_32;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI0, &spi_init_struct);


    /* enable SPI0 */
    spi_enable(SPI0);
}


// DMA初始化函数
void dma_init(uint8_t *data_buffer, uint32_t data_length)
{
    dma_single_data_parameter_struct dma_init_struct;

    rcu_periph_clock_enable(RCU_DMA1);

    dma_deinit(DMA1, DMA_CH3);

    // DMA初始化参数设置
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
       
    dma_init_struct.memory0_addr = (uint32_t)data_buffer;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
       
       
          dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
       
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
       
    dma_init_struct.number = data_length+4;

    dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
    dma_init_struct.priority = DMA_PRIORITY_LOW;
          dma_single_data_mode_init(DMA1, DMA_CH3,  &dma_init_struct);
       
          dma_channel_subperipheral_select(DMA1, DMA_CH3, DMA_SUBPERI3);

    // 使能DMA中断通道
    nvic_irq_enable(DMA1_Channel3_IRQn, 0, 0);
    // 配置DMA中断使能位
        // dma_circulation_disable(DMA1, DMA_CH3);
         dma_interrupt_enable(DMA1, DMA_CH3, DMA_CHXCTL_FTFIE);
         
         

}

int8_t spi_dma_data_send(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write)
{
       
       
          /* enable the write access to the flash */
    spi_flash_write_enable();

    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();
       

       
           pbuffer[0] = WRITE;
           pbuffer[1] = (write_addr & 0xFF0000) >> 16;
           pbuffer[2] = (write_addr & 0xFF00) >> 8;
           pbuffer[3] = write_addr & 0xFF ;
       
       
          if(st_spi_flash_err.SpiSendRecv !=0)//以上操作其中之一发生超时,出错
          {
                            printf("SPI Send Buffer Empty Timeout Error!\n");
                            SPI_FLASH_CS_HIGH();
                            return -1;
                }
       
               
                dma_channel_disable(DMA1, DMA_CH3);
       
          /* set DMA Memory base address */
          dma_memory_address_config(DMA1, DMA_CH3, DMA_MEMORY_0, (uint32_t)pbuffer);
       
          /* set the number of remaining data to be transferred by the DMA */
          dma_transfer_number_config(DMA1, DMA_CH3,4 + num_byte_to_write);
       
           /* enable DMA channel */
          dma_channel_enable(DMA1, DMA_CH3);
               
                spi_dma_enable(SPI0,SPI_DMA_TRANSMIT);
               
                return 0;
       
       
}




使用特权

评论回复
沙发
elephant00| | 2024-11-13 11:58 | 只看该作者
在配置DMA时,如果没有正确设置传输的起始地址、传输长度或数据宽度等参数,可能会导致DMA在传输过程中出现异常。特别是如果起始地址设置不正确,或者传输长度没有包括要写入的第一字节,就可能出现这种情况。

使用特权

评论回复
板凳
两只袜子| | 2024-11-13 13:00 | 只看该作者
如果SPI的时钟极性或相位设置不正确,或者没有正确配置SPI的数据长度和顺序,都可能导致数据写入异常。

使用特权

评论回复
地板
cr315| | 2024-11-13 14:23 | 只看该作者
SPI Flash本身具有一些写入特性,如写入前需要擦除、写入时有一定的时序要求等。如果在进行写入操作前没有正确擦除Flash区域,或者写入时序不满足Flash的要求,也可能导致写入异常。

使用特权

评论回复
5
classroom| | 2024-11-13 18:02 | 只看该作者
检查SPI的配置参数,包括时钟极性、相位、数据长度和顺序等

使用特权

评论回复
6
powerantone| | 2024-11-13 19:00 | 只看该作者
检查DMA的配置参数,确保起始地址、传输长度和数据宽度等设置正确。

使用特权

评论回复
7
laocuo1142| | 2024-11-13 21:00 | 只看该作者
软件或固件问题

使用特权

评论回复
8
flycamelaaa| | 2024-11-13 21:00 | 只看该作者
硬件连接问题

使用特权

评论回复
9
stormwind123| | 2024-11-13 22:26 | 只看该作者
检查SPI总线上的信号线连接是否良好

使用特权

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

本版积分规则

2

主题

2

帖子

0

粉丝