初级会员

- 积分
- 101
- 金钱
- 101
- 注册时间
- 2014-7-27
- 在线时间
- 31 小时
|
void DMA1_Init(void) //DMA初始化程序
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
DMA_DeInit(DMA1_Channel2); //将DMA的通道2寄存器重设为缺省值
DMA_DeInit(DMA1_Channel3); //将DMA的通道3寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&SPI1->DR;//DMA外设基地址
//DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)pbuf; //DMA内存基地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize=512;
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority=DMA_Priority_High;
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道SPI1_Tx_DMA_Channel所标识的寄存器
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR; //DMA外设基地址
// DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设读取发送到内存
DMA_InitStructure.DMA_BufferSize = 512; //DMA通道的DMA缓存的大小,一个SD卡扇区大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常模式下
DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //DMA通道x拥有较高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel2, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道SPI1_Rx_DMA_Channel所标识的寄存器
SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE); //使能SPI1接收的DMA传输
SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE); //使能SPI1发送的DMA传输
}
//从sd卡读取一个数据包的内容
//buf:数据缓存区
//len:要读取的数据长度.
//返回值:0,成功;其他,失败;
u8 SD_RecvData(u8*buf,u16 len)
{
u8 dummyclock=0xff; //用于SPI接收的时钟
if(SD_GetResponse(0xFE))return 1; //等待SD卡发回数据起始令牌0xFE
DMA1_Channel2->CNDTR=512; //接收的数据个数
DMA1_Channel2->CMAR=(uint32_t)buf;//接收数据缓冲区地址
DMA1_Channel3->CNDTR=512; //发送的数据个数
DMA1_Channel3->CMAR=(uint32_t)&dummyclock;//此处的目的是给SPI的DMA接收添加时钟
DMA1_Channel3->CCR&=~DMA_MemoryInc_Enable;//发送内存区地址不增加,一直发送0xff接收时钟用
DMA_Cmd(DMA1_Channel2,ENABLE); //使能DMA1通道2指令
DMA_Cmd(DMA1_Channel3,ENABLE); //使能DMA1通道3指令
while(!DMA_GetFlagStatus(DMA1_FLAG_TC2));//等待DMA传输完成 ??? 读扇区一直卡死在这
DMA_ClearFlag(DMA1_FLAG_TC2); //清除通道2传输完成标志位
DMA_ClearFlag(DMA1_FLAG_TC3); //清除通道3传输完成标志位
DMA_Cmd(DMA1_Channel2,DISABLE); //关闭DMA1通道2指令
DMA_Cmd(DMA1_Channel3,DISABLE); //关闭DMA1通道3指令
DMA1_Channel3->CCR|=DMA_MemoryInc_Enable;//恢复发送内存区地址增加
// while(len--)//开始接收数据
// {
// *buf=SPI1_ReadWriteByte(0xFF);
// buf++;
// }
//下面是2个伪CRC(dummy CRC)
SD_SPI_ReadWriteByte(0xFF);
SD_SPI_ReadWriteByte(0xFF);
return 0;//读取成功
}
//向sd卡写入一个数据包的内容 512字节
//buf:数据缓存区
//cmd:指令
//返回值:0,成功;其他,失败;
u8 SD_SendBlock(u8*buf,u8 cmd)
{
u16 t;
if(SD_WaitReady())return 1;//等待准备失效
SD_SPI_ReadWriteByte(cmd);
if(cmd!=0XFD)//不是结束指令
{
//此处采用DMA方式传输
DMA1_Channel3->CNDTR=512;//在DMA传输计数器中写入要传输的数据个数
DMA1_Channel3->CMAR=(u32)buf; //发送数据缓冲区地址
DMA_Cmd(DMA1_Channel3,ENABLE); //使能DMA1通道3指令
while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));//等待DMA传输完成 ??? 写扇区一直卡死在这
DMA_ClearFlag(DMA1_FLAG_TC3); //清除传输完成标志位
DMA_Cmd(DMA1_Channel3,DISABLE);//关闭DMA1通道3指令
// for(t=0;t<512;t++)SPI1_ReadWriteByte(buf[t]);//提高速度,减少函数传参时间
SD_SPI_ReadWriteByte(0xFF);//忽略crc
SD_SPI_ReadWriteByte(0xFF);
t=SD_SPI_ReadWriteByte(0xFF);//接收响应
if((t&0x1F)!=0x05)return 2;//响应错误
}
return 0;//写入成功
}
|
|