本帖最后由 chao超 于 2018-9-30 08:54 编辑
这些指令应该是没有什么问题应为初始化有时可以成功
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; //发送一个byte
while((SPI2->SR&1<<0)==0){} //等待接收完一个byte
return 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 First
tempreg|=1<<6; //SPI启动
SPI2->CR1=tempreg; //设置CR1
SPI2->CRCPR =0;
SPI2->CRCPR=0x0007;
SPI2->I2SCFGR&=~(1<<11);//选择SPI模式
SPI2_ReadWriteByte(0xff);//启动传输
}
void SPI_Send_Cmd(u8 cmdindex,u32 arg,u8 crc)
{
CS=0;
SPI2_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=1;
SPI2_ReadWriteByte(0xff);
return 0;
}
}
CS=1;
return 1;
}
u8 CmdError_r1(void)
{
u8 rec=0,i=30;
CS=0;
while(i--)
{
rec=SPI2_ReadWriteByte(0xff);
if(rec==0x00)
{
CS=1;
SPI2_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=1;
}
u8 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
");
return 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 0;
}
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);//发送CMD18
errorstatus=CmdError_r1();
if(errorstatus) return errorstatus;
CS=0;
while( !(SPI2_ReadWriteByte(0xff)==0xFE) ){}
CS=1;
for(j=0;j<Size;j++) // 读多块的大小可以通过改SIZE来实现 SIZE越大读的区域就越多当然不可能无限扩大
{
CS=0;
for(i=0;i<64;i++)
{
*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;
}
求解决红 {MOD}处的问题
一周热门 更多>