想在TFT屏上显示图片,让图片的数据放在SD卡中,利用单片机的SPI口去读写SD(STM32F107VC),在复位SD卡时(CM0命令),总是得不到正确!贴出操作SD卡的部分代码,请大家给我看看 搞了两天实在没办法了部分代码如下:
配置4个SPI接口的模式:
/************************SPI1引脚的复用功能******************/
/************************************************************/
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; //CS
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; //SD卡的数据输出
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //SD卡的命令输入(PA7) 配置成复用的推挽输出 ,SPI 的主模式时钟输出
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
配置SPI:
void InitSPI()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
SPI_I2S_DeInit(SPI1); //这个会调用其本身的外设时钟
SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //双线全双工模式
SPI_InitStruct.SPI_Mode=SPI_Mode_Master; //SPI主模式
SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b; //发送,接受8位帧模式
SPI_InitStruct.SPI_CPOL=SPI_CPOL_High; //空闲状态时时钟线为高
SPI_InitStruct.SPI_CPHA=SPI_CPHA_2Edge; //在第一个边沿进行数据采集
SPI_InitStruct.SPI_NSS=SPI_NSS_Soft; //NSS引脚由硬件控制
SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256; //拨特率=PCLK1/2
SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB; //传输时高位在前
SPI_InitStruct.SPI_CRCPolynomial=7;
SPI_Init(SPI1,&SPI_InitStruct);
// SPI_SSOutputCmd(SPI1, ENABLE);
// SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE); //使能SPI的接收DMA请求 允许DMA请求使传输效率更高
// SPI_Cmd(SPI,SPI_IT_TXE|SPI_IT_RXNE|SPI_IT_ERR,DISABLE); //用查询方式所以不用中断
SPI_Cmd(SPI1,ENABLE); //使能SPI
}
复位SD卡的代码:
uint8_t InitSDCard()
{
uint16_t i,WaitTime;
uint8_t data;
SetCsd;
for(i=0;i<0xF00;i++); //等待SD卡内部上电完成
for(i=0;i<16;i++) //产生74个时钟
{
SpiSendCommand(0xff); //这不是一个指令,而是用于维持MOSI的电平.//这里其实就是发送8个时钟给从设备.而MOSI一直维持高电平.当然你也可以维持低电平,写0X00就可以.不过通常的做法是维持高.
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)) return 1; //此为SD卡是否插入的检测引脚
do
{
data=SpiSendIndex(CMD0,0,0x95);
WaitTime++;
}while((data!=0x01)&&(WaitTime>200));
if(data==0x01) return SD_OK;
else return SD_ERROR;
}
SPI读写代码:
uint8_t SpiSendCommand(uint8_t SendData) //写数据
{
uint8_t RxData = 0;
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI1,SendData);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
//取数据
RxData = SPI_I2S_ReceiveData(SPI1);
return RxData;
}
/*
uint8_t SpiSendIndex(uint8_t Index,uint32_t Agrument,uint8_t crc)
{
uint8_t data;
uint16_t WaitTime;
SetCsd; //失能片选
SpiSendCommand(0xff);
ClrCsd; //片选SD卡
SpiSendCommand(Index|0x40);
SpiSendCommand(Agrument>>24);
SpiSendCommand(Agrument>>16);
SpiSendCommand(Agrument>>8);
SpiSendCommand(Agrument);
SpiSendCommand(crc);
while((data=SpiSendCommand(0xff))==0xff)
{
// SpiSendCommand(0xff);
WaitTime++;
if(WaitTime>200) return SD_ERROR; /*0 失败 1 成功*/
}
SetCsd;
SpiSendCommand(0xff);
return data;
}
SPI工作是正常的,用示波器看过SCK,MOSI引脚是有波形的,用的开发板,硬件电路应该是没有问题的!SD是手机上的 ,应该也是没有问题的!以上的几段代码和网上的例程基本是一样的!可是不知道为什么就是不能得到正确回应!请大家给我看看 实在是没招了!谢谢! |