- *************
- ***************/
- void SPI_SendData(uint8_t data)
- {
- uint8_t cnt;
- for(cnt=0;cnt<8;cnt++)
- {
- SPI_CLK_L;//拉低
- Delay1us(10);//这个延时时间任意,但要大于芯片数据手册上的(纳秒级的)
- if(data &0x80)
- {
- SPI_MOSI_H;
- }
- else
- {
- SPI_MOSI_L;
- }
- data <<= 1;//
- Delay1us(10);
- SPI_CLK_H;//拉高
- Delay1us(10);
- }
- }
- /*****************************************/
- uint8_t SPI_ReadData(void)
- {
- uint8_t i = 0;
- uint8_t value=0;
- SPI_CLK_H;
- Delay1us(2);
- for(i=0;i<8;i++)
- {
- SPI_CLK_L;
- value<<=1;
- if(SPI_MISO_READ())
- {
- value |= 0x01;
- }
- Delay1us(2);
- SPI_CLK_H;
- Delay1us(2);
- }
-
- return value;
- }
- /*************
- 等待擦除完成
- **************/
- void SPI_WaitErase(void)
- {
- uint8_t status = 0x01;
- SPI_CS_L;
- SPI_SendData(0x05); //读取状态寄存器命令
- do
- {
- status = SPI_ReadData();
- }
- while((status&0x01) == 1);
- SPI_CS_H;
- }
- /************
- 扇区擦除
- 4k
- **************/
- void SPI_EraseSector(uint32_t addr)
- {
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x06);
- SPI_CLK_L;
- SPI_CS_H;
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x20);
- SPI_SendData((uint8_t)(addr&0xFF0000)>>16);
- SPI_SendData((addr&0xFF00)>>8);
- SPI_SendData((addr&0xFF));
- SPI_CLK_L;
- SPI_CS_H;
- SPI_WaitErase();
- }
- /************
- 块擦除
- 32k
- **************/
- void SPI_EraseBlock(uint32_t addr)
- {
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x06);
- SPI_CLK_L;
- SPI_CS_H;
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x52);
- SPI_SendData((uint8_t)(addr&0xFF0000)>>16);
- SPI_SendData((addr&0xFF00)>>8);
- SPI_SendData((addr&0xFF));
- SPI_CLK_L;
- SPI_CS_H;
- SPI_WaitErase();
- }
- /************
- 块擦除
- 64k
- **************/
- void SPI_Erase64kBlock(uint32_t addr)
- {
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x06);
- SPI_CLK_L;
- SPI_CS_H;
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0xd8);
- SPI_SendData((uint8_t)(addr&0xFF0000)>>16);
- SPI_SendData((addr&0xFF00)>>8);
- SPI_SendData((addr&0xFF));
- SPI_CLK_L;
- SPI_CS_H;
- SPI_WaitErase();
- }
- /*****************
- 检测设备是否正确
- 设备ID为ID=0XEF4017
- 正常才继续后面的页写入和读取数据
- ******************/
- uint32_t SPI_CheckDevice(void)
- {
- uint8_t temp0,temp1,temp2;
- uint32_t Device_ID=0;
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x9F);
- temp0 = SPI_ReadData();
- temp1 = SPI_ReadData();
- temp2 = SPI_ReadData();
- SPI_CLK_L;
- SPI_CS_H;
- Device_ID = (temp0<<16) | (temp1<<8) | (temp2);
- return Device_ID;
- }
- /**************
- 读取数据
- readlen: 读取长度
- ***************/
- void SPI_BufferRead(uint8_t *pBuffer,uint32_t addr,uint32_t readlen)
- {
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x03);//读数据命令
- SPI_SendData((uint8_t)(addr&0xFF0000)>>16);
- SPI_SendData((addr&0xFF00)>>8);
- SPI_SendData((addr&0xFF));
- while(readlen--)
- {
- *pBuffer = SPI_ReadData();
- pBuffer++;
- }
- SPI_CLK_L;
- SPI_CS_H;
- }
- /************
- 页写入---写入字节数低于256可用页编程
- **************/
- void SPI_PageWrite(uint8_t *pBuffer,uint32_t addr,uint16_t writelen)
- {
- SPI_CLK_L;
- SPI_CS_L;
- SPI_SendData(0x06);
- SPI_CLK_L
- SPI_CS_H;
- SPI_CLK_L;//拉低
- SPI_CS_L;
- SPI_SendData(0x02);
- SPI_SendData((addr&0xFF0000)>>16);
- SPI_SendData((addr&0xFF00)>>8);
- SPI_SendData((addr&0xFF));
- if(writelen>Page_Size)
- {
- // printf("\r\n页写入最大为256字节\r\n");
- writelen = Page_Size ;
- }
- while(writelen--)
- {
- SPI_SendData(*pBuffer);
- pBuffer++;
- }
- SPI_CLK_L;//拉低
- SPI_CS_H;
- SPI_WaitErase();
- }
- /*************
- 写入任意长度数据
- *pBuffer :待写入数据
- addr :需写入flash的地址
- numToWrite :待写入数据长度
- ***************/
- void SPI_BufferWrite(uint8_t *pBuffer,uint32_t addr,uint32_t numToWrite)
- {
- uint32_t count=0,numPage=0,numSingle=0,Addr=0;
- Addr = addr%Page_Size;//某个page的地址
- count = Page_Size - Addr;//某page剩余字节数
- numPage = numToWrite/Page_Size;//待写入的数据占用page数
- numSingle = numToWrite%Page_Size;//待写入数据不够一个page的字节数
- if(Addr == 0)//在某page 起始位置 1
- {
- if(numPage==0)//写入字节数小于一个page
- {
- SPI_PageWrite(pBuffer,addr,numToWrite);
- }
- else//写入字节数大于等于1个page
- {
- while(numPage--)
- {
- SPI_PageWrite(pBuffer,addr,Page_Size);
- pBuffer+=Page_Size;
- addr+=Page_Size;
- }
- SPI_PageWrite(pBuffer,addr,numSingle);
- }
- }
- else //在某page的2~256位置
- {
- if(numPage==0)//写入字节数小于一个page
- {
- if(numSingle>count)//剩余字节数>该page剩余位置
- {
- SPI_PageWrite(pBuffer,addr,count);//向该page的剩余位置写入对应字节
- pBuffer+=count;
- addr+=count;
- SPI_PageWrite(pBuffer,addr,(numSingle-count));//其余的写入下一个page
- }
- else
- {
- SPI_PageWrite(pBuffer,addr,numToWrite);
- }
- }
- else//写入字节数大于等于一个page
- {
- numToWrite -= count;
- numPage = numToWrite/Page_Size;
- numSingle = numToWrite%Page_Size;
- SPI_PageWrite(pBuffer,addr,count);//写入该page还可写入的字节数
- addr+=count;
- pBuffer+=count;
- while(numPage--)//page个数
- {
- SPI_PageWrite(pBuffer,addr,Page_Size);
- pBuffer+=Page_Size;
- addr+=Page_Size;
- }
- if(numSingle!=0)//剩余字节数
- {
- SPI_PageWrite(pBuffer,addr,numSingle);
- }
- }
- }
- SPI_WaitErase();
- }
- /************
- 数据比较
- len :数据长度
- 不等:0
- 相等:1
- ************/
- uint8_t pBuffer_Cmp(uint8_t *buffer1,uint8_t *buffer2,uint32_t len)
- {
- while(len--)
- {
- if(*buffer1!=*buffer2)
- {
- return 0;
- }
- buffer1++;
- buffer2++;
- }
- return 1;
- }
- uint8_t Write_pBuffer[]={"软件模拟SPI成功!"};
- uint8_t Read_pBuffer[3500]={0};
- /***********
- 读写测试,验证是否正常
- ***********/
- void SPI_Test(void)
- {
- uint32_t Device_ID = 0;
- Device_ID = SPI_CheckDevice();
- // printf("ID=0x%x \r\n", Device_ID);
- if(Device_ID == 0xEF4016)
- {
- if(comparm.DebugComm & F_DebugStart)
- DebgStr_FramProc("SPI FLASH设备正常!\r\n");
- SPI_EraseSector(0x001000);//sector1
- SPI_BufferWrite(Write_pBuffer,0x001000,(sizeof(Write_pBuffer)/sizeof(*(Write_pBuffer))-1));
- SPI_BufferRead(Read_pBuffer,0x001000,(sizeof(Write_pBuffer)/sizeof(*(Write_pBuffer))-1));
- if(pBuffer_Cmp(Write_pBuffer,Read_pBuffer,(sizeof(Write_pBuffer)/sizeof(*(Write_pBuffer))-1)) == 1)
- {
-
- if(comparm.DebugComm & F_DebugStart)
- DebgStr_FramProc("软件模拟SPI的读写数据一致!\r\n");
- // DebgStr_FramProc("\r\n 读出的数据为:%s \r\n", Read_pBuffer);
- }
- else
- {
- if(comparm.DebugComm & F_DebugStart)
- DebgStr_FramProc("软件模拟SPI的读写数据不一致!\r\n");
- }
- }
- else
- {
- if(comparm.DebugComm & F_DebugStart)
- DebgStr_FramProc("SPI FLASH设备异常!\r\n");
- }
- }
|