GPIO口模拟SPI - 驱动W25Qxx
2016-01-11 22:26
441 查看
废话少说,直接上代码:
DataFlash_reg.h:
DataFlash_cmd.h:
DataFlash_reg.c:
DataFlash_reg.h:
/* Using SPIO simulator PB8 -- spi cs PA9 -- spi clock PA10 -- spi MOSI PB7 -- spi MISO PA8 -- hold PC4 -- Write protect */ #define SPI_CS_Port gpioPortB #define SPI_CS_Pin 8 #define SPI_CS (*((uint32_t *)(BITBAND_PER_BASE + (((uint32_t)&(GPIO->P[SPI_CS_Port].DOUT) - PER_MEM_BASE) * 32) + (SPI_CS_Pin * 4)))) #define SPI_CLK_Port gpioPortA #define SPI_CLK_Pin 9 #define SPI_CLK (*((uint32_t *)(BITBAND_PER_BASE + (((uint32_t)&(GPIO->P[SPI_CLK_Port].DOUT) - PER_MEM_BASE) * 32) + (SPI_CLK_Pin * 4)))) #define SPI_MOSI_Port gpioPortA #define SPI_MOSI_Pin 10 #define SPI_MOSI (*((uint32_t *)(BITBAND_PER_BASE + (((uint32_t)&(GPIO->P[SPI_MOSI_Port].DOUT) - PER_MEM_BASE) * 32) + (SPI_MOSI_Pin * 4)))) #define SPI_MISO_Port gpioPortB #define SPI_MISO_Pin 7 #define SPI_MISO (*((uint32_t *)(BITBAND_PER_BASE + (((uint32_t)&(GPIO->P[SPI_MISO_Port].DIN) - PER_MEM_BASE) * 32) + (SPI_MISO_Pin * 4)))) unsigned char DataFlash_Write_Byte(unsigned char Data);
DataFlash_cmd.h:
#ifndef __DATAFLASH_CMD_H__ #define __DATAFLASH_CMD_H__ #define W25X_BUSY 0 #define W25X_NotBUSY 1 #define Dummy_Byte1 0xA5 /********************************************* - W25X16的操作指令表,MCU通过向W25X16 发送以下指令就可以对W25X16进行以下的操作 *********************************************/ #define W25X_WriteEnable 0x06 //Write Enable #define W25X_WriteEnableVSR 0x50 //Write Enable for Volatile Status Register #define W25X_WriteDisable 0x04 //Write Disable #define W25X_ReadStatusReg1 0x05 //读状态寄存器1:S7~S0 #define W25X_ReadStatusReg2 0x35 //读状态寄存器2:S15~S8 #define W25X_WriteStatusReg 0x01 //写读状态寄存器:BYTE1:S7~S0 BYTE2:S15~S8 #define W25X_PageProgram 0x02 //单页编程:BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 BYTE4:D7~D0 #define W25X_SectorErase 0x20 //扇区擦除:4K BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 #define W25X_BlockErase32K 0x52 //块擦除:32K BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 #define W25X_BlockErase64K 0xD8 //块擦除:64K BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 #define W25X_ChipErase 0xC7 //芯片擦除 #define W25X_EraseSuspend 0x75 //暂停擦除 #define W25X_EraseResume 0x7A //恢复擦除 #define W25X_PowerDown 0xB9 //掉电 #define W25X_ContinuousReadMode 0xFF //连续读模式 #define W25X_ReadData 0x03 //读数据:BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 BYTE4:D7~D0 #define W25X_FastReadData 0x0B //快速读取:BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 BYTE4:dummy BYTE5:D7~D0 #define W25X_FastReadDual 0x3B //快速双读取:BYTE1:A23~A16 BYTE2:A15~A8 BYTE3:A7~A0 BYTE4:dummy BYTE5:D7~D0 #define W25X_ReleasePowerDown 0xAB #define W25X_DeviceID 0xAB #define W25X_ManufactDeviceID 0x90 #define W25X_JedecDeviceID 0x9F #endif
DataFlash_reg.c:
#include <stdint.h> #include <stdbool.h> #include "em_device.h" #include "em_chip.h" #include "em_cmu.h" #include "em_gpio.h" #include "DataFlash_reg.h" #include "DataFlash_cmd.h" /* Using SPIO simulator PB8 -- spi cs PA9 -- spi clock PA10 -- spi MOSI PB7 -- spi MISO PA8 -- hold PC4 -- Write protect */ void DataFlash_Initial_IO(void) { GPIO_PinModeSet(gpioPortB,8,gpioModePushPull,1); GPIO_PinModeSet(gpioPortA,9,gpioModePushPull,1); GPIO_PinModeSet(gpioPortA,10,gpioModePushPull,1); GPIO_PinModeSet(gpioPortB,7,gpioModeInputPull,1); GPIO_PinModeSet(gpioPortA,8,gpioModePushPull,1); GPIO_PinModeSet(gpioPortC,4,gpioModePushPull,1); } //*************** Write enable **************************** OK void DataFlash_WriteEnable (void) { SPI_CS = 0; __NOP(); __NOP(); DataFlash_Write_Byte(W25X_WriteEnable); __NOP(); __NOP(); SPI_CS = 1; } //*************** Write disable **************************** OK void DataFlash_WriteDisable (void) { SPI_CS = 0; __NOP(); __NOP(); DataFlash_Write_Byte(W25X_WriteDisable); __NOP(); __NOP(); SPI_CS = 1; } //***************判BUSY******************************** unsigned char DataFlash_SPI_BUSY_OrNot (void) //在读和写之前得先判断FLASH是否BUSY { //BUSY的原因是擦除,或是连续读写 unsigned char k; //如果没有以上方式,不必判定可以写读 SPI_CS = 0; __NOP(); __NOP(); DataFlash_Write_Byte(W25X_ReadStatusReg1); k = DataFlash_Write_Byte(Dummy_Byte1); __NOP(); __NOP(); SPI_CS = 1; if(k&0x01)return (W25X_BUSY); else return (W25X_NotBUSY); } void SPI_Flash_Read(uint32_t ReadAddr, uint32_t numBytes,void *data) { uint8_t *rxBuffer = (uint8_t *) data; /* Enable chip select */ SPI_CS = 0; __NOP(); __NOP(); DataFlash_Write_Byte(W25X_ReadData); DataFlash_Write_Byte(ReadAddr >> 16); DataFlash_Write_Byte(ReadAddr >> 8); DataFlash_Write_Byte(ReadAddr); while (numBytes--) { *rxBuffer = DataFlash_Write_Byte(Dummy_Byte1); //Read one byte rxBuffer++; } /* Disable chip select */ __NOP(); __NOP(); SPI_CS = 1; } /******************************************************************************* * Function Name : SPI_FLASH_ReadID * Description : Reads FLASH identification. * Input : None * Output : None * Return : FLASH identification *******************************************************************************/ unsigned long SPI_Flash_ReadID(void) { unsigned int Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0; /* Enable chip select */ SPI_CS = 0; __NOP(); __NOP(); /* Send "RDID " instruction */ DataFlash_Write_Byte(0x9F); /* Read a byte from the FLASH */ Temp0 = DataFlash_Write_Byte(Dummy_Byte1); /* Read a byte from the FLASH */ Temp1 = DataFlash_Write_Byte(Dummy_Byte1); /* Read a byte from the FLASH */ Temp2 = DataFlash_Write_Byte(Dummy_Byte1); /* Disable chip select */ __NOP(); __NOP(); SPI_CS = 1; Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2; return Temp; } ////每次写一页面 地址低8位应为0 //void SPI_Flash_Page_Write(uint32_t pageNum, unsigned char* data) //{ // uint8_t *rxBuffer = data; // while(1) // { // if(SPI_BUSY_OrNot() == W25X_NotBUSY) break; // } // // WriteEnable(); //写允许 // // /* Enable chip select */ // GPIO_PinOutClear(Flash_SPI_CS_PORT, Flash_SPI_CS_BIT); // // SPI_FlashWrite(W25X_PageProgram); // // unsigned int WriteAddr = pageNum<<8; // // SPI_FlashWrite((WriteAddr >> 16)); // SPI_FlashWrite((uint32_t)(WriteAddr >> 8)); // SPI_FlashWrite((uint32_t) WriteAddr); // // for(int i=0;i<SPI_FLASH_PAGE_SIZE;i++) // { // SPI_FlashWrite(*rxBuffer); // rxBuffer++; // } // /* Disable chip select */ // GPIO_PinOutSet(Flash_SPI_CS_PORT, Flash_SPI_CS_BIT); // // WriteDisable();//写禁止 //} // ////**************片擦除****************** OK //void SPI_EraseDevice(void) //{ // while(1) // { // if(SPI_BUSY_OrNot() == W25X_NotBUSY) break; // } // WriteEnable(); //写允许 // GPIO_PinOutClear(Flash_SPI_CS_PORT, Flash_SPI_CS_BIT); // SPI_FlashWrite(W25X_ChipErase); // GPIO_PinOutSet(Flash_SPI_CS_PORT, Flash_SPI_CS_BIT); //} unsigned char DataFlash_Write_Byte(unsigned char Data) { unsigned char Out = 0; unsigned char i = 0; SPI_CLK = 0; for(i = 0; i < 8; i++) { if(Data & 0x80)SPI_MOSI = 1; else SPI_MOSI = 0; Data = Data << 1; __NOP(); __NOP(); __NOP(); SPI_CLK = 1; if(SPI_MISO)Out |= 0x80 >> i; __NOP(); __NOP(); __NOP(); SPI_CLK = 0; } SPI_CLK = 0; return Out; }
相关文章推荐
- iOS图片拉伸技巧
- Android Dialog
- 268. Missing Number
- 2016.1.8 总结
- 学习shell编程笔记(一)
- 2016.1.7 总结
- 关于获取当前目录列表
- PHP正则表达式实战
- iOS开发UITableView小结
- struts+service+action+数据库
- VIJOS1420Valentine’s Seat
- 前端开发工程师之路
- COM学习笔记3_IUnknown的三个接口函数
- 1189: [HNOI2007]紧急疏散evacuate 二分答案+网络流
- Nodejs mac版安装
- Search for a Range
- Vmware 11.0下面安装Ubuntu14.04
- VS项目属性的一些配置项的总结
- DFS Codeforces505D Mr. Kitayuta's Technology
- 用Python编写一个简单的Http Server