Ejemplo n.º 1
0
//等待SD卡写入完成
//返回值:0,成功;
//    其他,错误代码;
u8 SD_WaitDataReady(void)
{
    u8 r1=MSD_DATA_OTHER_ERROR;
    u32 retry;
    retry=0;
    do
    {
        r1=SPIx_ReadWriteByte(0xFF)&0X1F;//读到回应
        if(retry==0xfffe)return 1;
        retry++;
        switch (r1)
        {
        case MSD_DATA_OK://数据接收正确了
            r1=MSD_DATA_OK;
            break;
        case MSD_DATA_CRC_ERROR:  //CRC校验错误
            return MSD_DATA_CRC_ERROR;
        case MSD_DATA_WRITE_ERROR://数据写入错误
            return MSD_DATA_WRITE_ERROR;
        default://未知错误
            r1=MSD_DATA_OTHER_ERROR;
            break;
        }
    } while(r1==MSD_DATA_OTHER_ERROR); //数据错误时一直等待
    retry=0;
    while(SPIx_ReadWriteByte(0XFF)==0)//读到数据为0,则数据还未写完成
    {
        retry++;
        //delay_us(10);//SD卡写等待需要较长的时间
        if(retry>=0XFFFFFFFE)return 0XFF;//等待失败了
    };
    return 0;//成功了
}
Ejemplo n.º 2
0
//写入MSD/SD数据
//pBuffer:数据存放区
//ReadAddr:写入的首地址
//NumByteToRead:要写入的字节数
//返回值:0,写入完成
//    其他,写入失败
u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite)
{
    u32 i,NbrOfBlock = 0, Offset = 0;
    u32 sector;
    u8 r1;
    NbrOfBlock = NumByteToWrite / BLOCK_SIZE;//得到要写入的块的数目
    SD_CS=0;
    while (NbrOfBlock--)//写入一个扇区
    {
        sector=WriteAddr+Offset;
        if(SD_Type==SD_TYPE_V2HC)sector>>=9;//执行与普通操作相反的操作
        r1=SD_SendCommand_NoDeassert(CMD24,sector,0xff);//写命令
        if(r1)
        {
            SD_CS=1;
            return 1;//应答不正确,直接返回
        }
        SPIx_ReadWriteByte(0xFE);//放起始令牌0xFE
        //放一个sector的数据
        for(i=0; i<512; i++)SPIx_ReadWriteByte(*pBuffer++);
        //发2个Byte的dummy CRC
        SPIx_ReadWriteByte(0xff);
        SPIx_ReadWriteByte(0xff);
        if(SD_WaitDataReady())//等待SD卡数据写入完成
        {
            SD_CS=1;
            return 2;
        }
        Offset += 512;
    }
    //写入完成,片选置1
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);
    return 0;
}
Ejemplo n.º 3
0
//写SPI_FLASH状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!!
void SPI_FLASH_Write_SR(u8 sr)   
{   
	SPI_FLASH_CS=0;                            //使能器件   
	SPIx_ReadWriteByte(W25X_WriteStatusReg);   //发送写取状态寄存器命令    
	SPIx_ReadWriteByte(sr);               //写入一个字节  
	SPI_FLASH_CS=1;                            //取消片选     	      
}   
Ejemplo n.º 4
0
//在指定位置读出指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值 
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
	{
	u8 status,u8_ctr;	       
	Clr_NRF24L01_CSN;           //使能SPI传输
	status=SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值   	   
	for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPIx_ReadWriteByte(0XFF);//读出数据
	Set_NRF24L01_CSN;       //关闭SPI传输
	return status;        //返回读到的状态值
	}
Ejemplo n.º 5
0
//在指定位置写指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
	u8 status,u8_ctr;	    
 	NRF24L01_CSN = 0;          //使能SPI传输
  	status = SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
  	for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPIx_ReadWriteByte(*pBuf++); //写入数据	 
  	NRF24L01_CSN = 1;       //关闭SPI传输
  	return status;          //返回读到的状态值
}				   
Ejemplo n.º 6
0
//读取SPI_FLASH的状态寄存器
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
u8 SPI_Flash_ReadSR(void)   
{  
	u8 byte=0;   
	SPI_FLASH_CS=0;                            //使能器件   
	SPIx_ReadWriteByte(W25X_ReadStatusReg);    //发送读取状态寄存器命令    
	byte=SPIx_ReadWriteByte(0Xff);             //读取一个字节  
	SPI_FLASH_CS=1;                            //取消片选     
	return byte;   
} 
Ejemplo n.º 7
0
//SPI写寄存器
//reg:指定寄存器地址
//value:写入的值
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
	{
	u8 status;	
	Clr_NRF24L01_CSN;                 //使能SPI传输
	status =SPIx_ReadWriteByte(reg);//发送寄存器号 
	SPIx_ReadWriteByte(value);      //写入寄存器的值
	Set_NRF24L01_CSN;                 //禁止SPI传输	   
	return(status);       			//返回状态值
	}
Ejemplo n.º 8
0
//读取SPI_FLASH的状态寄存器
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
u8 SPI_Flash_ReadSR(void)   
{  
	u8 byte=0;   
	W25Q16_CS_LOW();                            //使能器件   
	SPIx_ReadWriteByte(0x05);    //发送读取状态寄存器命令    
	byte=SPIx_ReadWriteByte(0Xff);             //读取一个字节  
	W25Q16_CS_HIGH();                            //取消片选     
	return byte;   
} 
Ejemplo n.º 9
0
//读取SPI寄存器值
//reg:要读的寄存器
u8 NRF24L01_Read_Reg(u8 reg)
	{
	u8 reg_val;	    
	Clr_NRF24L01_CSN;          //使能SPI传输		
	SPIx_ReadWriteByte(reg);   //发送寄存器号
	reg_val=SPIx_ReadWriteByte(0XFF);//读取寄存器内容
	Set_NRF24L01_CSN;          //禁止SPI传输		    
	return(reg_val);           //返回状态值
	}	
Ejemplo n.º 10
0
//擦除一个扇区
//Dst_Addr:扇区地址 0~511 for w25x16
//擦除一个山区的最少时间:150ms
void SPI_Flash_Erase_Sector(u32 Dst_Addr)   
{   
	Dst_Addr*=4096;
    SPI_FLASH_Write_Enable();                  //SET WEL 	 
    SPI_Flash_Wait_Busy();   
  	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_SectorErase);      //发送扇区擦除指令 
    SPIx_ReadWriteByte((u8)((Dst_Addr)>>16));  //发送24bit地址    
    SPIx_ReadWriteByte((u8)((Dst_Addr)>>8));   
    SPIx_ReadWriteByte((u8)Dst_Addr);  
	SPI_FLASH_CS=1;                            //取消片选     	      
    SPI_Flash_Wait_Busy();   				   //等待擦除完成
}  
Ejemplo n.º 11
0
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!	 
void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
 	u16 i;  
    SPI_FLASH_Write_Enable();                  //SET WEL 
	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_PageProgram);      //发送写页命令   
    SPIx_ReadWriteByte((u8)((WriteAddr)>>16)); //发送24bit地址    
    SPIx_ReadWriteByte((u8)((WriteAddr)>>8));   
    SPIx_ReadWriteByte((u8)WriteAddr);   
    for(i=0;i<NumByteToWrite;i++)SPIx_ReadWriteByte(pBuffer[i]);//循环写数  
	SPI_FLASH_CS=1;                            //取消片选 
	SPI_Flash_Wait_Busy();					   //等待写入结束
} 
Ejemplo n.º 12
0
//写入SD卡的N个block(未实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 写入的block数目
//返回值:0: 成功
//       other:失败
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count)
{
    u8 r1;
    u16 i;
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式
    if(SD_Type != SD_TYPE_V2HC)sector = sector<<9;//如果不是SDHC,给定的是sector地址,将其转换成byte地址
    if(SD_Type != SD_TYPE_MMC) r1 = SD_SendCommand(ACMD23, count, 0x00);//如果目标卡不是MMC卡,启用ACMD23指令使能预擦除
    r1 = SD_SendCommand(CMD25, sector, 0x00);//发多块写入指令
    if(r1 != 0x00)return r1;  //应答不正确,直接返回
    SD_CS=0;//开始准备数据传输
    SPIx_ReadWriteByte(0xff);//先放3个空数据,等待SD卡准备好
    SPIx_ReadWriteByte(0xff);
    //--------下面是N个sector写入的循环部分
    do
    {
        //放起始令牌0xFC 表明是多块写入
        SPIx_ReadWriteByte(0xFC);
        //放一个sector的数据
        for(i=0; i<512; i++)
        {
            SPIx_ReadWriteByte(*data++);
        }
        //发2个Byte的dummy CRC
        SPIx_ReadWriteByte(0xff);
        SPIx_ReadWriteByte(0xff);

        //等待SD卡应答
        r1 = SPIx_ReadWriteByte(0xff);
        if((r1&0x1F)!=0x05)
        {
            SD_CS=1;    //如果应答为报错,则带错误代码直接退出
            return r1;
        }
        //等待SD卡写入完成
        if(SD_WaitDataReady()==1)
        {
            SD_CS=1;    //等待SD卡写入完成超时,直接退出报错
            return 1;
        }
    } while(--count);//本sector数据传输完成
    //发结束传输令牌0xFD
    r1 = SPIx_ReadWriteByte(0xFD);
    if(r1==0x00)
    {
        count =  0xfe;
    }
    if(SD_WaitDataReady()) //等待准备好
    {
        SD_CS=1;
        return 1;
    }
    //写入完成,片选置1
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);
    return count;   //返回count值,如果写完则count=0,否则count=1
}
Ejemplo n.º 13
0
//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{ 
 	u16 i;    												    
	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_ReadData);         //发送读取命令   
    SPIx_ReadWriteByte((u8)((ReadAddr)>>16));  //发送24bit地址    
    SPIx_ReadWriteByte((u8)((ReadAddr)>>8));   
    SPIx_ReadWriteByte((u8)ReadAddr);   
    for(i=0;i<NumByteToRead;i++)
	{ 
        pBuffer[i]=SPIx_ReadWriteByte(0XFF);   //循环读数  
    }
	SPI_FLASH_CS=1;                            //取消片选     	      
}  
Ejemplo n.º 14
0
//向SD卡发送一个命令
//输入: u8 cmd   命令
//      u32 arg  命令参数
//      u8 crc   crc校验值
//返回值:SD卡返回的响应
u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc)
{
    u8 r1;
    u8 Retry=0;
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);//高速写命令延时
    SPIx_ReadWriteByte(0xff);
    SPIx_ReadWriteByte(0xff);
    //片选端置低,选中SD卡
    SD_CS=0;
    //发送
    SPIx_ReadWriteByte(cmd | 0x40);//分别写入命令
    SPIx_ReadWriteByte(arg >> 24);
    SPIx_ReadWriteByte(arg >> 16);
    SPIx_ReadWriteByte(arg >> 8);
    SPIx_ReadWriteByte(arg);
    SPIx_ReadWriteByte(crc);
    //等待响应,或超时退出
    while((r1=SPIx_ReadWriteByte(0xFF))==0xFF)
    {
        Retry++;
        if(Retry>200)break;
    }
    //关闭片选
    SD_CS=1;
    //在总线上额外增加8个时钟,让SD卡完成剩下的工作
    SPIx_ReadWriteByte(0xFF);
    //返回状态值
    return r1;
}
Ejemplo n.º 15
0
Archivo: spi.c Proyecto: zou-can/si-zou
/*
 * 函数名:SPIx_Init
 * 描述  :SPI1的初始化
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void SPIx_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//定义IO口配置 结构体

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE);//SPI GPIOA 时钟使能 
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//选中引脚5,6,7
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO输出速度50Hz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA,&GPIO_InitStructure);//配置引脚
	GPIO_SetBits(GPIOA, GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7);//PA 5,6,7 输出高
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主 SPI  
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//SPI发送接收 8 位帧结构  
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//选择了串行时钟的稳态:时钟悬空高
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//数据捕获于第二个时钟沿 
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//波特率预分频值为 256   
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从 MSB 位开始 
	SPI_InitStructure.SPI_CRCPolynomial = 7;//SPI_CRCPolynomial定义了用于 CRC值计算的多项式 
	SPI_Init(SPI1, &SPI_InitStructure); //配置SPI1
	
	SPI_Cmd(SPI1, ENABLE);//SPI1使能
	SPIx_ReadWriteByte(0xFF);//启动传输	
}
Ejemplo n.º 16
0
//等待SD卡回应
//Response:要得到的回应值
//返回值:0,成功得到了该回应值
//    其他,得到回应值失败
u8 SD_GetResponse(u8 Response)
{
    u16 Count=0xFFF;//等待次数
    while ((SPIx_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应
    if (Count==0)return MSD_RESPONSE_FAILURE;//得到回应失败
    else return MSD_RESPONSE_NO_ERROR;//正确回应
}
Ejemplo n.º 17
0
Archivo: spi.c Proyecto: nvero/fmhobby
//以下是SPI模块的初始化代码,配置成主机模式,访问SD Card/W25X16/24L01/JF24C							  
//SPI口初始化
//这里针是对SPI1的初始化
void SPIx_Init(void)
{
	RCC->APB2RSTR|=1<<12;      //SPI1复位 
	RCC->APB2RSTR&=~(1<<12);   //SPI1结束复位
		 
	RCC->APB2ENR|=1<<2;       //PORTA时钟使能 	 
	RCC->APB2ENR|=1<<12;      //SPI1时钟使能 
		   
	//这里只针对SPI口初始化
	GPIOA->CRL&=0X000FFFFF; 
	GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 	    
	GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉
		
	SPI1->CR1|=0<<10;//全双工模式	
	SPI1->CR1|=1<<9; //软件nss管理
	SPI1->CR1|=1<<8;  

	SPI1->CR1|=1<<2; //SPI主机
	SPI1->CR1|=0<<11;//8bit数据格式	
	//对24L01要设置 CPHA=0;CPOL=0;
	SPI1->CR1|=1<<1; //CPOL=0时空闲模式下SCK为1 
	SPI1->CR1|=1<<0; //第一个时钟的下降沿,CPHA=1 CPOL=1
	  
	SPI1->CR1|=7<<3; //Fsck=Fcpu/256
	SPI1->CR1|=0<<7; //MSBfirst   
	SPI1->CR1|=1<<6; //SPI设备使能
	SPIx_ReadWriteByte(0xff);//启动传输		 
}   
Ejemplo n.º 18
0
//唤醒
void SPI_Flash_WAKEUP(void)   
{  
  	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_ReleasePowerDown);   //  send W25X_PowerDown command 0xAB    
	SPI_FLASH_CS=1;                            //取消片选     	      
    delay_us(3);                               //等待TRES1
}   
Ejemplo n.º 19
0
void SPIx_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStructure;
  
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );	
   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

 	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
 
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//选择了串行时钟的稳态:时钟悬空高
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//数据捕获于第二个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI1, ENABLE); //使能SPI外设
	
	SPIx_ReadWriteByte(0xff);//启动传输		 
}   
Ejemplo n.º 20
0
//进入掉电模式
void SPI_Flash_PowerDown(void)   
{ 
  	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_PowerDown);        //发送掉电命令  
	SPI_FLASH_CS=1;                            //取消片选     	      
    delay_us(3);                               //等待TPD  
}   
Ejemplo n.º 21
0
//读取MSD/SD数据
//pBuffer:数据存放区
//ReadAddr:读取的首地址
//NumByteToRead:要读出的字节数
//返回值:0,读出完成
//    其他,读出失败
u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead)
{
    u32 NbrOfBlock=0,Offset=0;
    u32 sector=0;
    u8 r1=0;
    NbrOfBlock=NumByteToRead/BLOCK_SIZE;
    SD_CS=0;
    while (NbrOfBlock --)
    {
        sector=ReadAddr+Offset;
        if(SD_Type==SD_TYPE_V2HC)sector>>=9;//执行与普通操作相反的操作
        r1=SD_SendCommand_NoDeassert(CMD17,sector,0xff);//读命令
        if(r1)//命令发送错误
        {
            SD_CS=1;
            return r1;
        }
        r1=SD_ReceiveData(pBuffer,512,RELEASE);
        if(r1)//读数错误
        {
            SD_CS=1;
            return r1;
        }
        pBuffer+=512;
        Offset+=512;
    }
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);
    return 0;
}
Ejemplo n.º 22
0
/**
	*名称:SPI_Flash_Erase_Chip
	*输入:无
	*输出:无
	*返回:无
	*功能:擦除整个芯片整片擦除时间:
		   W25X16:25s 
		   W25X32:40s 
		   W25X64:40s 
		   等待时间超长...
	*说明:擦除时间来源于手册,有待验证

**/
void SPI_Flash_Erase_Chip(void)   
{                                             
    SPI_FLASH_Write_Enable();                  //SET WEL 
    SPI_Flash_Wait_Busy();   
  	W25Q16_CS_LOW();                            //使能器件   
    SPIx_ReadWriteByte(W25X_ChipErase);        //发送片擦除命令  
	W25Q16_CS_HIGH();                            //取消片选     	      
	SPI_Flash_Wait_Busy();   				   //等待芯片擦除结束
} 
Ejemplo n.º 23
0
//擦除整个芯片
//整片擦除时间:
//W25X16:25s 
//W25X32:40s 
//W25X64:40s 
//等待时间超长...
void SPI_Flash_Erase_Chip(void)   
{                                             
    SPI_FLASH_Write_Enable();                  //SET WEL 
    SPI_Flash_Wait_Busy();   
  	SPI_FLASH_CS=0;                            //使能器件   
    SPIx_ReadWriteByte(W25X_ChipErase);        //发送片擦除命令  
	SPI_FLASH_CS=1;                            //取消片选     	      
	SPI_Flash_Wait_Busy();   				   //等待芯片擦除结束
}   
Ejemplo n.º 24
0
//在指定扇区,从offset开始读出bytes个字节
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buf     数据存储地址(大小<=512byte)
//     u16 offset  在扇区里面的偏移量
//     u16 bytes   要读出的字节数
//返回值:0: 成功
//       other:失败
u8 SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes)
{
    u8 r1;
    u16 i=0;
    r1=SD_SendCommand(CMD17,address<<9,0);//发送读扇区命令
    if(r1)return r1;  //应答不正确,直接返回
    SD_CS=0;//选中SD卡
    if(SD_GetResponse(0xFE))//等待SD卡发回数据起始令牌0xFE
    {
        SD_CS=1; //关闭SD卡
        return 1;//读取失败
    }
    for(i=0; i<offset; i++)SPIx_ReadWriteByte(0xff); //跳过offset位
    for(; i<offset+bytes; i++)*buf++=SPIx_ReadWriteByte(0xff); //读取有用数据
    for(; i<512; i++) SPIx_ReadWriteByte(0xff); 	 //读出剩余字节
    SPIx_ReadWriteByte(0xff);//发送伪CRC码
    SPIx_ReadWriteByte(0xff);
    SD_CS=1;//关闭SD卡
    return 0;
}
Ejemplo n.º 25
0
//从SD卡中读回指定长度的数据,放置在给定位置
//输入: u8 *data(存放读回数据的内存>len)
//      u16 len(数据长度)
//      u8 release(传输完成后是否释放总线CS置高 0:不释放 1:释放)
//返回值:0:NO_ERR
//  	 other:错误信息
u8 SD_ReceiveData(u8 *data, u16 len, u8 release)
{
    // 启动一次传输
    SD_CS=0;
    if(SD_GetResponse(0xFE))//等待SD卡发回数据起始令牌0xFE
    {
        SD_CS=1;
        return 1;
    }
    while(len--)//开始接收数据
    {
        *data=SPIx_ReadWriteByte(0xFF);
        data++;
    }
    //下面是2个伪CRC(dummy CRC)
    SPIx_ReadWriteByte(0xFF);
    SPIx_ReadWriteByte(0xFF);
    if(release==RELEASE)//按需释放总线,将CS置高
    {
        SD_CS=1;//传输结束
        SPIx_ReadWriteByte(0xFF);
    }
    return 0;
}
Ejemplo n.º 26
0
/**
	*名称:SPI_Flash_ReadID
	*功能:读取芯片ID  W25X16的ID:0XEF14
**/
u16 SPI_Flash_ReadID(void)
{
	u16 Temp = 0;	  
	W25Q16_CS_LOW();
	SPIx_ReadWriteByte(0x90);     /*发送读取ID命令*/	    
	SPIx_ReadWriteByte(0x00); 	    
	SPIx_ReadWriteByte(0x00); 	    
	SPIx_ReadWriteByte(0x00); 	 			   
	Temp|=SPIx_ReadWriteByte(0xFF)<<8;  
	Temp|=SPIx_ReadWriteByte(0xFF);	 
	W25Q16_CS_HIGH();				    
	return Temp;
}
Ejemplo n.º 27
0
//读取芯片ID W25X16的ID:0XEF14
u16 SPI_Flash_ReadID(void)
{
	u16 Temp = 0;	  
	SPI_FLASH_CS=0;				    
	SPIx_ReadWriteByte(0x90);//发送读取ID命令	    
	SPIx_ReadWriteByte(0x00); 	    
	SPIx_ReadWriteByte(0x00); 	    
	SPIx_ReadWriteByte(0x00); 	 			   
	Temp|=SPIx_ReadWriteByte(0xFF)<<8;  
	Temp|=SPIx_ReadWriteByte(0xFF);	 
	SPI_FLASH_CS=1;				    
	return Temp;
}   		    
Ejemplo n.º 28
0
//把SD卡设置到挂起模式
//返回值:0,成功设置
//       1,设置失败
u8 SD_Idle_Sta(void)
{
    u16 i;
    u8 retry;
    for(i=0; i<0xf00; i++); //纯延时,等待SD卡上电完成
    //先产生>74个脉冲,让SD卡自己初始化完成
    for(i=0; i<10; i++)SPIx_ReadWriteByte(0xFF);
    //-----------------SD卡复位到idle开始-----------------
    //循环连续发送CMD0,直到SD卡返回0x01,进入IDLE状态
    //超时则直接退出
    retry = 0;
    do
    {
        //发送CMD0,让SD卡进入IDLE状态
        i = SD_SendCommand(CMD0, 0, 0x95);
        retry++;
    } while((i!=0x01)&&(retry<200));
    //跳出循环后,检查原因:初始化成功?or 重试超时?
    if(retry==200)return 1; //失败
    return 0;//成功
}
Ejemplo n.º 29
0
//读SD卡的多个block(实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 连续读count个block
//返回值:0: 成功
//       other:失败
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count)
{
    u8 r1;
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式
    //如果不是SDHC,将sector地址转成byte地址
    if(SD_Type!=SD_TYPE_V2HC)sector = sector<<9;
    //SD_WaitDataReady();
    //发读多块命令
    r1 = SD_SendCommand(CMD18, sector, 0);//读命令
    if(r1 != 0x00)return r1;
    do//开始接收数据
    {
        if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00)break;
        buffer += 512;
    } while(--count);
    //全部传输完毕,发送停止命令
    SD_SendCommand(CMD12, 0, 0);
    //释放总线
    SD_CS=1;
    SPIx_ReadWriteByte(0xFF);
    if(count != 0)return count;   //如果没有传完,返回剩余个数
    else return 0;
}
Ejemplo n.º 30
0
Archivo: spi.c Proyecto: nvero/fmhobby
//以下是SPI模块的初始化代码,配置成主机模式,访问SD Card/W25X16/24L01/JF24C							  
//SPI口初始化
//这里针是对SPI1的初始化
void SPIx_Init(void)
{	 
	RCC->APB2ENR|=1<<2;       //PORTA时钟使能 	 
	RCC->APB2ENR|=1<<12;      //SPI1时钟使能 
		   
	//这里只针对SPI口初始化
	GPIOA->CRL&=0X000FFFFF; 
	GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 	    
	GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉
		
	SPI1->CR1|=0<<10;//全双工模式	
	SPI1->CR1|=1<<9; //软件nss管理
	SPI1->CR1|=1<<8;  

	SPI1->CR1|=1<<2; //SPI主机
	SPI1->CR1|=0<<11;//8bit数据格式	
	SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1
	SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1  
	SPI1->CR1|=7<<3; //Fsck=Fcpu/256
	SPI1->CR1|=0<<7; //MSBfirst   
	SPI1->CR1|=1<<6; //SPI设备使能
	SPIx_ReadWriteByte(0xff);//启动传输		 
}