SPI 的DMA 模式 只有第一次成功

2019-10-15 04:10发布

本帖最后由 simms01 于 2016-1-18 18:02 编辑

程序主题大概如下
void dma(void)
{
  u8 buf[16];
u16 j,i;

for (i=0;i<16;i++)
{
buf=i;
}


//初始化spi2
SPI2_Init(MSB);
//设置dma
MYDMA_Config(DMA1_Channel5 ,(u32)&SPI2->DR,(u32)buf,16);//DMA1通道4,外设为SPI2,存储器为SendBuff,长度5168.
//传输2000次
for (j=0;j<2000;j++)
{

MYDMA_Enable(DMA1_Channel5);
  //等待传输完成
  while( ( DMA1->ISR & (1<<17) ) == 0  ) ;
}
}

//**************************//*************************
只有开机第一次call 这个 dma()  spi的数据发出来是正常的  再call 就错了

buf[]的数据没有错 只要不用DMA 用硬件SPI发出来是正确的

//***************************DMAd的设置
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=1<<0;   //开启DMA1时钟
//RCC->AHBENR|=1<<1;   //开启DMA2时钟
delay_ms(5);    //等待DMA时钟稳定
DMA_CHx->CPAR=cpar;    //DMA1 外设地址
DMA_CHx->CMAR=(u32)cmar;  //DMA1,存储器地址
DMA1_MEM_LEN=cndtr;       //保存DMA传输数据量
DMA_CHx->CNDTR=cndtr;     //DMA1,传输数据量
DMA_CHx->CCR=0X00000000; //复位
DMA_CHx->CCR|=1<<4;    //从存储器读
DMA_CHx->CCR|=0<<5;    //普通模式
DMA_CHx->CCR|=0<<6;   //外设地址非增量模式
DMA_CHx->CCR|=1<<7;    //存储器增量模式
DMA_CHx->CCR|=0<<8;    //外设数据宽度为8位
DMA_CHx->CCR|=0<<10;   //存储器数据宽度8位
DMA_CHx->CCR|=1<<12;   //中等优先级
DMA_CHx->CCR|=0<<14;   //非存储器到存储器模式     
}
//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_CHx->CCR&=~(1<<0);       //关闭DMA传输
DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量
DMA_CHx->CCR|=1<<0;          //开启DMA传输
}   

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
xkwy
2019-10-15 07:33
我有一次不小心也遇到过类似问题。

先说结论:
DMA的源地址千万不要设置为局部变量(数组)的地址!
DMA的源地址千万不要设置为局部变量(数组)的地址!
DMA的源地址千万不要设置为局部变量(数组)的地址!



针对你的问题,DMA能发送,说明DMA肯定配置好了。
你把DMA的源地址指向一个局部变量buf,但你知否,一旦void dma(void)这个函数执行完毕,buf这个存储在栈的数组要被弹出来的!
因此,DMA的源地址是一个野指针,野指针!!

解决方法,把buf的定义放在函数外面,或者定义成静态的。

另外,你的函数能编译通过吗?
buf=i;

这不会报错??

一周热门 更多>