找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2641|回复: 1
打印 上一主题 下一主题
收起左侧

C语言源代码W25M02驱动使用

[复制链接]
跳转到指定楼层
楼主
ID:155701 发表于 2021-6-9 11:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本案例使用的是新唐M451的SPI1驱动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内的两片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缓存数据
  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:数据
  60.     SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
  61. SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
  62. }
  63. //写状态寄存器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:数据
  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数据
  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. //擦除一块数据  64页 :64*2048=128k 字节
  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. //擦除功能函数
  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. //写入数据功能函数
  184. //StartAddress1 12~27位: 页地址
  185. //StartAddress1 0~11位:页内数据位置
  186. //ByteCount字节个数
  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;//数据写入IC缓冲区指令 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);//页内位置
  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++)//数据写入IC换冲执行过程
  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;//换冲导入存储区指令 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. //一页数据导出到IC缓冲区
  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;//页数据读取到缓存指令 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. //读出数据功能函数
  248. //StartAddress1 12~27位: 页地址
  249. //StartAddress1 0~11位:页内数据位置
  250. //ByteCount字节个数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缓冲区数据指令 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);//页内位置
  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缓冲区 准备接收IC缓冲区数据
  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. //以下是工程函数的案例
  290. #defineW25PAGE(n)( 4096 * n )
  291. //0 <= n < { 1024(块)*64(页)}
  292. //注意:擦除操作时是擦除整块 SpiFlash_ChipErase(W25PAGE(n))
  293. //拿第一块为例:n=0或n=63都是擦除第一块64个页的存储区
  294. //参数写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. //保存工程参数
  303. void W25M_write_GongChen(void)  
  304. {
  305. SpiFlash_ChipErase(W25PAGE(0));
  306. SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
  307. }
  308. //读取工程参数
  309. void W25M_read_GongChen(void)
  310. {
  311. SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
  312. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:431491 发表于 2023-7-26 10:47 | 只看该作者
学习中,感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表