stm32使用SPI用dma通道写SD卡程序卡死
在不使用DMA的情况下是正常读写的,但是改用DMA以后运行时卡死,大概是在这个位置,检测传输完成标志位循环中卡死
#if EN_SPI_Tx_DMA //如果使用SPI发送的DMA
DMA_Cmd(DMA1_Channel3,ENABLE); //使能DMA1通道3发送指令
while(DMA_GetFlagStatus(DMA1_FLAG_TC3)==RESET);//等待DMA传输完成
{
printf("1");
DMA_Cmd(DMA1_Channel3,DISABLE);//关闭DMA1通道3指令
DMA_ClearFlag(DMA1_FLAG_TC3); //清除传输完成标志位;
}
另外DMA和SPI的配置如下:
void DMA_Tx_Init( DMA_Channel_TypeDef* DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize)
{
DMA_InitTypeDef DMA_InitStructure={0};
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );
DMA_DeInit(DMA_CHx);
DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr;
DMA_InitStructure.DMA_MemoryBaseAddr = memadr;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = bufsize;
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( DMA_CHx, &DMA_InitStructure );
//DMA_Cmd(DMA1_Channel3,DISABLE); //关闭DMA1通道3发送指令
}
void SPIx_Init(uint16_t speed)
{
uint16_t tmp;
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
//SPI_FLASH_SPI pins: SCK--PA5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SPI_FLASH_SPI pins: MISO--PA6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SPI_FLASH_SPI pins: MOSI--PA7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SPI_FLASH_SPI_CS_PIN pin: CS--PA4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_CS_HIGH();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI1设置为两线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI1为主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个时钟沿开始采样数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure);
switch(speed) //设置波特率预分频的值
{
case 2:
tmp = SPI_BaudRatePrescaler_2;break;
case 4:
tmp = SPI_BaudRatePrescaler_4;break;
case 8:
tmp = SPI_BaudRatePrescaler_8;break;
case 16:
tmp = SPI_BaudRatePrescaler_16;break;
case 32:
tmp = SPI_BaudRatePrescaler_32;break;
case 64:
tmp = SPI_BaudRatePrescaler_64;break;
case 128:
tmp = SPI_BaudRatePrescaler_128;break;
case 256:
tmp = SPI_BaudRatePrescaler_256;break;
default:
break ;
}
SPI_InitStructure.SPI_BaudRatePrescaler=tmp; //波特率预分频值
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
uint32_t buf2[512];//SD卡数据缓存区
DMA_Tx_Init( DMA1_Channel3, (u32)&SPI1->DR, (u32)buf2, 512 );