-
使用 DMA写flash后,读取数据出现错位现象
使用 DMA写flash后,读取数据出现错位现象,读到的buffer 的第一节总为0,从第二字节开始才是正常数据。只能在24bit地址发送完后,再发一个DUMMY_BYTE(无效字节),才能bufferr接收数据。 一但调“dma_channel_enable(DMA1, DMA_CH3)这个使能”后就出现上述现象。每次读取数据时都要先发一个DUMMY_BYTE才能正确接收。若上电不调“dma_channel_enable(DMA1, DMA_CH3)“接收都是正常的。使用的MCU是GD32F470VIT6,SPI FLAH是GD25Q40C. 请各位大佬帮忙分析下。 以下为SPI代码 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发送 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; dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE; dma_init_struct.priority = DMA_PRIORITY_MEDIUM; 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); } DMA发送 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(); /* send "write to memory" instruction */ spi_flash_send_byte(WRITE); /* send read_addr high nibble address byte to read from */ spi_flash_send_byte((write_addr & 0xFF0000) >> 16); /* send read_addr medium nibble address byte to read from */ spi_flash_send_byte((write_addr& 0xFF00) >> 8); /* send read_addr low nibble address byte to read from */ spi_flash_send_byte(write_addr & 0xFF); dma_channel_disable(DMA1, DMA_CH3); spi_dma_disable(SPI0,SPI_DMA_TRANSMIT); dma_memory_address_config(DMA1, DMA_CH3, DMA_MEMORY_0, (uint32_t)(pbuffer)); dma_transfer_number_config(DMA1, DMA_CH3, num_byte_to_write); spi_dma_enable(SPI0,SPI_DMA_TRANSMIT); dma_channel_enable(DMA1, DMA_CH3); return 0; } DMA接收 int8_t spi_dma_data_recv(uint8_t* pbuffer, uint32_t read_addr, uint16_t num_byte_to_write) { uint8_t dumyy_byte = 0xA5; //spi_flash_wait_for_write_end(); /* select the flash: chip slect low */ SPI_FLASH_CS_LOW(); /* send "read from memory " instruction */ spi_flash_send_byte(READ); /* send read_addr high nibble address byte to read from */ spi_flash_send_byte((read_addr & 0xFF0000) >> 16); /* send read_addr medium nibble address byte to read from */ spi_flash_send_byte((read_addr& 0xFF00) >> 8); /* send read_addr low nibble address byte to read from */ spi_flash_send_byte(read_addr & 0xFF); spi_flash_send_byte(0xA5); //为应对错位,多加的一个DUMMY_BYTE dma_channel_disable(DMA1, DMA_CH3); dma_channel_disable(DMA1, DMA_CH2); spi_dma_disable(SPI0,SPI_DMA_TRANSMIT); spi_dma_disable(SPI0,SPI_DMA_RECEIVE); dma_memory_address_config(DMA1, DMA_CH3, DMA_MEMORY_0, (uint32_t)(&dumyy_byte)); //设置发送无效字节 dma_periph_width_config(DMA1, DMA_CH3, DMA_MEMORY_INCREASE_DISABLE);//取消地址自动增长 dma_transfer_number_config(DMA1, DMA_CH3, num_byte_to_write);//设置产生时钟脉冲个数 dma_memory_address_config(DMA1, DMA_CH2, DMA_MEMORY_0, (uint32_t)pbuffer);//设置接收数据位 dma_transfer_number_config(DMA1, DMA_CH2, num_byte_to_write);//设置产生时钟脉冲个数 /* enable DMA channel */ spi_dma_enable(SPI0,SPI_DMA_TRANSMIT); //SPI使能DMA发送功能 spi_dma_enable(SPI0,SPI_DMA_RECEIVE); /* enable DMA channel */ dma_channel_enable(DMA1, DMA_CH2); //使能DMA接收 dma_channel_enable(DMA1, DMA_CH3); //使能DMA发送 /* while there is data to be written on the flash */ } spi初始化 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); }
652浏览量 15回复量 关注量