m95512.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include "includes.h"
  2. #include "trace.h"
  3. #include "w25qxx.h"
  4. #include "m95512.h"
  5. //==============================================================================
  6. // 描述: 在AT25读状态寄存器
  7. // 输入: 无
  8. // 返回: unsigned char dat 状态寄存器数据
  9. //==============================================================================
  10. /**
  11. * @brief SPII/O配置
  12. * @param 无
  13. * @retval 无
  14. */
  15. static void SPI_E2PROM_GPIO_Config(void)
  16. {
  17. GPIO_InitTypeDef GPIO_InitStructure;
  18. //初始化CS引脚,使用软件控制,所以直接设置成推挽输出
  19. GPIO_InitStructure.GPIO_Pin = E2PROM_SPI_CS_PIN;
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  22. GPIO_Init(E2PROM_SPI_CS_PORT, &GPIO_InitStructure);
  23. E2PROM_SPI_CS_HIGH;
  24. }
  25. u8 eeprom_read_sr(void)
  26. {
  27. u8 dat;
  28. E2PROM_SPI_CS_LOW;
  29. SPI_USER_Send_Byte(RDSR); // 定入指令0x05
  30. dat = SPI_USER_Send_Byte(0xff); // 读回数据
  31. E2PROM_SPI_CS_HIGH;
  32. //printf("rdsr = 0x%x\r\n", dat);
  33. return dat;
  34. }
  35. //==============================================================================
  36. // 描述: 向AT25写入一个数据
  37. // 输入: unsigned char Dat 字符数据
  38. // unsigned int addr 写入的地址
  39. // 返回: 无
  40. //==============================================================================
  41. void eeprom_write_byte(u16 addr,u8 Dat)
  42. {
  43. unsigned char Add;
  44. while(eeprom_read_sr()&RDY); // 读状态寄存器
  45. E2PROM_SPI_CS_LOW;
  46. SPI_USER_Send_Byte(WREN); // 写使能锁存
  47. E2PROM_SPI_CS_HIGH;
  48. E2PROM_SPI_CS_LOW; // 芯片使能
  49. // 写入写操作指令
  50. if(addr>0x00ff)
  51. SPI_USER_Send_Byte((WRITE|0x08)); // 地址大于255
  52. else
  53. SPI_USER_Send_Byte(WRITE); // 地址小于255
  54. // 写入地址
  55. Add = (unsigned char)(addr & 0xff); // 将地址换成8位
  56. SPI_USER_Send_Byte(Add);
  57. // 写入数据
  58. SPI_USER_Send_Byte(Dat);
  59. E2PROM_SPI_CS_HIGH; // 芯片关闭
  60. }
  61. //==============================================================================
  62. // 描述: 在AT25读一个字节操作
  63. // 输入: 无
  64. // 返回: unsigned char dat 读出一个字符数据
  65. //==============================================================================
  66. u8 eeprom_read_byte(u16 addr)
  67. {
  68. u8 dat,add;
  69. while(eeprom_read_sr()&RDY); // 读状态寄存器
  70. E2PROM_SPI_CS_LOW;
  71. // 写入写操作指令
  72. if(addr>0x00ff)
  73. SPI_USER_Send_Byte((READ | 0x08)); // 地址大于255
  74. else
  75. SPI_USER_Send_Byte(READ); // 地址小于255
  76. // 写入地址
  77. add = (unsigned char)(addr & 0xff); // 将地址换成8位
  78. SPI_USER_Send_Byte(add);
  79. // 读出一个数据
  80. dat=SPI_USER_Send_Byte(0xff);
  81. E2PROM_SPI_CS_HIGH;
  82. return dat;
  83. }
  84. //==============================================================================
  85. // 描述: 向AT25连续写入数据
  86. // 输入: unsigned char *PC 写入数据指针
  87. // unsigned int count 写入数量计数
  88. // unsigned int SatAddr 写入起始地址
  89. // 返回: 无
  90. //==============================================================================
  91. void eeprom_write_buf(u16 startAddr,u8 *buf,u16 count)
  92. {
  93. u8 Add;
  94. u16 i;
  95. while(eeprom_read_sr()&RDY); // 读状态寄存器
  96. E2PROM_SPI_CS_LOW;
  97. SPI_USER_Send_Byte(WREN); // 写使能锁存
  98. E2PROM_SPI_CS_HIGH;
  99. E2PROM_SPI_CS_LOW;
  100. // 写入写操作指令
  101. if(startAddr>0x00ff)
  102. SPI_USER_Send_Byte((WRITE|0x08)); // 地址大于255
  103. else
  104. SPI_USER_Send_Byte(WRITE); // 地址小于255
  105. // 写入地址
  106. Add = (unsigned char)(startAddr & 0xff); // 将地址换成8位
  107. SPI_USER_Send_Byte(Add);
  108. for(i=0;i<count;i++)// 写入数据
  109. {
  110. SPI_USER_Send_Byte(*buf++);
  111. }
  112. E2PROM_SPI_CS_HIGH; // 芯片关闭
  113. }
  114. //==============================================================================
  115. // 描述: 在AT25连续读数据
  116. // 输入: unsigned char *PC 读出数据指针
  117. // unsigned int count 读出数量计数
  118. // unsigned int SatAddr 读出起始地址
  119. // 返回: 无
  120. //==============================================================================
  121. void eeprom_read_buf(u16 startAddr,u8 *buf,u16 count)
  122. {
  123. unsigned char Add;
  124. unsigned int i;
  125. while(eeprom_read_sr()&RDY); // 读状态寄存器
  126. E2PROM_SPI_CS_LOW;
  127. // 写入写操作指令
  128. if(startAddr>0x00ff)
  129. SPI_USER_Send_Byte((READ | 0x08)); // 地址大于255
  130. else
  131. SPI_USER_Send_Byte(READ); // 地址小于255
  132. // 写入地址
  133. Add = (unsigned char)(startAddr & 0xff); // 将地址换成8位
  134. SPI_USER_Send_Byte(Add);
  135. // 读出n个数据
  136. for(i=0;i<count;i++)
  137. {
  138. *buf++ = SPI_USER_Send_Byte(0xff);
  139. }
  140. E2PROM_SPI_CS_HIGH;
  141. }
  142. //读取FLASH的内容
  143. void SPI_E2PROM_Read_Data(uint32_t addr,uint8_t *readBuff,uint32_t numByteToRead)
  144. {
  145. //片选使能
  146. E2PROM_SPI_CS_LOW;
  147. SPI_USER_Send_Byte(READ);
  148. SPI_USER_Send_Byte((addr>>8)&0xff);
  149. SPI_USER_Send_Byte(addr&0xff);
  150. while(numByteToRead--)
  151. {
  152. *readBuff = SPI_USER_Send_Byte(DUMMY);
  153. readBuff++;
  154. }
  155. E2PROM_SPI_CS_HIGH;
  156. }
  157. //FLASH写入使能
  158. void SPI_E2PROM_Write_Enable(void)
  159. {
  160. //片选使能
  161. E2PROM_SPI_CS_LOW;
  162. SPI_USER_Send_Byte(WREN);
  163. E2PROM_SPI_CS_HIGH;
  164. //eeprom_read_sr();
  165. //while((eeprom_read_sr()&RDY) == RDY); // 读状态寄存器
  166. }
  167. //FLASH写入使能
  168. void SPI_E2PROM_Write_Disable(void)
  169. {
  170. //片选使能
  171. E2PROM_SPI_CS_LOW;
  172. SPI_USER_Send_Byte(WRDIS);
  173. E2PROM_SPI_CS_HIGH;
  174. //eeprom_read_sr();
  175. //while((eeprom_read_sr()&RDY) == RDY); // 读状态寄存器
  176. }
  177. //向FLASH写入内容
  178. void SPI_E2PROM_Write_Data(uint32_t addr,uint8_t *writeBuff,uint32_t numByteToWrite)
  179. {
  180. SPI_E2PROM_Write_Enable();
  181. //eeprom_read_sr();
  182. //片选使能
  183. E2PROM_SPI_CS_LOW;
  184. SPI_USER_Send_Byte(WRITE);
  185. SPI_USER_Send_Byte((addr>>8)&0xff);
  186. SPI_USER_Send_Byte(addr&0xff);
  187. while(numByteToWrite--)
  188. {
  189. SPI_USER_Send_Byte(*writeBuff);
  190. writeBuff++;
  191. }
  192. E2PROM_SPI_CS_HIGH;
  193. SPI_E2PROM_Write_Disable();
  194. }
  195. static u8 Spi_E2_Buf_Write[256], Spi_E2_Buf_Read[256];
  196. uint8_t SPI_E2PROM_Test(void)
  197. {
  198. u16 i;
  199. SPI_USER_Init();
  200. SPI_E2PROM_GPIO_Config();
  201. //id = SPI_FLASH_Read_ID();
  202. if(1) {
  203. memset(Spi_E2_Buf_Write, 0, 256);
  204. for ( i=0; i<=255; i++ ) {//填充缓冲
  205. Spi_E2_Buf_Write[i] = i+20;
  206. }
  207. data_dump("E2PROM Write", Spi_E2_Buf_Write, sizeof(Spi_E2_Buf_Write));
  208. //字节写入方式
  209. SPI_E2PROM_Write_Data(0, Spi_E2_Buf_Write, 128);
  210. delay_ms(1000);
  211. //将 EEPROM 读出数据顺序保持到 I2c_Buf_Read 中
  212. memset(Spi_E2_Buf_Read, 0, 256);
  213. SPI_E2PROM_Read_Data(0, Spi_E2_Buf_Read, 128);
  214. //将 I2c_Buf_Read 中的数据通过串口打印
  215. data_dump("E2PROM Read", Spi_E2_Buf_Read, sizeof(Spi_E2_Buf_Read));
  216. printf("\r\nSPI(m95512)rw success\r\n");
  217. delay_ms(1000);
  218. }
  219. return 1;
  220. }