unsigned char DMA1_Init(void)
{
DMA_InitTypeDef DMA1_Init;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
//DMA2通道2用于RAM->SPI的数据传输
DMA_DeInit(DMA2_Channel2);//发送
DMA1_Init.DMA_PeripheralBaseAddr=(u32)&SPI3->DR;//SPI3_DR_Address (u32)&SPI3->DR
//DMA1_Init.DMA_MemoryBaseAddr=...; //启动传输前装入实际RAM地址
DMA1_Init.DMA_DIR=DMA_DIR_PeripheralDST;
DMA1_Init.DMA_BufferSize=1028;//1028
DMA1_Init.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA1_Init.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA1_Init.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA1_Init.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA1_Init.DMA_Mode=DMA_Mode_Normal;
DMA1_Init.DMA_Priority=DMA_Priority_High;
DMA1_Init.DMA_M2M=DMA_M2M_Disable;
DMA_Init(DMA2_Channel2,&DMA1_Init); //对DMA2通道2进行初始化
//DMA通道1用于SPI->RAM的数据传输
DMA_DeInit(DMA2_Channel1); //接收
DMA1_Init.DMA_PeripheralBaseAddr=(u32)&SPI3->DR;
//DMA1_Init.DMA_MemoryBaseAddr=...; //启动传输前装入实际RAM地址
DMA1_Init.DMA_DIR=DMA_DIR_PeripheralSRC;
DMA1_Init.DMA_BufferSize=1028;//512
DMA1_Init.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA1_Init.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA1_Init.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA1_Init.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA1_Init.DMA_Mode=DMA_Mode_Normal;
DMA1_Init.DMA_Priority=DMA_Priority_High;
DMA1_Init.DMA_M2M=DMA_M2M_Disable;
DMA_Init(DMA2_Channel1,&DMA1_Init); //对DMA通道1进行初始化
SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Rx,ENABLE); //使能SPI的DMA接收请求
SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE); //使能SPI的DMA发送请求
return 0;
}
unsigned char DMA1_Star_SPI_RX(u8 *buffer,u16 len)
{
//DMA_DeInit(DMA2_Channel1); //接收
unsigned char temp=0xff;
DMA2_Channel1->CNDTR=len; //设置传输的数据长度
DMA2_Channel1->CMAR=(unsigned long)buffer; //设置内存缓冲区地址
/*SPI作为主机进行数据接收时必须要主动产生时钟,因此此处必须有DMA通道2的配合*/
DMA2_Channel2->CNDTR=len;
DMA2_Channel2->CMAR=(u32)&temp; //temp=0xff
DMA2_Channel2->CCR&=~DMA_MemoryInc_Enable; //内存地址非自增
DMA_Cmd(DMA2_Channel1,ENABLE); //首先启动DMA通道1
DMA_Cmd(DMA2_Channel2,ENABLE); //再启动DMA通道2
while(!DMA_GetFlagStatus(DMA2_FLAG_TC1)); //等待DMA通道1接收数据完成
DMA_ClearFlag(DMA2_FLAG_TC1);
DMA_ClearFlag(DMA2_FLAG_TC2); //清除DMA通道1与2的传输完成标志
DMA_Cmd(DMA2_Channel1,DISABLE);
DMA_Cmd(DMA2_Channel2,DISABLE); //使DMA通道1与2停止工作
DMA2_Channel2->CCR|=DMA_MemoryInc_Enable; //将DMA通道2恢复为内存地址自增方式
return 0;
}
//向sd卡写入一个数据包的内容 len字节 启动DMA传输
//buf:数据缓存区
unsigned char DMA1_Star_SPI_TX(u8 *buffer,u16 len)
{
DMA2_Channel2->CNDTR=len; //设置要传输的数据长度//DMA2_Channel2->CNDTR=512;
DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Channel2,ENABLE); //启动DMA传输 RAM->SPI
while(!DMA_GetFlagStatus(DMA2_FLAG_TC2)); //等待DMA通道2传输完成
DMA_ClearFlag(DMA2_FLAG_TC2); //清除通道2传输完成状态标记
DMA_Cmd(DMA2_Channel2,DISABLE); //使DMA通道2停止工作
return 0;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我的理解就是,DMA2的通道2传输完成,也就是SPI3的传输完成。(DMA2 Channel2 transfer complete flag)
试了你的方法
unsigned char DMA1_Star_SPI_TX(u8 *buffer,u16 len)
{
#if 0
DMA2_Channel2->CNDTR=len; //设置要传输的数据长度//DMA2_Channel2->CNDTR=512;
DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Channel2,ENABLE); //启动DMA传输 RAM->SPI
while(!DMA_GetFlagStatus(DMA2_FLAG_TC2)); //等待DMA通道2传输完成
DMA_ClearFlag(DMA2_FLAG_TC2); //清除通道2传输完成状态标记
DMA_Cmd(DMA2_Channel2,DISABLE); //使DMA通道2停止工作
return 0;
#else
unsigned char temp=0xff;
DMA2_Channel1->CNDTR=len; //设置传输的数据长度
DMA2_Channel1->CMAR=(unsigned long)&temp; //设置内存缓冲区地址
/*SPI作为主机进行数据接收时必须要主动产生时钟,因此此处必须有DMA通道2的配合*/
DMA2_Channel2->CNDTR=len;
DMA2_Channel2->CMAR=(u32)buffer; //temp=0xff
DMA2_Channel1->CCR&=~DMA_MemoryInc_Enable; //内存地址非自增
DMA_Cmd(DMA2_Channel1,ENABLE); //首先启动DMA通道1
DMA_Cmd(DMA2_Channel2,ENABLE); //再启动DMA通道2
while(!DMA_GetFlagStatus(DMA2_FLAG_TC1)); //等待DMA通道1接收数据完成(停在这里)
DMA_ClearFlag(DMA2_FLAG_TC1);
DMA_ClearFlag(DMA2_FLAG_TC2); //清除DMA通道1与2的传输完成标志
DMA_Cmd(DMA2_Channel1,DISABLE);
DMA_Cmd(DMA2_Channel2,DISABLE); //使DMA通道1与2停止工作
DMA2_Channel1->CCR|=DMA_MemoryInc_Enable; //将DMA通道2恢复为内存地址自增方式
return 0;
#endif
}
发送函数放在
SPI_FLASH_CS_LOW();
Delay_ARMJISHU(20);
#if 0
for(i=0;i<bufferLength;i++)
{
//temp=buffer;//test
test_temp=SPI_FLASH_SendByte(buffer);
}
//(不带DMA,这里发送是正常的)
#else
DMA1_Star_SPI_TX(buffer,bufferLength);
#endif
Delay_ARMJISHU(20);
SPI_FLASH_CS_HIGH();
你的传输完成中断开了吗?
加了
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA2_Channel2, DMA_IT_TC, ENABLE);
还是不行
一周热门 更多>