找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3660|回復: 1
打印 上一主題 下一主題
收起左側(cè)

C語言源代碼W25M02驅(qū)動使用

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:155701 發(fā)表于 2021-6-9 11:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本案例使用的是新唐M451的SPI1驅(qū)動W25M02的.
  1. //W25 IC復位
  2. void SpiFlash_Rest(void)
  3. {
  4.     unsigned int au32SourceData;
  5.     unsigned int au32DestinationData;
  6.     SPI_SET_SS_LOW(SPI1);
  7.     //有些地方使用了 16 24 32 位模式 所以這里會重新設置一遍
  8.     SPI_SET_DATA_WIDTH(SPI1, 8);//設置SPI為8位模式
  9.     au32SourceData = 0xFF;//復位指令      
  10.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  11.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  12. }
  13. //選擇模具 IChange == 0 或 1
  14. void SpiFlash_IC_Change(u8 IChange)
  15. {
  16.    unsigned int au32SourceData;
  17.     unsigned int au32DestinationData;
  18.     SPI_SET_SS_LOW(SPI1);
  19.    SPI_SET_DATA_WIDTH(SPI1, 8);//設置SPI為8位模式
  20.     //選擇模具指令 選擇W25M02GV內(nèi)的兩片W25N01GV中的其中一片 然后進行操作
  21.     au32SourceData = 0xC2;
  22.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  23.     au32SourceData = IChange;      
  24. SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  25. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  26. }
  27. //讀取IC ID值 一共24位
  28. unsigned int SpiFlash_ReadMidDid(void)
  29. {
  30.     unsigned int au32SourceData;
  31.     unsigned int au32DestinationData;
  32.     SPI_SET_SS_LOW(SPI1);
  33.       SPI_SET_DATA_WIDTH(SPI1, 8);
  34.       au32SourceData = 0x9F;//讀取ID指令  9F 00
  35.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  36.     au32SourceData = 0x0;
  37.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  38. //如果不想更改SPI設置 也可以拆成3個8位來操作     
  39. SPI_SET_DATA_WIDTH(SPI1, 24);//設置SPI為24位模式
  40.     I2S_CLR_RX_FIFO(SPI1);//清除SPI緩存
  41.     // 接收
  42.     au32SourceData = 0x0;
  43.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  44.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  45.     //導出SPI緩存數(shù)據(jù)
  46.     au32DestinationData = SPI_READ_RX(SPI1);
  47.     return (au32DestinationData & 0xffffff);
  48. }
  49. //寫寄存器1  
  50. void SpiFlash_WriteStatusReg1(u8 SRData)
  51. {    unsigned int au32SourceData;
  52.     unsigned int au32DestinationData;
  53.     SPI_SET_SS_LOW(SPI1);
  54.     SPI_SET_DATA_WIDTH(SPI1, 8);
  55.     au32SourceData = 0x01;//寫寄存器1指令: 01 A0
  56.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  57. au32SourceData = 0xA0;
  58.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  59. au32SourceData = SRData;;//寫寄存器1:數(shù)據(jù)
  60.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  61. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  62. }
  63. //寫狀態(tài)寄存器2
  64. void SpiFlash_WriteStatusReg2(u8 SRData)
  65. {
  66.     unsigned int au32SourceData;
  67.     unsigned int au32DestinationData;
  68.     SPI_SET_SS_LOW(SPI1);
  69.     SPI_SET_DATA_WIDTH(SPI1, 8);
  70.     au32SourceData = 0x01;//寫寄存器2指令: 01 B0
  71.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  72. au32SourceData = 0xB0;
  73.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  74. au32SourceData = SRData;//寫寄存器2:數(shù)據(jù)
  75.    SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  76. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  77. }
  78. //讀寄存器1
  79. unsigned int SpiFlash_ReadStatusReg1(void)
  80. {
  81.     unsigned int au32SourceData;
  82.     unsigned int au32DestinationData;
  83.     SPI_SET_SS_LOW(SPI1);
  84.     SPI_SET_DATA_WIDTH(SPI1, 8);
  85.     au32SourceData = 0x05;//讀寄存器1指令: 05 A0
  86.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  87. au32SourceData = 0xA0;
  88.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  89. I2S_CLR_RX_FIFO(SPI1);
  90. au32SourceData = 0X0;
  91.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  92. au32DestinationData = SPI_READ_RX(SPI1);//導致寄存器1數(shù)據(jù)
  93. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  94.     return (au32DestinationData & 0xFF);
  95. }
  96. //讀寄存器2
  97. unsigned int SpiFlash_ReadStatusReg2(void)
  98. {
  99.     unsigned int au32SourceData;
  100.     unsigned int au32DestinationData;
  101.     SPI_SET_SS_LOW(SPI1);    SPI_SET_DATA_WIDTH(SPI1, 8);
  102.     au32SourceData = 0x05;//讀寄存器2指令: 05 B0
  103.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  104. au32SourceData = 0xB0;
  105.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  106. I2S_CLR_RX_FIFO(SPI1);
  107. au32SourceData = 0X0;
  108.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  109. au32DestinationData = SPI_READ_RX(SPI1);
  110. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  111.     return (au32DestinationData & 0xFF);
  112. }
  113. //讀寄存器3
  114. unsigned int SpiFlash_ReadStatusReg3(void)
  115. {
  116.     unsigned int au32SourceData;
  117.     unsigned int au32DestinationData;
  118.    SPI_SET_SS_LOW(SPI1);
  119.     SPI_SET_DATA_WIDTH(SPI1, 8);
  120.     au32SourceData = 0x05;//讀寄存器2指令: 05 C0
  121.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  122. au32SourceData = 0xC0;
  123.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  124. I2S_CLR_RX_FIFO(SPI1);
  125. au32SourceData = 0X0;
  126.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  127. au32DestinationData = SPI_READ_RX(SPI1);
  128. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  129.     return (au32DestinationData & 0xFF);
  130. }
  131. //等待ic空閑
  132. void SpiFlash_WaitReady(void)
  133. {
  134.     unsigned int ReturnValue;
  135.     do
  136. { ReturnValue = SpiFlash_ReadStatusReg3();
  137.         ReturnValue = ReturnValue & 1;
  138.     }while(ReturnValue != 0);
  139. }
  140. //判斷是否正在寫入IC
  141. void SpiFlash_WaitWEL_1(void)
  142. {
  143.     unsigned int ReturnValue;
  144.     do
  145. { ReturnValue = SpiFlash_ReadStatusReg3();
  146.         ReturnValue = ReturnValue | 0XFD;
  147.    }while(ReturnValue != 0XFF);
  148. }
  149. //擦除一塊數(shù)據(jù)  64頁 :64*2048=128k 字節(jié)
  150. void SpiFlash_PageErase(u32 StartAddress)
  151. {    unsigned int au32SourceData;
  152.     SPI_SET_SS_LOW(SPI1);
  153.     SPI_SET_DATA_WIDTH(SPI1, 8);
  154.     au32SourceData = 0x06;//寫啟用指令 06
  155.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  156.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  157. SpiFlash_WaitReady();//等閑
  158. SpiFlash_WaitWEL_1();
  159.     SPI_SET_SS_LOW(SPI1);
  160.     au32SourceData = 0xD8;//擦除塊 指令 D8 00
  161.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  162.     au32SourceData = 0x0;
  163.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  164. SPI_SET_DATA_WIDTH(SPI1, 16);
  165. //改塊64頁中任意一頁地址
  166. au32SourceData=ADDR_Row_PA15_PA0(StartAddress);
  167.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  168.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  169. SpiFlash_WaitReady();//等閑
  170. }
  171. //擦除功能函數(shù)
  172. void SpiFlash_ChipErase(u32 StartAddress)
  173. {
  174. SpiFlash_PageErase(StartAddress);
  175. W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
  176. if(W25M_STR3 & 0x04)//擦除失敗
  177. {
  178. //printf("\r\nErase_Error\r\n");
  179. SpiFlash_PageErase(StartAddress);
  180. }
  181. SpiFlash_WaitReady();
  182. }
  183. //寫入數(shù)據(jù)功能函數(shù)
  184. //StartAddress1 12~27位: 頁地址
  185. //StartAddress1 0~11位:頁內(nèi)數(shù)據(jù)位置
  186. //ByteCount字節(jié)個數(shù)
  187. void SpiFlash_WriteData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
  188. {
  189.     u32 au32SourceData;
  190.     unsigned int Counter;
  191.     SPI_SET_SS_LOW(SPI1);
  192.     SPI_SET_DATA_WIDTH(SPI1, 8);
  193.     au32SourceData = 0x06;//寫啟用指令 06
  194.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  195.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  196. SpiFlash_WaitReady();//等閑
  197. SpiFlash_WaitWEL_1();
  198.     SPI_SET_SS_LOW(SPI1);
  199.       au32SourceData = 0x02;//數(shù)據(jù)寫入IC緩沖區(qū)指令 02
  200. SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  201.     SPI_SET_DATA_WIDTH(SPI1, 16);   au32SourceData=StartAddress1;
  202.     au32SourceData = (u16)(au32SourceData&0x7ff);//頁內(nèi)位置
  203.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  204.     SPI_SET_DATA_WIDTH(SPI1, 8);
  205.     for(Counter = 0; Counter < ByteCount; Counter++)//數(shù)據(jù)寫入IC換沖執(zhí)行過程
  206.     {
  207.       au32SourceData = DataBuffer[Counter];
  208. SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  209.     }
  210.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  211. SpiFlash_WaitReady();//等閑
  212. SPI_SET_SS_LOW(SPI1);
  213. au32SourceData = 0x10;//換沖導入存儲區(qū)指令 10 00
  214.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  215. au32SourceData = 0x0;
  216.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  217. SPI_SET_DATA_WIDTH(SPI1, 16);
  218. au32SourceData=StartAddress1;
  219. au32SourceData = (u16)(au32SourceData>>12);//頁地址
  220.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  221. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  222. SpiFlash_WaitReady();//等閑
  223. W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
  224. if(W25M_STR3 & 0x08)//寫入失敗
  225. {
  226. //printf("\r\nWrite_Error\r\n");
  227. }
  228. SpiFlash_WaitReady();
  229. }
  230. //一頁數(shù)據(jù)導出到IC緩沖區(qū)
  231. void SpiFlash_LoadData(u32 StartAddress1)
  232. {
  233.     u32 au32SourceData;
  234. SPI_SET_SS_LOW(SPI1);
  235. SPI_SET_DATA_WIDTH(SPI1, 8);
  236. au32SourceData = 0x13;//頁數(shù)據(jù)讀取到緩存指令 13 00
  237.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  238.     au32SourceData = 0x0;
  239.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  240. SPI_SET_DATA_WIDTH(SPI1, 16);
  241. au32SourceData=(u16)(StartAddress1>>12);//頁地址
  242. SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  243. SPI_SET_SS_HIGH(SPI1);
  244. sys_delayms(2);
  245. SpiFlash_WaitReady();//等閑

  246. }
  247. //讀出數(shù)據(jù)功能函數(shù)
  248. //StartAddress1 12~27位: 頁地址
  249. //StartAddress1 0~11位:頁內(nèi)數(shù)據(jù)位置
  250. //ByteCount字節(jié)個數(shù)void SpiFlash_ReadData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
  251. {
  252.     u32 au32SourceData;
  253.     unsigned int au32DestinationData;
  254.     unsigned int Counter;
  255. SpiFlash_LoadData(StartAddress1);
  256. W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
  257. if(W25M_STR3 & 0x20)//讀取失敗
  258. {
  259. //printf("\r\nRead_Load_Error\r\n");
  260. SpiFlash_LoadData(StartAddress1);
  261. W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
  262. if(W25M_STR3 & 0x20)//讀取失敗
  263. {
  264. //UART1_PUTS(":讀取失敗\r\n");
  265. }
  266. }
  267.    SPI_SET_SS_LOW(SPI1);
  268.     SPI_SET_DATA_WIDTH(SPI1, 8);
  269.     au32SourceData = 0x03;//讀取IC緩沖區(qū)數(shù)據(jù)指令 03
  270.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  271.     SPI_SET_DATA_WIDTH(SPI1, 16);
  272. au32SourceData=StartAddress1;
  273.     au32SourceData = (u16)(au32SourceData&0x7ff);//頁內(nèi)位置
  274.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  275.     SPI_SET_DATA_WIDTH(SPI1, 8);
  276.     au32SourceData = 0x0;
  277.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  278.     I2S_CLR_RX_FIFO(SPI1);//清空SPI緩沖區(qū) 準備接收IC緩沖區(qū)數(shù)據(jù)
  279.     for(Counter = 0; Counter < ByteCount; Counter++)
  280.     {
  281. au32SourceData = 0x0;
  282. SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  283. au32DestinationData = SPI_READ_RX(SPI1);
  284. DataBuffer[Counter] = (u8) au32DestinationData;
  285.     }
  286.     SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  287. SpiFlash_WaitReady();
  288. }
  289. //以下是工程函數(shù)的案例
  290. #defineW25PAGE(n)( 4096 * n )
  291. //0 <= n < { 1024(塊)*64(頁)}
  292. //注意:擦除操作時是擦除整塊 SpiFlash_ChipErase(W25PAGE(n))
  293. //拿第一塊為例:n=0或n=63都是擦除第一塊64個頁的存儲區(qū)
  294. //參數(shù)寫0并保存
  295. void W25M_write_0(void)  
  296. {
  297. u16 i=0;
  298. for(i=0;i<2048;i++)
  299. {W25M_temp[i]=0;}
  300. SpiFlash_ChipErase(W25PAGE(0));SpiFlash_WriteData(W25M_temp, W25PAGE(0),2048);
  301. }
  302. //保存工程參數(shù)
  303. void W25M_write_GongChen(void)  
  304. {
  305. SpiFlash_ChipErase(W25PAGE(0));
  306. SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
  307. }
  308. //讀取工程參數(shù)
  309. void W25M_read_GongChen(void)
  310. {
  311. SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
  312. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:431491 發(fā)表于 2023-7-26 10:47 | 只看該作者
學習中,感謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表