完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用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); } |
|
相关推荐
6个回答
|
|
固件或驱动程序中的bug可能导致DMA传输异常。
|
|
|
|
SPI时钟频率与DMA的传输速度不匹配,可能导致数据在传输过程中出现错位。
|
|
|
|
DMA的传输数量或地址设置可能不正确,导致数据未能完整或准确地写入flash。
|
|
|
|
使用的MCU或SPI flash芯片可能存在硬件缺陷或兼容性问题。
|
|
|
|
可能是DMA配置错误
|
|
|
|
出现错位现象的原因可能有以下几点:
1. DMA配置问题:可能是DMA配置不正确,导致数据传输出现错位。请检查DMA的配置参数,确保它们与您的硬件和需求相匹配。 2. SPI配置问题:可能是SPI配置不正确,导致数据传输出现错位。请检查SPI的配置参数,确保它们与您的硬件和需求相匹配。 3. 时序问题:可能是时序问题导致数据传输出现错位。请检查您的时序参数,确保它们与您的硬件和需求相匹配。 4. 硬件问题:可能是硬件问题导致数据传输出现错位。请检查您的硬件连接和硬件设备,确保它们工作正常。 为了解决这个问题,您可以尝试以下步骤: 1. 检查DMA配置:请检查您的DMA配置参数,确保它们与您的硬件和需求相匹配。您可以参考GD32F470VIT6和GD25Q40C的数据手册,了解正确的配置参数。 2. 检查SPI配置:请检查您的SPI配置参数,确保它们与您的硬件和需求相匹配。您可以参考GD32F470VIT6和GD25Q40C的数据手册,了解正确的配置参数。 3. 检查时序参数:请检查您的时序参数,确保它们与您的硬件和需求相匹配。您可以参考GD32F470VIT6和GD25Q40C的数据手册,了解正确的时序参数。 4. 检查硬件连接:请检查您的硬件连接,确保它们正确无误。如果可能,请尝试更换硬件设备,以排除硬件问题。 5. 调试代码:您可以使用调试工具(如Keil MDK-ARM)来调试您的代码,查看DMA和SPI的运行情况,找出问题所在。 6. 更新固件和库文件:请确保您的固件和库文件是最新的,以便获得最佳性能和稳定性。 希望以上建议能帮助您解决问题。如果问题仍然存在,请提供更多详细信息,以便我们进一步分析和解决。 |
|
|
|
只有小组成员才能发言,加入小组>>
299 浏览 1 评论
509 浏览 2 评论
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
747 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
638 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1107 浏览 1 评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
223浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
180浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
45浏览 13评论
在使用3254进行录音的时候出现一个奇怪的现象,右声道有吱吱声,请教一下,是否是什么寄存器设置存在问题?
149浏览 13评论
TLV320芯片内部自带数字滤波功能,请问linein进来的模拟信号是否是先经过ADC的超采样?
152浏览 12评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-16 07:54 , Processed in 1.138305 second(s), Total 89, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号