W25Q64FV是一款FLASH存储芯片,由32768页组成的存储芯片,其中每一页有256字节。
每次最多可以一次写入256字节(一页);擦除则可以按扇区进行擦除(一个扇区16页,4KB字节),或者可以按128个页进行擦除(32KB),或者可以按256个页(64KB)进行擦除,以及整个芯片擦除方式进行擦除。
W25Q64FV支持标准的同步串行通信协议(SPI),下面简单举例介绍其常用的驱动程序:
数据定义:
1 #ifndef __W25Q64Driver_H 2 #define __W25Q64Driver_H 3 4 //ID 5 #define W25Q64 0xEF16 6 7 // W25Q64 Registors 8 #define W25Q64_WRITE_ENABLE_CMD 0X06 9 #define W25Q64_WRITE_DISABLE_CMD 0x04 10 #define W25Q64_rSTATUS_REG_CMD 0x05 11 #define W25Q64_wSTATUS_REG_CMD 0x01 12 #define W25Q64_READ_DARA_CMD 0x03 13 #define W25Q64_FAST_READ_DATA_CMD 0x0B 14 #define W25Q64_FAST_READ_DUAL_CMD 0x3B 15 #define W25Q64_PAGE_WRITE_CMD 0x02 16 #define W25Q64_BLOCK_ERASE_CMD 0xD8 17 #define W25Q64_SECTOR_ERASE_CMD 0x20 18 #define W25Q64_CHIP_ERASE_CMD 0xC7 19 #define W25Q64_PWR_DOWN_CMD 0xB9 20 #define W25Q64_RELEASE_PWR_DOWN_CMD 0xAB 21 22 #define W25Q64_DEVICE_ID 0xAB 23 #define W25Q64_MANUFACT_ID 0x90 24 #define W25Q64_JEDEC_DEVICE_ID 0x9F 25 26 27 28 29 //Block0 64K 30 #define Block0_Header_Addr 0x000000 31 #define Block0_Tail_Addr 0x00FFFF 32 33 //... Block N ... 34 35 //Block127 64K 36 #define Block127_Header_Addr 0x7F0000 37 #define Block127_Tail_Addr 0x7FFFFF 38 39 40 void SPI_Interface_Init(void); 41 unsigned char WReadSPI2(unsigned char byinput); 42 void W25Q64_PageRead(unsigned char *pOutBuf,unsigned long Addr,unsigned int NumByte); 43 void W25Q64_PageWrite(unsigned char *pInputBuf,unsigned long Addr,unsigned int NumBytes); 44 void W25Q64_nPageWrite(unsigned char *pInputbuf,unsigned long Addr,unsigned int NumBytes); 45 void W25Q64_Sector_Erase(unsigned long Addr); 46 void W25Q64_Block_Erase(unsigned long Addr); 47 48 49 #endif
功能函数实现:
1 #include"stdio.h" 2 #include"string.h" 3 4 #include"IO_Port.h" 5 #include"W25Q64Driver.h" 6 7 8 void SPI_Interface_Init(void) 9 { 10 P3SEL |= BIT1+BIT2+BIT3; //option select. P3.1Master out;P3.2Master in ;P3.3Master CLK out 11 12 UCB0CTL1 |= UCSWRST; // **Put state machine in reset** 13 UCB0IE=0X00; 14 15 UCB0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; //3-pin, 8-bit SPI master clk polarity select the inactive state is low 16 /* 17 /---------------------------// SPI master 18 /--------------------//Synchronous mode 19 /-------------//date captured on the first UCLK edge change flow edge 20 /-----//MSB first 21 */ 22 UCB0CTL1 |= UCSSEL_2; //SMCLK Sourse 23 UCB0BR0 = 0x02; // /2 24 UCB0BR1 = 0; // No modulation 25 26 UCB0CTL1 &= ~UCSWRST; //Initialize USCI state machine;clearing this bit releases the USCI for opertion 27 28 //EE_WP_High; //release write protect;LOW ACTIVE 29 EE_CS_Low; //LOW ACTIVE 30 } 31 /*-------------------------------------------------- 32 *read SPI2 33 *parameter: data to write 34 *return: data to read 35 //-------------------------------------------------*/ 36 unsigned char WReadSPI2(unsigned char byinput) 37 { 38 unsigned char i; 39 while(!(UCB0IFG&UCTXIFG)); //TXBUF Ready? 40 UCB0TXBUF=byinput; //TXIFG automatically reset when a character is writen the the txbuf 41 while(!(UCB0IFG&UCRXIFG)); //wait data has mvoed to TX shift register. 42 i=UCB0RXBUF; 43 return i; 44 } 45 /* 46 7 6 5 4 3 2 1 0 47 SPR RV TB BP2 BP1 BP0 WEL BUSY 48 SPR: 49 TB BP2 BP1 BP0:FLASH 50 WEL: 51 BUSY: 52 */ 53 unsigned char W25Q64_ReadSR(void) 54 { 55 unsigned char status=0; 56 EE_CS_Low; 57 WReadSPI2(W25Q64_rSTATUS_REG_CMD);//05 58 status=WReadSPI2(0xFF); 59 EE_CS_High; 60 return status; 61 } 62 //SPR TB BP2 BP1 BP0 (bit,5,4,3,2) 63 void W25Q64_WriteSR(unsigned char SetReg) 64 { 65 EE_CS_Low; 66 WReadSPI2(W25Q64_wSTATUS_REG_CMD); 67 WReadSPI2(SetReg); 68 EE_CS_Low; 69 } 70 //WEL 71 void W25Q64_WriteEnable(void) 72 { 73 EE_CS_Low; 74 WReadSPI2(W25Q64_WRITE_ENABLE_CMD); 75 EE_CS_High; 76 } 77 //WEL 78 void W25Q64_WriteDisable(void) 79 { 80 EE_CS_Low; 81 WReadSPI2(W25Q64_WRITE_DISABLE_CMD); 82 EE_CS_High; 83 } 84 void W25Q64_Wait_Busy(void) 85 { 86 while((W25Q64_ReadSR()&0x01)==0x01); 87 } 88 //pOutBuf:buffer 89 //Addr:24bit) 90 //NumByte: 91 void W25Q64_PageRead(unsigned char *pOutBuf,unsigned long Addr,unsigned int NumByte) 92 { 93 EE_CS_Low; 94 //$03 this cmd allows one or more data bytes to be sequentially read from the memory. 95 WReadSPI2(W25Q64_READ_DARA_CMD); 96 WReadSPI2((Addr&0x00ff0000)>>16); 97 WReadSPI2((Addr&0x0000ff00)>>8); 98 WReadSPI2(Addr&0x000000ff); 99 while(NumByte--) 100 { 101 *pOutBuf++ = WReadSPI2(0xFF); 102 } 103 EE_CS_High; 104 } 105 //pInputBuf: 106 //Addr: 107 //NumBytes: 108 void W25Q64_PageWrite(unsigned char *pInputBuf,unsigned long Addr,unsigned int NumBytes) 109 { 110 W25Q64_WriteEnable(); //WEL=1 111 EE_CS_Low; 112 //$02 this cmd allows one byte or 256 bytes(a page) 0f data to be programmed 113 // at previously erased memory locations. 114 WReadSPI2(W25Q64_PAGE_WRITE_CMD); 115 WReadSPI2((Addr&0x00ff0000)>>16); 116 WReadSPI2((Addr&0x0000ff00)>>8); 117 WReadSPI2(Addr&0x000000ff); 118 while(NumBytes--) 119 { 120 WReadSPI2(*pInputBuf++); 121 } 122 EE_CS_High; 123 W25Q64_Wait_Busy(); 124 } 125 //pInputBuf: 126 //Addr: 127 //NumBytes: 128 void W25Q64_nPageWrite(unsigned char *pInputbuf,unsigned long Addr,unsigned int NumBytes) 129 { 130 unsigned int PageRestCount; 131 PageRestCount=256-Addr%256; 132 if(NumBytes<=PageRestCount) 133 PageRestCount=NumBytes; 134 while(1) 135 { 136 W25Q64_PageWrite(pInputbuf,Addr,PageRestCount); 137 if(NumBytes==PageRestCount) 138 break; 139 else 140 { 141 pInputbuf += PageRestCount; 142 Addr += PageRestCount; 143 NumBytes-=PageRestCount; 144 if(NumBytes > 256) 145 { 146 PageRestCount=256; 147 } 148 else 149 { 150 PageRestCount=NumBytes; 151 } 152 } 153 } 154 } 155 //Addr 156 //erase a sector(4K ) 157 void W25Q64_Sector_Erase(unsigned long Addr) 158 { 159 W25Q64_WriteEnable(); //WEL=1 160 W25Q64_Wait_Busy(); 161 Addr<<=12; 162 EE_CS_Low; 163 164 WReadSPI2(W25Q64_SECTOR_ERASE_CMD); 165 WReadSPI2((Addr&0x00ff0000)>>16); 166 WReadSPI2((Addr&0x0000ff00)>>8); 167 WReadSPI2(Addr&0x000000ff); 168 EE_CS_High; 169 W25Q64_Wait_Busy(); 170 } 171 //BLOCK区 172 //Addr 173 //vBlock: Block 174 //erase a block(64K ) 175 void W25Q64_Block_Erase(unsigned long Addr) 176 { 177 W25Q64_WriteEnable(); //WEL=1 178 W25Q64_Wait_Busy(); 179 Addr<<=16; 180 EE_CS_Low; 181 182 WReadSPI2(W25Q64_BLOCK_ERASE_CMD); 183 WReadSPI2((Addr&0x00ff0000)>>16); 184 WReadSPI2((Addr&0x0000ff00)>>8); 185 WReadSPI2(Addr&0x000000ff); 186 EE_CS_High; 187 W25Q64_Wait_Busy(); 188 } 189 190 191 //about 1 min 192 void W25Q64_ChipErase(void) 193 { 194 W25Q64_WriteEnable(); //WEL=1 195 W25Q64_Wait_Busy(); 196 EE_CS_Low; 197 //$c7 The instruction sets all memory within the device to the erased state of all FFh 198 WReadSPI2(W25Q64_CHIP_ERASE_CMD); 199 EE_CS_High; 200 201 W25Q64_Wait_Busy(); 202 } 203 //Power Down mode 204 void W25Q64_Power_Down() 205 { 206 EE_CS_Low; 207 WReadSPI2(W25Q64_PWR_DOWN_CMD); 208 EE_CS_High; 209 } 210 //Weka up Mode 211 void W25Q64_ReleasePowerDown(void) 212 { 213 EE_CS_Low; 214 WReadSPI2(W25Q64_RELEASE_PWR_DOWN_CMD); 215 EE_CS_High; 216 } 217 //ID 218 unsigned int W25Q64_ReadID(void) 219 { 220 unsigned int tmp=0; 221 EE_CS_Low; 222 WReadSPI2(0x90); 223 WReadSPI2(0x00); 224 WReadSPI2(0x00); 225 WReadSPI2(0x00); 226 tmp|=WReadSPI2(0xFF)<<8; 227 tmp|=WReadSPI2(0xFF); 228 EE_CS_High; 229 return tmp; 230 } 231 232 //------------------------------- End-------------------------------------------
仅供参考,谢谢!