├── README.md ├── W25Q64 ├── W25Q64.cpp ├── W25Q64.h └── examples │ ├── sample │ └── sample.ino │ └── sample_STM32 │ └── sample_STM32.ino └── img ├── Schematic1.png ├── Schematic2.png ├── Schematic3.jpg ├── Schematic4.png ├── W25Q64.jpg ├── demo.jpg └── sample_console_2.jpg /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-W25Q64 2 | 3 | Arduino用 SPI接続フラッシュメモリW25Q64ライブラリ 4 | 5 | ![結線図](img/demo.jpg) 6 | 7 | ## 概要 8 | 9 | Arduinoでwinbond社製 SPI接続フラッシュメモリ**W25Q64**を利用するためのライブラリです。 10 | **W25Q32**でも利用出来ます。 11 | 12 | ![W25Q64 DIP](img/W25Q64.jpg) 13 | 14 | 15 | ライブラリ名称: **W25Q64** 16 | ヘッダファイル: `#include ` 17 | 18 | ## インストール 19 | 20 | **W25Q64**フォルダを**Arduino IDE**の**libraries**フォルダに置いて下さい。 21 | 22 | ## 回路図 23 | 24 | **W25Q64**は3.3V稼働のため、5V稼働のArduinoで利用する場合はレベルシフト等の対応を行って下さい。 25 | (電源部のパスコンは省略しても動くようです) 26 | 27 | ![回路図](img/Schematic1.png) 28 | ![接続図](img/Schematic2.png) 29 | 30 | 3.3V稼働可能なArduinoは直接接続で利用します。 31 | ![接続図2](img/Schematic3.jpg) 32 | 33 | Arduino STM32 Blue Pillボードでの利用例 34 | 利用するポートは、関数`void W25Q64_setSPIPort(SPIClass& rSPI);`で指定出来ます。 35 | ![接続図2](img/Schematic4.png) 36 | 37 | ## サンプルプログラム 38 | 39 | スケッチ名:**sample.ino** (Arduino Uno用) 40 | **W25Q64**に対して、書き込みと読み込みを行いその結果を表示します。 41 | 42 | シリアル通信の速度は115200で接続します。 43 | ![接続図](img/sample_console_2.jpg) 44 | 45 | スケッチ名:**sample_STM32.ino** (Arduino STM32 BluePill用) 46 | sample.inoと同じ機能です。 47 | スケッチ内の**E25Q64_SPI_PORT**の設定にて利用するSPIポートの変更が可能です。 48 | -------------------------------------------------------------------------------- /W25Q64/W25Q64.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // フラッシュメモリW25Q64 からのフォントデータ取得 3 | // 作成 2014/10/14 4 | // 修正 2016/05/21 5 | // 修正 2017/11/18,Arduin STM32対応 6 | // 修正 2018/07/14,Arduin STM32対応用W25Q64_seSPIPort()の追加 7 | // 修正 2018/07/14,W25Q64_begin()の第2引数にSPIのCLK周波数を指定可能にした 8 | // 修正 2018/07/27,W25Q64_seSPIPortをW25Q64_setSPIPortに訂正 9 | // 修正 2019/06/23,W25Q64_pageWrite()の書き込みバイト数の型をbyteからuint16_tに変更 10 | // 修正 2020/05/212,W25Q64_readUniqieID()の読み取りバイト数不具合修正(7=>8バイト) 11 | // 12 | 13 | #include 14 | 15 | #define SPI_SLAVE_SEL_PIN 10 // チップセレクトピン番号 16 | #define MAX_BLOCKSIZE 128 // ブロック総数 17 | #define MAX_SECTORSIZE 2048 // 総セクタ数 18 | 19 | #define CMD_WRIRE_ENABLE 0x06 20 | #define CMD_WRITE_DISABLE 0x04 21 | #define CMD_READ_STATUS_R1 0x05 22 | #define CMD_READ_STATUS_R2 0x35 23 | #define CMD_WRITE_STATUS_R 0x01 // 未実装 24 | #define CMD_PAGE_PROGRAM 0x02 25 | #define CMD_QUAD_PAGE_PROGRAM 0x32 // 未実装 26 | #define CMD_BLOCK_ERASE64KB 0xd8 27 | #define CMD_BLOCK_ERASE32KB 0x52 28 | #define CMD_SECTOR_ERASE 0x20 29 | #define CMD_CHIP_ERASE 0xC7 30 | #define CMD_ERASE_SUPPEND 0x75 // 未実装 31 | #define CMD_ERASE_RESUME 0x7A // 未実装 32 | #define CMD_POWER_DOWN 0xB9 33 | #define CMD_HIGH_PERFORM_MODE 0xA3 // 未実装 34 | #define CMD_CNT_READ_MODE_RST 0xFF // 未実装 35 | #define CMD_RELEASE_PDOWN_ID 0xAB // 未実装 36 | #define CMD_MANUFACURER_ID 0x90 37 | #define CMD_READ_UNIQUE_ID 0x4B 38 | #define CMD_JEDEC_ID 0x9f 39 | 40 | #define CMD_READ_DATA 0x03 41 | #define CMD_FAST_READ 0x0B 42 | #define CMD_READ_DUAL_OUTPUT 0x3B // 未実装 43 | #define CMD_READ_DUAL_IO 0xBB // 未実装 44 | #define CMD_READ_QUAD_OUTPUT 0x6B // 未実装 45 | #define CMD_READ_QUAD_IO 0xEB // 未実装 46 | #define CMD_WORD_READ 0xE3 // 未実装 47 | 48 | #define SR1_BUSY_MASK 0x01 49 | #define SR1_WEN_MASK 0x02 50 | 51 | static uint8_t cspin ; 52 | static SPIClass* mpSPI = &SPI; 53 | static SPISettings mSPISettings; 54 | 55 | // SPIポートの設定 56 | void W25Q64_setSPIPort(SPIClass& rSPI) { 57 | mpSPI = &rSPI; 58 | } 59 | 60 | // 61 | // フラッシュメモリ W25Q64の利用開始 62 | // 63 | void W25Q64_begin(uint8_t cs, uint32_t frq) { 64 | cspin = cs; 65 | pinMode (cspin, OUTPUT); 66 | W25Q64_deselect(); 67 | mSPISettings = SPISettings(frq, MSBFIRST, SPI_MODE0); 68 | mpSPI->begin(); 69 | } 70 | 71 | // 72 | // フラッシュメモリ W25Q64の利用終了 73 | // 74 | void W25Q64_end() { 75 | W25Q64_powerDown(); 76 | W25Q64_deselect(); 77 | mpSPI->end(); 78 | } 79 | 80 | // 81 | // チップセレクト 82 | // フラッシュメモリ操作を選択にする 83 | // 84 | void W25Q64_select() { 85 | mpSPI->beginTransaction(mSPISettings); 86 | digitalWrite(cspin, LOW); 87 | } 88 | 89 | // 90 | // チップディセレクト 91 | // フラッシュメモリ操作を有非選択にする 92 | // 93 | void W25Q64_deselect() { 94 | digitalWrite(cspin, HIGH); 95 | mpSPI->endTransaction(); 96 | } 97 | 98 | // 99 | // ステータスレジスタ1の値取得 100 | // 戻り値: ステータスレジスタ1の値 101 | // 102 | byte W25Q64_readStatusReg1() { 103 | byte rc; 104 | W25Q64_select(); 105 | mpSPI->transfer(CMD_READ_STATUS_R1); 106 | rc = mpSPI->transfer(0xFF); 107 | W25Q64_deselect(); 108 | return rc; 109 | } 110 | 111 | // 112 | // ステータスレジスタ2の値取得 113 | // 戻り値: ステータスレジスタ2の値 114 | // 115 | byte W25Q64_readStatusReg2() { 116 | byte rc; 117 | W25Q64_select(); 118 | mpSPI->transfer(CMD_READ_STATUS_R2); 119 | rc = mpSPI->transfer(0xFF); 120 | W25Q64_deselect(); 121 | return rc; 122 | } 123 | 124 | // 125 | // JEDEC ID(Manufacture, Memory Type,Capacity)の取得 126 | // d(out) :Manufacture, Memory Type,Capacityの3バイトを格納する 127 | // 128 | void W25Q64_readManufacturer(byte* d) { 129 | W25Q64_select(); 130 | mpSPI->transfer(CMD_JEDEC_ID); 131 | for (byte i =0; i <3; i++) { 132 | d[i] = mpSPI->transfer(0x00); 133 | } 134 | W25Q64_deselect(); 135 | } 136 | 137 | // 138 | // Unique IDの取得 139 | // d(out): Unique ID 8バイトを返す 140 | // 141 | void W25Q64_readUniqieID(byte* d) { 142 | W25Q64_select(); 143 | mpSPI->transfer(CMD_READ_UNIQUE_ID); 144 | mpSPI->transfer(0x00); 145 | mpSPI->transfer(0x00); 146 | mpSPI->transfer(0x00); 147 | mpSPI->transfer(0x00); 148 | for (byte i =0; i <8; i++) { 149 | d[i] = mpSPI->transfer(0x00); 150 | } 151 | W25Q64_deselect(); 152 | } 153 | 154 | // 155 | // 書込み等の処理中チェック 156 | // 戻り値: true:作業 、false:アイドル中 157 | // 158 | boolean W25Q64_IsBusy() { 159 | uint8_t r1; 160 | W25Q64_select(); 161 | mpSPI->transfer(CMD_READ_STATUS_R1); 162 | r1 = mpSPI->transfer(0xff); 163 | W25Q64_deselect(); 164 | if(r1 & SR1_BUSY_MASK) 165 | return true; 166 | return false; 167 | } 168 | 169 | // 170 | // パワーダウン指定 171 | // 172 | void W25Q64_powerDown() { 173 | W25Q64_select(); 174 | mpSPI->transfer(CMD_POWER_DOWN); 175 | W25Q64_deselect(); 176 | } 177 | 178 | // 179 | // 書込み許可設定 180 | // 181 | void W25Q64_WriteEnable() { 182 | W25Q64_select(); 183 | mpSPI->transfer(CMD_WRIRE_ENABLE); 184 | W25Q64_deselect(); 185 | } 186 | 187 | // 188 | // 書込み禁止設定 189 | // 190 | void W25Q64_WriteDisable() { 191 | W25Q64_select(); 192 | mpSPI->transfer(CMD_WRITE_DISABLE); 193 | W25Q64_deselect(); 194 | } 195 | 196 | // 197 | // データの読み込み 198 | // addr(in): 読込開始アドレス (24ビット 0x00000 - 0xFFFFF) 199 | // n(in):読込データ数 200 | // 201 | uint16_t W25Q64_read(uint32_t addr,uint8_t *buf,uint16_t n){ 202 | W25Q64_select(); 203 | mpSPI->transfer(CMD_READ_DATA); 204 | mpSPI->transfer(addr>>16); // A23-A16 205 | mpSPI->transfer((addr>>8) & 0xFF); // A15-A08 206 | mpSPI->transfer(addr & 0xFF); // A07-A00 207 | 208 | uint16_t i; 209 | for(i = 0; itransfer(0x00); 211 | } 212 | 213 | W25Q64_deselect(); 214 | return i; 215 | } 216 | 217 | // 218 | // 高速データの読み込み 219 | // addr(in): 読込開始アドレス (24ビット 0x00000 - 0xFFFFF) 220 | // n(in):読込データ数 221 | // 222 | uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n) { 223 | W25Q64_select(); 224 | mpSPI->transfer(CMD_FAST_READ); 225 | mpSPI->transfer(addr>>16); // A23-A16 226 | mpSPI->transfer((addr>>8) & 0xFF); // A15-A08 227 | mpSPI->transfer(addr & 0xFF); // A07-A00 228 | mpSPI->transfer(0x00); // ダミー 229 | 230 | uint16_t i; 231 | for(i = 0; itransfer(0x00); 233 | 234 | W25Q64_deselect(); 235 | return i; 236 | } 237 | 238 | // 239 | // セクタ単位消去(4kb空間単位でデータの消去を行う) 240 | // sect_no(in) セクタ番号(0 - 2048) 241 | // flgwait(in) true:処理待ちを行う false:待ち無し 242 | // 戻り値: true:正常終了 false:失敗 243 | // 補足: データシートでは消去に通常 30ms 、最大400msかかると記載されている 244 | // アドレス23ビットのうち上位 11ビットがセクタ番号の相当する。下位12ビットはセクタ内アドレスとなる。 245 | // 246 | boolean W25Q64_eraseSector(uint16_t sect_no, boolean flgwait) { 247 | uint32_t addr = sect_no; 248 | addr<<=12; 249 | 250 | W25Q64_WriteEnable(); 251 | W25Q64_select(); 252 | mpSPI->transfer(CMD_SECTOR_ERASE); 253 | mpSPI->transfer((addr>>16) & 0xff); 254 | mpSPI->transfer((addr>>8) & 0xff); 255 | mpSPI->transfer(addr & 0xff); 256 | W25Q64_deselect(); 257 | 258 | // 処理待ち 259 | while(W25Q64_IsBusy() & flgwait) { 260 | delay(10); 261 | } 262 | 263 | return true; 264 | } 265 | 266 | // 267 | // 64KBブロック単位消去(64kb空間単位でデータの消去を行う) 268 | // blk_no(in) ブロック番号(0 - 127) 269 | // flgwait(in) true:処理待ちを行う false:待ち無し 270 | // 戻り値: true:正常終了 false:失敗 271 | // 補足: データシートでは消去に通常 150ms 、最大1000msかかると記載されている 272 | // アドレス23ビットのうち上位 7ビットがブロックの相当する。下位16ビットはブロック内アドレスとなる。 273 | // 274 | boolean W25Q64_erase64Block(uint16_t blk_no, boolean flgwait) { 275 | uint32_t addr = blk_no; 276 | addr<<=16; 277 | 278 | W25Q64_WriteEnable(); 279 | W25Q64_select(); 280 | mpSPI->transfer(CMD_BLOCK_ERASE64KB); 281 | mpSPI->transfer((addr>>16) & 0xff); 282 | mpSPI->transfer((addr>>8) & 0xff); 283 | mpSPI->transfer(addr & 0xff); 284 | W25Q64_deselect(); 285 | 286 | // 処理待ち 287 | while(W25Q64_IsBusy() & flgwait) { 288 | delay(50); 289 | } 290 | 291 | return true; 292 | } 293 | 294 | // 295 | // 32KBブロック単位消去(32kb空間単位でデータの消去を行う) 296 | // blk_no(in) ブロック番号(0 - 255) 297 | // flgwait(in) true:処理待ちを行う false:待ち無し 298 | // 戻り値: true:正常終了 false:失敗 299 | // 補足: データシートでは消去に通常 120ms 、最大800msかかると記載されている 300 | // アドレス23ビットのうち上位 8ビットがブロックの相当する。下位15ビットはブロック内アドレスとなる。 301 | // 302 | boolean W25Q64_erase32Block(uint16_t blk_no, boolean flgwait) { 303 | 304 | uint32_t addr = blk_no; 305 | addr<<=15; 306 | 307 | W25Q64_WriteEnable(); 308 | W25Q64_select(); 309 | mpSPI->transfer(CMD_BLOCK_ERASE32KB); 310 | mpSPI->transfer((addr>>16) & 0xff); 311 | mpSPI->transfer((addr>>8) & 0xff); 312 | mpSPI->transfer(addr & 0xff); 313 | W25Q64_deselect(); 314 | 315 | // 処理待ち 316 | while(W25Q64_IsBusy() & flgwait) { 317 | delay(50); 318 | } 319 | 320 | return true; 321 | } 322 | 323 | // 324 | // 全領域の消去 325 | // flgwait(in) true:処理待ちを行う false:待ち無し 326 | // 戻り値: true:正常終了 false:失敗 327 | // 補足: データシートでは消去に通常 15s 、最大30sかかると記載されている 328 | // 329 | boolean W25Q64_eraseAll(boolean flgwait) { 330 | W25Q64_WriteEnable(); 331 | W25Q64_select(); 332 | mpSPI->transfer(CMD_CHIP_ERASE); 333 | W25Q64_deselect(); 334 | 335 | // 処理待ち 336 | while(W25Q64_IsBusy() & flgwait) { 337 | delay(500); 338 | } 339 | 340 | W25Q64_deselect(); 341 | return true; 342 | } 343 | 344 | // 345 | // データの書き込み 346 | // sect_no(in) : セクタ番号(0x00 - 0x7FF) 347 | // inaddr(in) : セクタ内アドレス(0x00-0xFFF) 348 | // data(in) : 書込みデータ格納アドレス 349 | // n(in) : 書込みバイト数(0~256) 350 | // 351 | uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, byte* data, uint16_t n) { 352 | 353 | uint32_t addr = sect_no; 354 | uint16_t i; 355 | addr<<=12; 356 | addr += inaddr; 357 | 358 | W25Q64_WriteEnable(); 359 | 360 | if (W25Q64_IsBusy()) { 361 | return 0; 362 | } 363 | 364 | W25Q64_select(); 365 | mpSPI->transfer(CMD_PAGE_PROGRAM); 366 | mpSPI->transfer((addr>>16) & 0xff); 367 | mpSPI->transfer((addr>>8) & 0xff); 368 | mpSPI->transfer(addr & 0xff); 369 | 370 | for (i=0; i < n; i++) { 371 | mpSPI->transfer(data[i]); 372 | } 373 | W25Q64_deselect(); 374 | while(W25Q64_IsBusy()) ; 375 | 376 | return i; 377 | } 378 | -------------------------------------------------------------------------------- /W25Q64/W25Q64.h: -------------------------------------------------------------------------------- 1 | // 2 | // フラッシュメモリW25Q64 からのフォントデータ取得 3 | // 作成 2014/10/14 4 | // 修正 2016/05/21 5 | // 修正 2017/11/18,Arduin STM32対応 6 | // 修正 2018/07/14,Arduin STM32対応用W25Q64_seSPIPort()の追加 7 | // 修正 2018/07/14,W25Q64_begin()の第2引数にSPIのCLK周波数を指定可能にした 8 | // 修正 2018/07/14,ヘッダファイルの多重割り込み対応 9 | // 修正 2018/07/27,"arduino.h"を"Arduino.h"に訂正、W25Q64_seSPIPortをW25Q64_setSPIPortに訂正 10 | // 修正 2019/06/23,W25Q64_pageWrite()の書き込みバイト数の型をbyteからuint16_tに変更 11 | // 12 | 13 | #ifndef ___W25Q64_h___ 14 | #define ___W25Q64_h___ 15 | 16 | #include 17 | #include 18 | 19 | void W25Q64_setSPIPort(SPIClass& rSPI); // SPIポートの設定 20 | 21 | void W25Q64_begin(uint8_t cs,uint32_t frq=8000000); // フラッシュメモリ W25Q64の利用開始 22 | void W25Q64_end(); // フラッシュメモリ W25Q64の利用終了 23 | void W25Q64_select(); // チップセレクト フラッシュメモリ操作を選択にする 24 | void W25Q64_deselect(); // チップディセレクト フラッシュメモリ操作を有非選択にする 25 | byte W25Q64_readStatusReg1(); // ステータスレジスタ1の値取得 26 | byte W25Q64_readStatusReg2(); // ステータスレジスタ2の値取得 27 | void W25Q64_readManufacturer(byte* d); // JEDEC ID(Manufacture, Memory Type,Capacity)の取得 28 | void W25Q64_readUniqieID(byte* d); // Unique IDの取得 29 | boolean W25Q64_IsBusy(); // 書込み等の処理中チェック 30 | void W25Q64_powerDown(); // パワーダウン指定 31 | void W25Q64_WriteEnable(); // 書込み許可設定 32 | void W25Q64_WriteDisable(); // 書込み禁止設定 33 | 34 | uint16_t W25Q64_read(uint32_t addr,uint8_t *buf,uint16_t n); // データの読み込み 35 | uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n); // 高速データの読み込み 36 | boolean W25Q64_eraseSector(uint16_t sect_no, boolean flgwait); // セクタ単位消去 37 | boolean W25Q64_erase64Block(uint16_t blk_no, boolean flgwait); // 64KBブロック単位消去 38 | boolean W25Q64_erase32Block(uint16_t blk_no, boolean flgwait); // 32KBブロック単位消去 39 | boolean W25Q64_eraseAll(boolean flgwait); // 全領域の消去 40 | uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, byte* data, uint16_t n); // データの書き込み 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /W25Q64/examples/sample/sample.ino: -------------------------------------------------------------------------------- 1 | // 2 | // SPI シリアルフラッシュメモリ W25Q64 操作検証プログラム 3 | // W25Q64のメモリ領域構造 4 | // 総バイト数 8388608 5 | // メモリ空間 24ビットアドレス指定 0x00000 - 0x7FFFFF 6 | // ブロック数 128 (64KB/ブロック) 7 | // セクタ数 2048 ( 4KB/セクタ) 8 | // 総セクタ数 2048 9 | // 10 | // 修正 2020/05/12, Unique ID取得の修正 11 | // 12 | 13 | #include 14 | #include 15 | 16 | // 17 | // 書込みデータのダンプリスト 18 | // dt(in) : データ格納先頭アドレス 19 | // n(in) : 表示データ数 20 | // 21 | void dump(byte *dt, uint32_t n) { 22 | char buf[64]; 23 | uint16_t clm = 0; 24 | byte data; 25 | byte sum; 26 | byte vsum[16]; 27 | byte total =0; 28 | uint32_t saddr =0; 29 | uint32_t eaddr =n-1; 30 | 31 | Serial.println("----------------------------------------------------------"); 32 | for (uint16_t i=0;i<16;i++) vsum[i]=0; 33 | for (uint32_t addr = saddr; addr <= eaddr; addr++) { 34 | data = dt[addr]; 35 | if (clm == 0) { 36 | sum =0; 37 | sprintf(buf,"%05lx: ",addr); 38 | Serial.print(buf); 39 | } 40 | 41 | sum+=data; 42 | vsum[addr % 16]+=data; 43 | 44 | sprintf(buf,"%02x ",data); 45 | Serial.print(buf); 46 | clm++; 47 | if (clm == 16) { 48 | sprintf(buf,"|%02x ",sum); 49 | Serial.print(buf); 50 | Serial.println(""); 51 | clm = 0; 52 | } 53 | } 54 | Serial.println("----------------------------------------------------------"); 55 | Serial.print(" "); 56 | for (uint16_t i=0; i<16;i++) { 57 | total+=vsum[i]; 58 | sprintf(buf,"%02x ",vsum[i]); 59 | Serial.print(buf); 60 | } 61 | sprintf(buf,"|%02x ",total); 62 | Serial.print(buf); 63 | Serial.println(""); 64 | Serial.println(""); 65 | } 66 | 67 | void setup() { 68 | byte buf[256]; // 取得データ 69 | byte wdata[16]; // 書込みデータ 70 | 71 | uint16_t n; // 取得データ数 72 | 73 | W25Q64_begin(10); // フラッシュメモリ利用開始 74 | Serial.begin(115200); 75 | 76 | // JEDEC IDの取得テスト 77 | W25Q64_readManufacturer(buf); 78 | Serial.print("JEDEC ID : "); 79 | for (byte i=0; i< 3; i++) { 80 | Serial.print(buf[i],HEX); 81 | Serial.print(" "); 82 | } 83 | Serial.println(""); 84 | 85 | // Unique IDの取得テスト 86 | memset(buf,0,8); 87 | W25Q64_readUniqieID(buf); 88 | Serial.print("Unique ID : "); 89 | for (byte i=0; i< 8; i++) { 90 | Serial.print(buf[i],HEX); 91 | Serial.print(" "); 92 | } 93 | Serial.println(""); 94 | 95 | // データの読み込み(アドレス0から256バイト取得) 96 | memset(buf,0,256); 97 | n = W25Q64_read(0,buf, 256); 98 | Serial.print("Read Data: n="); 99 | Serial.println(n,DEC); 100 | dump(buf,256); 101 | 102 | // 高速データの読み込み(アドレス0から256バイト取得) 103 | memset(buf,0,256); 104 | n = W25Q64_fastread(0,buf, 256); 105 | Serial.print("Fast Read Data: n="); 106 | Serial.println(n,DEC); 107 | dump(buf,256); 108 | 109 | // セクタ単位の削除 110 | n = W25Q64_eraseSector(0,true); 111 | Serial.print("Erase Sector(0): n="); 112 | Serial.println(n,DEC); 113 | memset(buf,0,256); 114 | n = W25Q64_read (0,buf, 256); 115 | dump(buf,256); 116 | 117 | // データ書き込みテスト 118 | for (byte i=0; i < 16;i++) { 119 | wdata[i]='A'+i; 120 | } 121 | n = W25Q64_pageWrite(0, 10, wdata, 16); 122 | Serial.print("page_write(0,10,d,16): n="); 123 | Serial.println(n,DEC); 124 | memset(buf,0,256); 125 | n = W25Q64_read (0,buf, 256); 126 | dump(buf,256); 127 | 128 | // ステータスレジスタ1の取得 129 | buf[0] = W25Q64_readStatusReg1(); 130 | Serial.print("Status Register-1: "); 131 | Serial.print(buf[0],BIN); 132 | Serial.println(""); 133 | 134 | // ステータスレジスタ2の取得 135 | buf[0] = W25Q64_readStatusReg2(); 136 | Serial.print("Status Register-2: "); 137 | Serial.print(buf[0],BIN); 138 | Serial.println(""); 139 | } 140 | 141 | void loop() { 142 | 143 | } 144 | -------------------------------------------------------------------------------- /W25Q64/examples/sample_STM32/sample_STM32.ino: -------------------------------------------------------------------------------- 1 | // 2 | // SPI シリアルフラッシュメモリ W25Q64 操作検証プログラム 3 | // W25Q64のメモリ領域構造 4 | // 総バイト数 8388608 5 | // メモリ空間 24ビットアドレス指定 0x00000 - 0x7FFFFF 6 | // ブロック数 128 (64KB/ブロック) 7 | // セクタ数 2048 ( 4KB/セクタ) 8 | // 総セクタ数 2048 9 | // 10 | // 修正 2020/05/12, Unique ID取得の修正 11 | // 12 | 13 | #include 14 | #include 15 | 16 | // 利用するSPIポートの指定 17 | #define E25Q64_SPI_PORT 1 // 1:SPI1, 2:SPI2, 3:SPI3 18 | 19 | // CSピンの指定 20 | #define E25Q64_CS PB0 21 | 22 | // SPI1でない場合、SPIオブジェクトを用意する 23 | #if E25Q64_SPI_PORT != 1 24 | SPIClass MySPI(E25Q64_SPI_PORT); 25 | #endif 26 | 27 | // 28 | // 書込みデータのダンプリスト 29 | // dt(in) : データ格納先頭アドレス 30 | // n(in) : 表示データ数 31 | // 32 | void dump(byte *dt, uint32_t n) { 33 | char buf[64]; 34 | uint16_t clm = 0; 35 | byte data; 36 | byte sum; 37 | byte vsum[16]; 38 | byte total =0; 39 | uint32_t saddr =0; 40 | uint32_t eaddr =n-1; 41 | 42 | Serial.println("----------------------------------------------------------"); 43 | for (uint16_t i=0;i<16;i++) vsum[i]=0; 44 | for (uint32_t addr = saddr; addr <= eaddr; addr++) { 45 | data = dt[addr]; 46 | if (clm == 0) { 47 | sum =0; 48 | sprintf(buf,"%05lx: ",addr); 49 | Serial.print(buf); 50 | } 51 | 52 | sum+=data; 53 | vsum[addr % 16]+=data; 54 | 55 | sprintf(buf,"%02x ",data); 56 | Serial.print(buf); 57 | clm++; 58 | if (clm == 16) { 59 | sprintf(buf,"|%02x ",sum); 60 | Serial.print(buf); 61 | Serial.println(""); 62 | clm = 0; 63 | } 64 | } 65 | Serial.println("----------------------------------------------------------"); 66 | Serial.print(" "); 67 | for (uint16_t i=0; i<16;i++) { 68 | total+=vsum[i]; 69 | sprintf(buf,"%02x ",vsum[i]); 70 | Serial.print(buf); 71 | } 72 | sprintf(buf,"|%02x ",total); 73 | Serial.print(buf); 74 | Serial.println(""); 75 | Serial.println(""); 76 | } 77 | 78 | void setup() { 79 | byte buf[256]; // 取得データ 80 | byte wdata[16]; // 書込みデータ 81 | uint16_t n; // 取得データ数 82 | Serial.begin(115200); 83 | delay(1000); 84 | 85 | #if E25Q64_SPI_PORT !=1 86 | W25Q64_setSPIPort(MySPI); 87 | W25Q64_begin(E25Q64_CS,18000000); // フラッシュメモリ利用開始 88 | #else 89 | W25Q64_begin(E25Q64_CS,32000000); // フラッシュメモリ利用開始 90 | #endif 91 | // JEDEC IDの取得テスト 92 | W25Q64_readManufacturer(buf); 93 | Serial.print("JEDEC ID : "); 94 | for (byte i=0; i< 3; i++) { 95 | Serial.print(buf[i],HEX); 96 | Serial.print(" "); 97 | } 98 | Serial.println(""); 99 | 100 | // Unique IDの取得テスト 101 | memset(buf,0,8); 102 | W25Q64_readUniqieID(buf); 103 | Serial.print("Unique ID : "); 104 | for (byte i=0; i< 8; i++) { 105 | Serial.print(buf[i],HEX); 106 | Serial.print(" "); 107 | } 108 | Serial.println(""); 109 | 110 | // データの読み込み(アドレス0から256バイト取得) 111 | memset(buf,0,256); 112 | n = W25Q64_read(0,buf, 256); 113 | Serial.print("Read Data: n="); 114 | Serial.println(n,DEC); 115 | dump(buf,256); 116 | 117 | // 高速データの読み込み(アドレス0から256バイト取得) 118 | memset(buf,0,256); 119 | n = W25Q64_fastread(0,buf, 256); 120 | Serial.print("Fast Read Data: n="); 121 | Serial.println(n,DEC); 122 | dump(buf,256); 123 | 124 | // セクタ単位の削除 125 | n = W25Q64_eraseSector(0,true); 126 | Serial.print("Erase Sector(0): n="); 127 | Serial.println(n,DEC); 128 | memset(buf,0,256); 129 | n = W25Q64_read (0,buf, 256); 130 | dump(buf,256); 131 | 132 | // データ書き込みテスト 133 | for (byte i=0; i < 16;i++) { 134 | wdata[i]='A'+i; 135 | } 136 | n = W25Q64_pageWrite(0, 10, wdata, 16); 137 | Serial.print("page_write(0,10,d,16): n="); 138 | Serial.println(n,DEC); 139 | memset(buf,0,256); 140 | n = W25Q64_read (0,buf, 256); 141 | dump(buf,256); 142 | 143 | // ステータスレジスタ1の取得 144 | buf[0] = W25Q64_readStatusReg1(); 145 | Serial.print("Status Register-1: "); 146 | Serial.print(buf[0],BIN); 147 | Serial.println(""); 148 | 149 | // ステータスレジスタ2の取得 150 | buf[0] = W25Q64_readStatusReg2(); 151 | Serial.print("Status Register-2: "); 152 | Serial.print(buf[0],BIN); 153 | Serial.println(""); 154 | } 155 | 156 | void loop() { 157 | 158 | } 159 | -------------------------------------------------------------------------------- /img/Schematic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/Schematic1.png -------------------------------------------------------------------------------- /img/Schematic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/Schematic2.png -------------------------------------------------------------------------------- /img/Schematic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/Schematic3.jpg -------------------------------------------------------------------------------- /img/Schematic4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/Schematic4.png -------------------------------------------------------------------------------- /img/W25Q64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/W25Q64.jpg -------------------------------------------------------------------------------- /img/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/demo.jpg -------------------------------------------------------------------------------- /img/sample_console_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tamakichi/Arduino-W25Q64/c88d21e515b2edbe1061bb55a66a859e1bed6a7c/img/sample_console_2.jpg --------------------------------------------------------------------------------