打印

关于SPI驱动SD卡就是初始化失败

[复制链接]
243|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丑帅丑帅的|  楼主 | 2018-7-12 08:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这些指令应该是没有什么问题应为初始化有时可以成功
void SPI2_SetSpeed(u8 SpeedSet)
{SpeedSet&=0X07//限制范围SPI2->CR1&=0XFFC7; SPI2->CR1|=SpeedSet<<3//设置SPI1速度SPI2->CR1|=1<<6//SPI设备使能 }

u8 SPI2_ReadWriteByte(u8 TxData)
while((SPI2->SR&1<<1)==0) //等待发送区空
SPI2->DR=TxData//发送一个bytewhile((SPI2->SR&1<<0)==0){} //等待接收完一个bytereturn SPI2->DR;//返回收到的数据}

void SPI2_Init(void)
{u16 tempreg=0;
RCC->AHB1ENR|=1<<1//使能PORTB时钟RCC->AHB1ENR|=1<<2//使能PORTC时钟RCC->APB1ENR|=1<<14//SPI1时钟使能
GPIO_Set(GPIOC,1<<1,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PB3~5复用功能输出

GPIO_Set(GPIOC,1<<2,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PB3~5复用功能输出GPIO_Set(GPIOC,1<<3,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU)//PB3~5复用功能输出
GPIO_Set(GPIOB,1<<13,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU)//PB3~5复用功能输出

GPIO_AF_Set(GPIOB,13,5)//PB3,AF5
GPIO_AF_Set(GPIOC,2,5)//PB4,AF5
GPIO_AF_Set(GPIOC,3,5)//PB5,AF5
//这里只针对SPI口初始化
RCC->APB1RSTR|=1<<14//复位SPI1
RCC->APB1RSTR&=~(1<<14);//停止复位SPI1
tempreg|=0<<10//全双工模式tempreg|=1<<9;//软件nss管理
tempreg|=1<<8;
tempreg|=1<<2;//SPI主机tempreg|=0<<11;//8位数据格式
tempreg|=1<<1//空闲模式下SCK为1 CPOL=1
tempreg|=1<<0//数据采样从第2个时间边沿开始,CPHA=1//对SPI1属于APB2的外设.时钟频率最大为84Mhz频率.
tempreg|=7<<3//Fsck=Fpclk1/256
tempreg|=0<<7//MSB Firsttempreg|=1<<6;//SPI启动
SPI2->CR1=tempreg//设置CR1
SPI2->CRCPR =0;
SPI2->CRCPR=0x0007;
SPI2->I2SCFGR&=~(1<<11);//选择SPI模式
SPI2_ReadWriteByte(0xff);//启动传输}

oid SPI_Send_Cmd(u8 cmdindex,u32 arg,u8 crc)
CS=0SPI2_ReadWriteByte( 0x40|cmdindex);
SPI2_ReadWriteByte( arg>>24 );

SPI2_ReadWriteByte( arg>>16 );

SPI2_ReadWriteByte( arg>>8);

SPI2_ReadWriteByte( arg>>0);

SPI2_ReadWriteByte( crc);

CS=1;}

u8 CmdErrorR1( void )
{u8 rec,i=30;CS=0; while(i--)rec=SPI2_ReadWriteByte(0xff)if(rec==0x01)
CS=1SPI2_ReadWriteByte(0xff)return 0;}
CS=1;
u8 CmdError_r1(void)
{u8 rec=0,i=30CS=0; while(i--){rec=SPI2_ReadWriteByte(0xff)if(rec==0x00) CS=1SPI2_ReadWriteByte(0xff);
return 0;}
CS=1;
return 1}
u8 CmdErrorr1( void )
u8 rec,i=30;
CS=0;
while(i--)
rec=SPI2_ReadWriteByte(0xff);if(rec==0x01)
CS=1;SPI2_ReadWriteByte(0xff);return 0;}
CS=1;
return 1;
void CmdErrorR3( void )
u8 rec CS=0;
rec=SPI2_ReadWriteByte(0xff)ARG_Tab[3]=SPI2_ReadWriteByte(0xff)ARG_Tab[2]=SPI2_ReadWriteByte(0xff);
ARG_Tab[1]=SPI2_ReadWriteByte(0xff);
ARG_Tab[0]=SPI2_ReadWriteByte(0xff);
SPI2_ReadWriteByte(0xff);
CS=1u8 SD_PowerOn(void)

u8 i=0;
u8 errorstatus=0;
u32 count=0,validvoltage=0;
u32 SDType=0;
CS=1;
GPIOC->ODR |=1<<2;
GPIOC->ODR |=1<<3;for(i=0;i<10;i++)

SPI2_ReadWriteByte(0xff);
for(i=0;i<200;i++)
SPI_Send_Cmd(SD_CMD_GO_IDLE_STATE,0,0x95);//发arg送CMD0进入SPI模式命令.errorstatus=CmdErrorR1();
if(errorstatus==0) break;
if(errorstatus)return errorstatus;//返回错误状态
printf("SPI MODE is OK
");
for(i=0;i<200;i++)
SPI_Send_Cmd(SD_CMD_HS_SEND_EXT_CSD,SD_CHECK_PATTERN,0x01);//发送CMD8,短响应,检查SD卡接口特性.
//arg[11:8]:01,支持电压范围,2.7~3.6V
//arg[7:0]:默认0XAA
errorstatus=CmdErrorR1();&;//等待R1响应
SPI_Send_Cmd((u8)58,0,0x01);//发送CMD58
CmdErrorR3();
if(errorstatus==0) break;
if(errorstatus)return errorstatus;//返回错误状态
if(errorstatus==0)//R1响应正常
CardType=SDIO_STD_CAPACITY_SD_CARD_V2_0//SD 2.0卡
SDType=SD_HIGH_CAPACITY//高容量卡
printf("Card returns response without illegal command
");
SPI_Send_Cmd(SD_CMD_APP_CMD,0,0x01);//发送CMD55
errorstatus=CmdErrorR1()if(errorstatus)return errorstatus;//返回错误状态printf("/*******************/
while((!validvoltage)&&(count<200))

SPI_Send_Cmd(SD_CMD_APP_CMD,0,0x01);//发送CMD55
errorstatus=CmdErrorR1()if(errorstatus)return errorstatus;//返回错误状态printf(/*******************/)
SPI_Send_Cmd(SD_CMD_SD_APP_OP_COND,SDType|SD_VOLTAGE_WINDOW_SD,0x01);//发送CMD41
errorstatus=CmdError_r1();
if(errorstatus==0)return errorstatus;//响应错误
printf("/********ddd***********/
")运行到这里就不行了,不知道怎么回事
SPI_Send_Cmd( (u8)58,0,0x01);//发送CMD58
CmdErrorR3();
//validvoltage=((ARG_Tab[3] & 0x80)?1:0)//判断SD卡上电是否完成
//count++;
if(ARG_Tab[3] & 0x80) validvoltage=1; count++;
printf("check the function
");
if(count>=200)
errorstatus=SD_INVALID_VOLTRANGE;
printf("SD_INVALID_VOLTRANGE
");
eturn 0;
if(ARG_Tab[3]&=0x40)
CardType=SDIO_HIGH_CAPACITY_SD_CARD;
printf("SDIO_HIGH_CAPACITY_SD_CARD
");
else
//{
//printf(" illegal command
")
SPI_Send_Cmd(55,0,0x01);//发送CMD55
errorstatus=CmdErrorR1()if(errorstatus)return errorstatus;//返回错误状态SPI_Send_Cmd(41,SD_VOLTAGE_WINDOW_SD,0x01);//发送CMD41
errorstatus=CmdError_r1(); if(errorstatus)return errorstatus;//返回错误状态
else
CardType=SDIO_STD_CAPACITY_SD_CARD_V1_1;
printf("SDIO_STD_CAPACITY_SD_CARD_V1_1
")
// return 0;
return


u8 Read_SDSocket(u8 *buff, u32 address ,u8 mode )
u8 errorstatus=0,i=0,j=0;
if(mode==0)// read block
{for(i=0;i<60;i++)
SPI_Send_Cmd( SD_CMD_READ_SINGLE_BLOCK, address, 0x01);//发送CMD17
errorstatus=CmdError_r1();
if(errorstatus==0)break
if(errorstatus)return errorstatus
printf("Read_SDSocket
");
CS=0;
while( !(SPI2_ReadWriteByte(0xff)==0xfe)){}

printf("www
")for(i=0;i<64;i++)
{ *buff=SPI2_ReadWriteByte(0xff);
buff++;

SPI2_ReadWriteByte(0xff); //tow byte CRC
SPI2_ReadWriteByte(0xff);
CS=1;}
else if(mode==1) // read multiple block
{SPI_Send_Cmd( (u8)18, address, 0x01);//发送CMD18errorstatus=CmdError_r1();
if(errorstatus)return errorstatus;
CS=0while( !(SPI2_ReadWriteByte(0xff)==0xFE)){}
CS=1;
for(j=0;j<Size;j++)// 读多块的大小可以通过改SIZE来实现 SIZE越大读的区域就越多当然不可能无限扩大
CS=0;
*buff=SPI2_ReadWriteByte(0xff);
buff++
SPI2_ReadWriteByte(0xff); //tow byte CRC
SPI2_ReadWriteByte(0xff);
CS=1}
SPI_Send_Cmd( (u8)12,0,0x01);//发送CMD10}return 0;}
u8 Write_SDSocket(u8 *buff, u32 address ,u8 mode ){u8 errorstatus=0,i=0,j=0;
if(mode==0)// read block
{SPI_Send_Cmd( (u8)24, address, 0x01);//发送CMD17
errorstatus=CmdError_r1();
if(errorstatus);return errorstatus;
printf("Write_SDSocket
");
for(i=0;i<5;i++)SPI2_ReadWriteByte(0xff);
SPI2_ReadWriteByte(0xFE);for(i=0;i<64;i++)
SPI2_ReadWriteByte(*buff);
buff++}
SPI2_ReadWriteByte(0xff); //send tow byte CRC
SPI2_ReadWriteByte(0xff);

while( !(SPI2_ReadWriteByte(0xff)==0x05)){}
while( !(SPI2_ReadWriteByte(0xff)==0xff)){} }
else if(mode==1) // read multiple block
{SPI_Send_Cmd( (u8)25, address, 0x01);//发送CMD10
errorstatus=CmdError_r1();
if(errorstatus)return errorstatus;
for(j=0;j<Size;j++)
for(i=0;i<5;i++)SPI2_ReadWriteByte(0xff);

SPI2_ReadWriteByte(0xFC)for(i=0;i<64;i++)
SPI2_ReadWriteByte(*buff);
buff++SPI2_ReadWriteByte(0xff); //send tow byte CRC
SPI2_ReadWriteByte(0xff);
while( !(SPI2_ReadWriteByte(0xff)==0x05)){}
SPI2_ReadWriteByte(0xFD);
while( !(SPI2_ReadWriteByte(0xff)==0xff)

return 1}
求解决红色处的问题

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

741

主题

742

帖子

0

粉丝