这些指令应该是没有什么问题应为初始化有时可以成功
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(&quot;SPI MODE is OK
&quot;);
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(&quot;Card returns response without illegal command
&quot;);
SPI_Send_Cmd(SD_CMD_APP_CMD,0,0x01);//发送CMD55
errorstatus=CmdErrorR1()if(errorstatus)return errorstatus;//返回错误状态printf(&quot;/*******************/
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(&quot;/********ddd***********/
&quot;)运行到这里就不行了,不知道怎么回事
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(&quot;check the function
&quot;);
if(count>=200)
errorstatus=SD_INVALID_VOLTRANGE;
printf(&quot;SD_INVALID_VOLTRANGE
&quot;);
eturn 0;
if(ARG_Tab[3]&=0x40)
CardType=SDIO_HIGH_CAPACITY_SD_CARD;
printf(&quot;SDIO_HIGH_CAPACITY_SD_CARD
&quot;);
else
//{
//printf(&quot; illegal command
&quot;)
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(&quot;SDIO_STD_CAPACITY_SD_CARD_V1_1
&quot;)
// 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(&quot;Read_SDSocket
&quot;);
CS=0;
while( !(SPI2_ReadWriteByte(0xff)==0xfe)){}
printf(&quot;www
&quot;)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(&quot;Write_SDSocket
&quot;);
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}
求解决红色处的问题 |