进入在线调试试试看,先建立一个存放SPI数据的变量,看看有没有数据;还可以在DMA中断函数设置一个FLAG,如果进入中断置1否则为0;如果是0的话确实没有进中断,那要看看你的配置了,对照例子再仔细看看吧!
复位移位寄存器,清除多余数据,重置DMA计数器。
通过RCC寄存器将整个SPI模块复位,然后重新配置SPI。DMA不要复位,但是必须先停止DMA,SPI复位完成之后,重新配置DAM收发计数器值,再打开DMA。
SPI是“解决方案销售方法”的知识产权所有者,这是一种全球公认的销售培训,为销售人员和管理人员提供成熟、完整、端到端的专业发展计划。
stm32 DMA错误无法恢复问题
stm32f446,程序中需要ADC1、ADC3和DAC同时工作。
首先,在此工程的STM32G474版中,使用TIM8同时触发2个AD、一个DA工作,所以在STM32F446版中也使用此策略,结果无法实现。
所以使用了TIM8-trog触发ADC1,TIM8-ch1触发ADC3,TIM6触发DAC输出波形。
在长时间运行后,或者反复进出jlink调试,会导致ADC的DMA过程受阻,ADC的OVERRUN位置位,一般清除此位后即可恢复运行
后来DMA数据进一步增加,即使清除OVERRUN位,也不会恢复工作了。
由于此时设备已经发到客户手中,即使能够复现,也无法调试。所以费了很大的劲,通过反复进出调试器的方式复现了错误,然后在调试器中对ADC、DMA等寄存器进行操作。发现此时连续扫描型的ADC并未受影响,仍然通过DMA传出数据。只是定时器触发的ADC阻塞,并且,DMA寄存器不受控了,写入值也不发生变化。
通过复位DMA时钟的方式,才改变了DMA寄存器的值。然后给DMA重新初始化,程序又开始工作了:
1 RCC-AHB1RSTR |= RCC_AHB1Periph_DMA2;2 RCC-AHB1RSTR = ~RCC_AHB1Periph_DMA2;3 RCC-AHB1ENR = ~RCC_AHB1Periph_DMA2;4 RCC-AHB1RSTR |= RCC_AHB1Periph_DMA2;5 RCC-AHB1RSTR = ~RCC_AHB1Periph_DMA2;
也不知道这个RSTR是在ENR之前还是之后,所以反复写了两遍
但是这个AD用的DMA2,在ADC2上也使用了,所以ADC2也需要重新初始化。结果ADC2通过重启时钟的方式,寄存器不会归零,必须人工归零后才能使用。
STM32的SPI使用DMA传输的方法,根据自己的硬件特性需要更改一些设置。
void DMA_SPI2_Transfer(void)
{
DMA_Cmd( DMA1_Channel5, DISABLE);
DMA_Init( DMA1_Channel5, DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_HT5);
DMA_Cmd( DMA1_Channel5, ENABLE);
}
void DMA_SPI2_Init(BYTE *data, uint32_t size)
{
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit( DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(SPI2-DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) data;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = size ;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init( DMA1_Channel5, DMA_InitStructure);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
}
去掉DMA的初始化函数即可,若想在运行过程中退出,失能DMA即可。
本文标签:如何复位stm32的spi和dma