FLASH_W25Q64 驱动简介

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-------------------------------------------

仅供参考,谢谢!

猜你喜欢

转载自www.cnblogs.com/lumao1122-Milolu/p/12521894.html