W25Q64.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. //#define THIS_FILE_ID 13
  2. #include "includes.h"
  3. #define W25Q_SECTOR_SIZE 4096
  4. //4Kbytes为一个Sector
  5. //16个扇区为1个Block
  6. //W25X16
  7. //容量为2M字节,共有32个Block,512个Sector
  8. //先要调用函数进行sector解保护,或者全局解保护后才能写入.
  9. //W25系列上电默认没有软件写保护,故可直接写入
  10. #define sFLASH_CS_PIN GPIO_Pin_4 /* PA.04 */
  11. #define sFLASH_CS_GPIO_PORT GPIOA /* GPIOA */
  12. #define sFLASH_CS_GPIO_CLK RCC_APB2Periph_GPIOA
  13. #define sFLASH_SPI SPI1
  14. #define sFLASH_SPI_CLK RCC_APB2Periph_SPI1
  15. #define sFLASH_SPI_SCK_PIN GPIO_Pin_5 /* PA.05 */
  16. #define sFLASH_SPI_SCK_GPIO_PORT GPIOA /* GPIOA */
  17. #define sFLASH_SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOA
  18. #define sFLASH_SPI_MISO_PIN GPIO_Pin_6 /* PA.06 */
  19. #define sFLASH_SPI_MISO_GPIO_PORT GPIOA /* GPIOA */
  20. #define sFLASH_SPI_MISO_GPIO_CLK RCC_APB2Periph_GPIOA
  21. #define sFLASH_SPI_MOSI_PIN GPIO_Pin_7 /* PA.07 */
  22. #define sFLASH_SPI_MOSI_GPIO_PORT GPIOA /* GPIOA */
  23. #define sFLASH_SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOA
  24. #define sFLASH_WP_PIN GPIO_Pin_0
  25. #define sFLASH_WP_GPIO_PORT GPIOB
  26. #define sFLASH_CS_LOW() GPIO_ResetBits(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
  27. #define sFLASH_CS_HIGH() GPIO_SetBits(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
  28. #define sFLASH_WP_DIS() GPIO_ResetBits(sFLASH_WP_GPIO_PORT, sFLASH_WP_PIN)
  29. #define sFLASH_WP_EN() GPIO_SetBits(sFLASH_WP_GPIO_PORT, sFLASH_WP_PIN)
  30. //指令表
  31. #define W25Q64_WriteEnable 0x06
  32. #define W25Q64_WriteDisable 0x04
  33. #define W25Q64_ReadStatusReg 0x05
  34. #define W25Q64_WriteStatusReg 0x01
  35. #define W25Q64_ReadData 0x03
  36. #define W25Q64_FastReadData 0x0B
  37. #define W25Q64_FastReadDual 0x3B //??
  38. #define W25Q64_PageProgram 0x02
  39. #define W25Q64_SectorErase 0x20 //erase 4k
  40. #define W25Q64_BlockErase 0x52 //erase 32k
  41. #define W25Q64_BigBlockErase 0xd8 //erase 64k
  42. #define W25Q64_ChipErase 0xC7 //0x60
  43. #define W25Q64_PowerDown 0xB9
  44. #define W25Q64_ReleasePowerDown 0xAB
  45. #define W25Q64_DeviceID 0x9F
  46. //#define W25Q64_UnprotectSector 0x39
  47. //#define W25Q64_ProtectSector 0x36
  48. uint32_t sFlash_ReadID(void); //读取FLASH ID
  49. uint8_t sFlash_ReadSR(void); //读取状态寄存器
  50. //void sFlash_Write_SR(uint8_t sr); //写状态寄存器
  51. //void sFlash_Write_Enable(void); //写使能
  52. //void sFlash_Write_Disable(void); //写保护
  53. //void sFlash_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead); //读取flash
  54. //void sFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);//写入flash
  55. //void sFlash_Erase_Chip(void); //整片擦除
  56. //void sFlash_Erase_Sector(uint32_t Dst_Addr);//扇区擦除
  57. void sFlash_Wait_Busy(void); //等待空闲
  58. //void sFlash_PowerDown(void); //进入掉电模式
  59. //void sFlash_WAKEUP(void); //唤醒
  60. //void sFlash_Protect_Sector(uint32_t Dst_Addr);
  61. //void sFlash_Unprotect_Sector(uint32_t Dst_Addr);
  62. void sFlash_SetProtectMode(unsigned char mode);//设置保护模式 0--寄存器方式 1--硬件WP操作方式
  63. void sFlash_Global_Protect(void);
  64. void sFlash_Global_Unprotect(void);
  65. static unsigned char sFlashProtectMode=0;
  66. unsigned char ExFlashWatchDog = 0;
  67. /**********************************************************************
  68. 1ms在8000~9000之间
  69. ***********************************************************************/
  70. void DelayMs(unsigned short ms)
  71. {
  72. unsigned short i;
  73. unsigned short t=ms;
  74. while(t--){
  75. for(i=0;i<8000;i++);
  76. //for(i=0;i<3000;i++);
  77. }
  78. }
  79. /**********************************************************************
  80. 1ms在8000~9000之间
  81. fclk=24M
  82. 24*1.24=29.75M
  83. ***********************************************************************/
  84. void DelayUs(unsigned short us)
  85. {
  86. unsigned char i;
  87. unsigned short t=us;
  88. while(t--)
  89. {
  90. for(i=0;i<45;i++)
  91. __nop();
  92. }
  93. }
  94. /***************************************************************
  95. W25Q64_PortInit
  96. ****************************************************************/
  97. void W25Q64_PortInit(void)
  98. {
  99. GPIO_InitTypeDef GPIO_InitStructure;
  100. /*!< sFLASH_SPI_CS_GPIO, sFLASH_SPI_MOSI_GPIO, sFLASH_SPI_MISO_GPIO
  101. and sFLASH_SPI_SCK_GPIO Periph clock enable */
  102. RCC_APB2PeriphClockCmd(sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |
  103. sFLASH_SPI_SCK_GPIO_CLK, ENABLE);
  104. /*!< sFLASH_SPI Periph clock enable */
  105. RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);
  106. /*!< Configure sFLASH_SPI pins: SCK */
  107. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
  108. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  109. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  110. GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
  111. /*!< Configure sFLASH_SPI pins: MOSI */
  112. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
  113. GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
  114. /*!< Configure sFLASH_SPI pins: MISO */
  115. GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
  116. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  117. GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
  118. /*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */
  119. GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
  120. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  121. GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
  122. /*!< Configure sFLASH_WP_PIN pin: sFLASH Card WPpin */
  123. GPIO_InitStructure.GPIO_Pin = sFLASH_WP_PIN;
  124. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  125. GPIO_Init(sFLASH_WP_GPIO_PORT, &GPIO_InitStructure);
  126. // sFLASH_WP_DIS();
  127. }
  128. /***************************************************************
  129. W25Q64_Init
  130. ****************************************************************/
  131. int W25Q64_Init(void)
  132. {
  133. uint32_t sFlashId;
  134. SPI_InitTypeDef SPI_InitStructure;
  135. // printf("sFlash Init...\r\n");
  136. W25Q64_PortInit();
  137. /*!< Deselect the FLASH: Chip Select high */
  138. sFLASH_CS_HIGH();
  139. /*!< SPI configuration */
  140. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  141. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  142. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  143. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  144. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  145. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  146. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  147. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  148. SPI_InitStructure.SPI_CRCPolynomial = 7;
  149. SPI_Init(sFLASH_SPI, &SPI_InitStructure);
  150. //
  151. /*!< Enable the sFLASH_SPI */
  152. SPI_Cmd(sFLASH_SPI, ENABLE);
  153. //
  154. DelayUs(1000);
  155. //
  156. sFlash_Write_Enable();
  157. sFlashId=sFlash_ReadID();
  158. return 1;
  159. }
  160. /**********************************************************************
  161. *
  162. ***********************************************************************/
  163. uint8_t SPIx_ReadWriteByte(u8 byte)
  164. {
  165. // < Loop while DR register in not emplty
  166. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
  167. // !< Send byte through the SPI1 peripheral
  168. SPI_I2S_SendData(sFLASH_SPI, byte);
  169. // !< Wait to receive a byte
  170. while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  171. // !< Return the byte read from the SPI bus
  172. return SPI_I2S_ReceiveData(sFLASH_SPI);
  173. }
  174. /*
  175. //SPIx 读写一个字节
  176. //返回值:读取到的字节
  177. uint8_t SPIx_ReadWriteByte(uint8_t TxData)
  178. {
  179. uint8_t retry=0;
  180. while((SPI1->SR&1<<1)==0)//等待发送区空
  181. {
  182. retry++;
  183. if(retry>200)return 0;
  184. }
  185. SPI1->DR=TxData; //发送一个byte
  186. retry=0;
  187. while((SPI1->SR&1<<0)==0) //等待接收完一个byte
  188. {
  189. retry++;
  190. if(retry>200)return 0;
  191. }
  192. return SPI1->DR; //返回收到的数据
  193. }
  194. */
  195. //读取sFlash的状态寄存器
  196. //BIT7 6 5 4 3 2 1 0
  197. //SPR RV TB BP2 BP1 BP0 WEL BUSY
  198. //SPR:默认0,状态寄存器保护位,配合WP使用
  199. //TB,BP2,BP1,BP0:FLASH区域写保护设置
  200. //WEL:写使能锁定
  201. //BUSY:忙标记位(1,忙;0,空闲)
  202. //默认:0x00
  203. uint8_t sFlash_ReadSR(void)
  204. {
  205. uint8_t byte=0;
  206. sFLASH_CS_LOW(); //使能器件
  207. SPIx_ReadWriteByte(W25Q64_ReadStatusReg); //发送读取状态寄存器命令
  208. byte=SPIx_ReadWriteByte(0Xff); //读取一个字节
  209. sFLASH_CS_HIGH(); //取消片选
  210. return byte;
  211. }
  212. //写sFlash状态寄存器
  213. //只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!!
  214. void sFlash_Write_SR(uint8_t sr)
  215. {
  216. sFLASH_CS_LOW(); //使能器件
  217. SPIx_ReadWriteByte(W25Q64_WriteStatusReg); //发送写取状态寄存器命令
  218. SPIx_ReadWriteByte(sr); //写入一个字节
  219. sFLASH_CS_HIGH(); //取消片选
  220. }
  221. //sFlash写使能
  222. //将WEL置位
  223. void sFlash_Write_Enable(void)
  224. {
  225. sFLASH_CS_LOW(); //使能器件
  226. SPIx_ReadWriteByte(W25Q64_WriteEnable); //发送写使能
  227. sFLASH_CS_HIGH(); //取消片选
  228. }
  229. //sFlash写禁止
  230. //将WEL清零
  231. void sFlash_Write_Disable(void)
  232. {
  233. sFLASH_CS_LOW(); //使能器件
  234. SPIx_ReadWriteByte(W25Q64_WriteDisable); //发送写禁止指令
  235. sFLASH_CS_HIGH(); //取消片选
  236. }
  237. //读取芯片ID W25X16的ID:0XEF14
  238. uint32_t sFlash_ReadID(void)
  239. {
  240. uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
  241. sFLASH_CS_LOW();
  242. SPIx_ReadWriteByte(W25Q64_DeviceID);//发送读取ID命令
  243. Temp0=SPIx_ReadWriteByte(0xFF);
  244. Temp1=SPIx_ReadWriteByte(0xFF);
  245. Temp2=SPIx_ReadWriteByte(0xFF);
  246. sFLASH_CS_HIGH();
  247. Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
  248. return Temp;
  249. }
  250. //读取SPI FLASH
  251. //在指定地址开始读取指定长度的数据
  252. //pBuffer:数据存储区
  253. //ReadAddr:开始读取的地址(24bit)
  254. //NumByteToRead:要读取的字节数(最大65535)
  255. void sFlash_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
  256. {
  257. uint16_t i;
  258. sFLASH_CS_LOW(); //使能器件
  259. //SPIx_ReadWriteByte(W25Q64_ReadData); //发送读取命令
  260. SPIx_ReadWriteByte(W25Q64_FastReadData);//快速读命令
  261. SPIx_ReadWriteByte((uint8_t)((ReadAddr)>>16)); //发送24bit地址
  262. SPIx_ReadWriteByte((uint8_t)((ReadAddr)>>8));
  263. SPIx_ReadWriteByte((uint8_t)ReadAddr);
  264. pBuffer[0]=SPIx_ReadWriteByte(0XFF);//快速读命令丢弃一个字节
  265. for(i=0;i<NumByteToRead;i++)
  266. {
  267. pBuffer[i]=SPIx_ReadWriteByte(0XFF); //循环读数
  268. }
  269. sFLASH_CS_HIGH(); //取消片选
  270. }
  271. //SPI在一页(0~65535)内写入少于256个字节的数据
  272. //在指定地址开始写入最大256字节的数据
  273. //pBuffer:数据存储区
  274. //WriteAddr:开始写入的地址(24bit)
  275. //NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
  276. void sFlash_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
  277. {
  278. uint16_t i;
  279. sFlash_Write_Enable(); //SET WEL
  280. sFLASH_CS_LOW(); //使能器件
  281. SPIx_ReadWriteByte(W25Q64_PageProgram); //发送写页命令
  282. SPIx_ReadWriteByte((uint8_t)((WriteAddr)>>16)); //发送24bit地址
  283. SPIx_ReadWriteByte((uint8_t)((WriteAddr)>>8));
  284. SPIx_ReadWriteByte((uint8_t)WriteAddr);
  285. for(i=0;i<NumByteToWrite;i++) SPIx_ReadWriteByte(pBuffer[i]);//循环写数
  286. sFLASH_CS_HIGH(); //取消片选
  287. sFlash_Wait_Busy(); //等待写入结束
  288. }
  289. //无检验写SPI FLASH
  290. //必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
  291. //具有自动换页功能
  292. //在指定地址开始写入指定长度的数据,但是要确保地址不越界!
  293. //pBuffer:数据存储区
  294. //WriteAddr:开始写入的地址(24bit)
  295. //NumByteToWrite:要写入的字节数(最大65535)
  296. //CHECK OK
  297. void sFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
  298. {
  299. uint16_t pageremain;
  300. pageremain=256-WriteAddr%256; //单页剩余的字节数
  301. if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节
  302. while(1)
  303. {
  304. sFlash_Write_Page(pBuffer,WriteAddr,pageremain);
  305. if(NumByteToWrite==pageremain)break;//写入结束了
  306. else //NumByteToWrite>pageremain
  307. {
  308. pBuffer+=pageremain;
  309. WriteAddr+=pageremain;
  310. NumByteToWrite-=pageremain; //减去已经写入了的字节数
  311. if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节
  312. else pageremain=NumByteToWrite; //不够256个字节了
  313. }
  314. };
  315. }
  316. //写SPI FLASH
  317. //此驱动被修改过,同扇区内允许重复写,比如参数区
  318. //记录区只允许递加写,且以16个数量递增写
  319. uint8_t sFlash_BUF[1024];
  320. void sFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
  321. {//这个函数要求每次最多只能写1024个字节,而且最好不要跨页/扇区
  322. uint32_t secpos;
  323. uint16_t secoff;
  324. uint16_t secremain;
  325. uint16_t internalPage;//要写的开始地址属于当前扇区的哪两页(1K)
  326. uint16_t pageOff;//K内偏移
  327. uint16_t pageRemain;
  328. uint8_t need_erase=0;
  329. uint16_t i,j;
  330. if(NumByteToWrite >1024) return;
  331. ExFlashWatchDog = 1;//进入FLASH写函数就置位1,跳出函数复位0
  332. secpos=WriteAddr/W25Q_SECTOR_SIZE;//扇区地址 0~511 for w25x16
  333. secoff=WriteAddr%W25Q_SECTOR_SIZE;//在扇区内的偏移
  334. secremain=W25Q_SECTOR_SIZE-secoff;//扇区剩余空间大小
  335. //if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
  336. //由于内存有效,不能使用4K那么大,只能用1K
  337. //因为要写的地址如果不为FF,则写是不成功的
  338. //那么,每次进入这个扇区(4K)时,会做一次擦除
  339. internalPage=secoff/1024;//K块
  340. pageOff = secoff%1024;//k内偏移
  341. pageRemain = 1024-pageOff;//K内剩余大小
  342. for(i=internalPage;i<4;i++)
  343. {//从所要写的地址开始检查
  344. sFlash_Read(sFlash_BUF,secpos*W25Q_SECTOR_SIZE+i*1024,1024);//读出当前扇区内的整K内容
  345. for(j=0;j<pageRemain;j++)//校验数据
  346. {
  347. if(sFlash_BUF[pageOff+j]!=0XFF)
  348. {//need earse
  349. need_erase=1;
  350. j=pageRemain;//跳出去
  351. }
  352. }
  353. if(need_erase)
  354. i=4;//跳出去
  355. else
  356. {//下一K
  357. //i就代表K块了,上面会自加
  358. pageRemain=1024;//下一块就直接检测整K了
  359. pageOff=0;
  360. }
  361. }
  362. if(need_erase)
  363. {//需要擦除
  364. sFlash_Erase_Sector(secpos);//擦除这个扇区
  365. }
  366. sFlash_Write_NoCheck(pBuffer,secpos*W25Q_SECTOR_SIZE+secoff,NumByteToWrite);//写入需要写的数量
  367. ExFlashWatchDog = 0;//进入FLASH写函数就置位1,跳出函数复位0
  368. }
  369. //擦除整个芯片
  370. //整片擦除时间:
  371. //W25X16:25s
  372. //W25X32:40s
  373. //W25X64:40s
  374. //等待时间超长...
  375. void sFlash_Erase_Chip(void)
  376. {
  377. sFlash_Write_Enable(); //SET WEL
  378. sFlash_Wait_Busy();
  379. sFLASH_CS_LOW(); //使能器件
  380. SPIx_ReadWriteByte(W25Q64_ChipErase); //发送片擦除命令
  381. sFLASH_CS_HIGH(); //取消片选
  382. sFlash_Wait_Busy(); //等待芯片擦除结束
  383. }
  384. //void sFlash_EraseChip(void)
  385. //{
  386. ///*!&lt; Send write enable instruction */
  387. //sFlash_Write_Enable();
  388. //sFlash_WaitForWriteEnd();
  389. ///*!&lt; Bulk Erase */
  390. ///*!&lt; Select the FLASH: Chip Select low */
  391. //W25X_FLASH_CS_LOW();
  392. ///*!&lt; Send Bulk Erase instruction */
  393. //sFlash_SendByte(W25X_CMD_ChipErase);
  394. ///*!&lt; Deselect the FLASH: Chip Select high */
  395. //W25X_FLASH_CS_HIGH();
  396. //
  397. ///*!&lt; Wait the end of Flash writing */
  398. //sFlash_WaitForWriteEnd();
  399. //}
  400. //擦除一个扇区
  401. //Dst_Addr:扇区地址 0~511 for w25x16
  402. //擦除一个山区的最少时间:150ms
  403. void sFlash_Erase_Sector(uint32_t Dst_Addr)
  404. {
  405. Dst_Addr*=W25Q_SECTOR_SIZE;
  406. sFlash_Write_Enable(); //SET WEL
  407. sFlash_Wait_Busy();
  408. sFLASH_CS_LOW(); //使能器件
  409. SPIx_ReadWriteByte(W25Q64_SectorErase); //发送扇区擦除指令
  410. SPIx_ReadWriteByte((uint8_t)((Dst_Addr)>>16)); //发送24bit地址
  411. SPIx_ReadWriteByte((uint8_t)((Dst_Addr)>>8));
  412. SPIx_ReadWriteByte((uint8_t)Dst_Addr);
  413. sFLASH_CS_HIGH(); //取消片选
  414. sFlash_Wait_Busy(); //等待擦除完成
  415. }
  416. //保护全芯片
  417. void sFlash_Global_Protect(void)
  418. {
  419. //sFlash_Wait_Busy();
  420. sFlash_Write_Enable(); //SET WEL
  421. sFlash_Wait_Busy();
  422. sFlash_Write_SR(0x3c);
  423. //sFlash_Wait_Busy();
  424. }
  425. //解保护全芯片
  426. void sFlash_Global_Unprotect(void)
  427. {
  428. //sFlash_Wait_Busy();
  429. sFlash_Write_Enable(); //SET WEL
  430. sFlash_Wait_Busy();
  431. sFlash_Write_SR(0x80);
  432. //sFlash_Wait_Busy();
  433. }
  434. //等待空闲
  435. void sFlash_Wait_Busy(void)
  436. {
  437. while ((sFlash_ReadSR()&0x01)==0x01){ // 等待BUSY位清空
  438. }
  439. }
  440. //进入掉电模式
  441. void sFlash_PowerDown(void)
  442. {
  443. // sFLASH_CS_LOW(); //使能器件
  444. // SPIx_ReadWriteByte(W25Q64_PowerDown); //发送掉电命令
  445. // sFLASH_CS_HIGH(); //取消片选
  446. // DelayUs(3); //等待TPD
  447. }
  448. //唤醒
  449. void sFlash_WAKEUP(void)
  450. {
  451. // sFLASH_CS_LOW(); //使能器件
  452. // SPIx_ReadWriteByte(W25Q64_ReleasePowerDown); // send W25Q64_PowerDown command 0xAB
  453. // sFLASH_CS_HIGH(); //取消片选
  454. // DelayUs(3); //等待TRES1
  455. }
  456. /*********************************************
  457. *
  458. ***********************************************/
  459. /*
  460. void W25Q64Test(void)
  461. {
  462. uint32_t sFlashId;
  463. unsigned char sFlashSR;
  464. static int scStep=0;
  465. unsigned char t;
  466. char buf[200];
  467. int i;
  468. switch(scStep){
  469. case 0:
  470. sFlashId=sFlash_ReadID();
  471. printf("sFlashID=%04x\r\n",sFlashId);
  472. break;
  473. case 1:
  474. memset(buf,0,sizeof(buf));
  475. strcpy(buf,"333333333444444444455555555555\r\n");
  476. printf("sFlash Write=%s",buf);
  477. sFlash_Write((unsigned char *)buf,0,sizeof(buf));
  478. break;
  479. case 2:
  480. memset(buf,0,sizeof(buf));
  481. sFlash_Read((unsigned char *)buf,0,sizeof(buf));
  482. printf("sFlash Read=%s",buf);
  483. printf("sFlash write 8MB...\r\n");
  484. for(i=0;i<200;i++){
  485. buf[i]=i;
  486. }
  487. for(i=0;i<1000;i++){
  488. sFlash_Write_Page((unsigned char *)buf,i*4096,200);
  489. }
  490. printf("sFlash write 8MB OK!\r\n");
  491. break;
  492. case 3:
  493. break;
  494. }
  495. if(scStep<3)scStep++;
  496. }
  497. */