nrf51822操作MX25L4005

指令集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define SPI_Flash_Read_CMD 0x03
#define SPI_Flash_Sector_Erase 0x20
#define SPI_Flash_Block_Erase 0xD8
#define SPI_Flash_Chip_Erase 0x60
#define SPI_Flash_Page_Program 0x02
#define SPI_Flash_Read_Status 0x05
#define SPI_Flash_Write_Status 0x01
#define SPI_Flash_Write_Enable 0x06
#define SPI_Flash_Write_Disable 0x04
#define SPI_Flash_Read_ID 0x9F
#define SPI_Flash_Read 0x03
#define SPI_Flash_Fast_Read 0x0B
#define SPI_Flash_Power_Down 0xB9
#define SPI_Flash_Release_DP 0xAB
#define SPI_Flash_Enter_4K 0xA5
#define SPI_Flash_Exit_4K 0xB5
#define SPI_Flash_Read_ES 0xAB
#define SPI_Flash_Read_EMS 0x90
#define SPI_Flash_Parallel_Mode 0x55

内存结构:

DATASTRUCT

CODE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include "M25L.h"
#include <nrf51.h>
#include "../Broad_Pin_config.h"
#include "spi_master_config.h"
#include "nrf_gpio.h"
#define FLASH_ENABLE nrf_gpio_pin_clear(SPI_PSELSS1)
#define FLASH_DISABLE nrf_gpio_pin_set(SPI_PSELSS1)
#define SPI_BUFSIZE 8
uint8_t M25MasterBuffer[SPI_BUFSIZE];
uint8_t M25SlaveBuffer[SPI_BUFSIZE];
uint8_t M25ReadLength, M25WriteLength;
#define SET 0x01
#define RESET 0x00
uint8_t Flash_Init(void)
{
uint32_t *spi_base_address = spi_master_init(SPI1, SPI_MODE0, false);
if (spi_base_address == 0) {
return false;
}
return true;
}
u8 SPI1_WriteRead_Data(u8 dat)
{
uint32_t counter = 0;
NRF_SPI_Type *spi_base = (NRF_SPI_Type *)NRF_SPI1;
spi_base->TXD = (uint32_t)(dat);
while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
{
counter++;
}
if (counter == TIMEOUT_COUNTER)
{
FLASH_DISABLE;
return false;
}
else { /* clear the event to be ready to receive next messages */
spi_base->EVENTS_READY = 0U;
}
return (uint8_t)spi_base->RXD;
}
FLASH_ID Flash_Read_ID(void)
{
FLASH_ID Flash_id;
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Read_ID);
Flash_id.MXIC_ID = SPI1_WriteRead_Data(DummyData);
Flash_id.MemType_ID = SPI1_WriteRead_Data(DummyData);
Flash_id.MemDensity_ID = SPI1_WriteRead_Data(DummyData);
FLASH_DISABLE;
return Flash_id;
}
void Flash_Write_Enable(void)
{
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Write_Enable);
FLASH_DISABLE;
}
void Flash_Write_Disable(void)
{
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Write_Disable);
FLASH_DISABLE;
}
u8 Flash_Read_Status_Register(void)
{
u8 data;
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Read_Status);
data = SPI1_WriteRead_Data(DummyData);
FLASH_DISABLE;
return data;
}
void Flash_Write_Status_Register(u8 dat)
{
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Write_Status);
SPI1_WriteRead_Data(dat);
FLASH_DISABLE;
}
void Flash_Sector_Erase(u16 Sector_idx)
{
u8 Sector_Addr_H;
u8 Sector_Addr_M;
u8 Sector_Addr_L;
Sector_Addr_H = (u8)(((Sector_idx * 0x1000) & 0x00ff0000) >> 16);
Sector_Addr_M = (u8)(((Sector_idx * 0x1000) & 0x0000ff00) >> 8);
Sector_Addr_L = 0x00;
Flash_Write_Enable();
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Sector_Erase);
SPI1_WriteRead_Data(Sector_Addr_H);
SPI1_WriteRead_Data(Sector_Addr_M);
SPI1_WriteRead_Data(Sector_Addr_L);
FLASH_DISABLE;
while (Flash_Read_Status_Register()&C_Flash_Busy != RESET);
}
void Flash_Block_Erase(u16 Block_idx)
{
u8 Block_Addr_H;
u8 Block_Addr_M;
u8 Block_Addr_L;
Block_Addr_H = (u8)(((Block_idx * 0x10000) & 0x00ff0000) >> 16);
Block_Addr_M = 0x00;
Block_Addr_L = 0x00;
Flash_Write_Enable();
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Block_Erase);
SPI1_WriteRead_Data(Block_Addr_H);
SPI1_WriteRead_Data(Block_Addr_M);
SPI1_WriteRead_Data(Block_Addr_L);
FLASH_DISABLE;
while (Flash_Read_Status_Register()&C_Flash_Busy != RESET);
}
void Flash_Chip_Erase(void)
{
Flash_Write_Enable();
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Chip_Erase);
FLASH_DISABLE;
while (Flash_Read_Status_Register()&C_Flash_Busy != RESET);
}
void Flash_WriteByte(uint32_t data_addr, u8 data)
{
u8 Data_Addr_H;
u8 Data_Addr_M;
u8 Data_Addr_L;
Data_Addr_H = (u8)(((data_addr * 0x10000) & 0x00ff0000) >> 16);
Data_Addr_M = (u8)(((data_addr * 0x10000) & 0x0000ff00) >> 8);
Data_Addr_L = (u8)((data_addr * 0x10000) & 0x000000ff);
Flash_Write_Enable();
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Page_Program);
SPI1_WriteRead_Data(Data_Addr_H);
SPI1_WriteRead_Data(Data_Addr_M);
SPI1_WriteRead_Data(Data_Addr_L);
SPI1_WriteRead_Data(data);
FLASH_DISABLE;
while (Flash_Read_Status_Register()&C_Flash_Busy != RESET);
}
void Flash_WriteBytes(uint32_t data_addr, u8* ptdata, u16 count)
{
u8 Data_Addr_H;
u8 Data_Addr_M;
u8 Data_Addr_L;
Data_Addr_H = (u8)(((data_addr * 0x10000) & 0x00ff0000) >> 16);
Data_Addr_M = (u8)(((data_addr * 0x10000) & 0x0000ff00) >> 8);
Data_Addr_L = (u8)((data_addr * 0x10000) & 0x000000ff);
Flash_Write_Enable();
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Page_Program);
SPI1_WriteRead_Data(Data_Addr_H);
SPI1_WriteRead_Data(Data_Addr_M);
SPI1_WriteRead_Data(Data_Addr_L);
for (; count != 0; count--)
{
SPI1_WriteRead_Data(*(ptdata++));
}
FLASH_DISABLE;
while (Flash_Read_Status_Register()&C_Flash_Busy != RESET);
}
void Flash_ReadBytes(uint32_t data_addr, u8* ptdata, u16 count)
{
u8 Data_Addr_H;
u8 Data_Addr_M;
u8 Data_Addr_L;
Data_Addr_H = (u8)(((data_addr * 0x10000) & 0x00ff0000) >> 16);
Data_Addr_M = (u8)(((data_addr * 0x10000) & 0x0000ff00) >> 8);
Data_Addr_L = (u8)((data_addr * 0x10000) & 0x000000ff);
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Fast_Read);
SPI1_WriteRead_Data(Data_Addr_H);
SPI1_WriteRead_Data(Data_Addr_M);
SPI1_WriteRead_Data(Data_Addr_L);
SPI1_WriteRead_Data(DummyData);
for (; count != 0; count--)
{
*(ptdata++) = SPI1_WriteRead_Data(DummyData);
}
FLASH_DISABLE;
}
u8 Flash_ReadByte(uint32_t data_addr)
{
u8 data;
u8 Data_Addr_H;
u8 Data_Addr_M;
u8 Data_Addr_L;
Data_Addr_H = (u8)(((data_addr * 0x10000) & 0x00ff0000) >> 16);
Data_Addr_M = (u8)(((data_addr * 0x10000) & 0x0000ff00) >> 8);
Data_Addr_L = (u8)((data_addr * 0x10000) & 0x000000ff);
FLASH_ENABLE;
SPI1_WriteRead_Data(SPI_Flash_Read);
SPI1_WriteRead_Data(Data_Addr_H);
SPI1_WriteRead_Data(Data_Addr_M);
SPI1_WriteRead_Data(Data_Addr_L);
data = SPI1_WriteRead_Data(DummyData);
FLASH_DISABLE;
return data;
}

使用注意事项:

首先,写数据之前必须要擦除,因为所有的flash只能从1变为0,擦除将flash全部置1,写的时候相应位置0。
在对flash进行写操作时,要理解一点:对flash写数据(也就是Page Program(PP),Command 02)是基于页(256bytes)为单位的,如果数据写到页的末尾,会从当前页的首地址继续开始写剩余的数据,这样就有可能造成成数据的丢失。
也就是说:

  • 如果从0开始写, 数据量大于256,写完256个数据之后, 会从当前页的0位开始写后面的数据。
  • 如果不是从0开始写,数量量超当前页的时候, 也会从当前页的0位开始覆盖数据。

感谢

heshanxingzhe
jayjiang86

留言