Arduino与Proteus仿真实例-M45PE16串行(SPI)Flash数据存取驱动仿真
M45PE16串行(SPI)Flash数据存取驱动仿真
1、M45PE16介绍
M45PE16 是一个 16Mbit(2M x 8 位)串行页面闪存(Flash),通过高速 SPI 兼容总线访问。使用页面写入或页面编程指令,可以一次写入或编程 1 至 256 个字节的内存。 页写入指令由一个集成的页擦除周期和一个页编程周期组成。
内存被组织成 32 个扇区,每个扇区包含 256 页。 每页宽 256 字节。 因此,可以将整个存储器视为由 8192 页或 2,097,152 字节组成。存储器可以使用页擦除指令一次擦除一页,或使用扇区擦除指令一次擦除一个扇区。

引脚功能如下:

2、仿真电路原理图

3、仿真代码实现
1)M45PE16定义
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
| // M45PE16.h #ifndef \_\_M45PE16\_H\_\_ #define \_\_M45PE16\_H\_\_ // M45PE16命令 #define WREN 0X06 #define WRDI 0X04 #define RDID 0X9F #define RDSR 0X05 #define READ 0X03 #define FAST\_READ 0X0B #define PW 0X0A #define PP 0X02 #define PE 0XDB #define SE 0XD8 #define DP 0XB9 #define RDP 0XAB
// 页面大小 #define PAGE\_SIZE 256 // 扇区偏移 #define NUM\_OF\_SECTORS 32 // 扇区中的页面 #define NUM\_OF\_PAGES\_IN\_SECTOR 256
// SPI片选引脚拉高(SS引脚) #define FLASH\_chipSelectHigh() (PORTB|=(1<<2)) // SPI片选引脚拉低(SS引脚) #define FLASH\_chipSelectLow() (PORTB&=~(1<<2)) // 等待传输完成 #define waitForTransferComplete() while(!(SPSR&(1<<SPIF))) #ifdef \_\_cplusplus extern "C" { #endif // 配置SPI void FLASH\_ConfigSPI(void); // 写一个字节数据 void FLASH\_TXByte(uint8\_t uData); // 在指定地址写指定长度数据 void FLASH\_PageWrite(uint32\_t pageAddress,uint8\_t \*uData, uint8\_t sizeData); // 从指定地址开始读取指定长度数据 void FLASH\_PageRead(uint32\_t pageAddress,uint8\_t \*uData, uint8\_t sizeData); #ifdef \_\_cplusplus } #endif //#ifdef \_\_cplusplus #endif /\* \_\_M45PE16\_H\_\_ \*/
|
2)M45PE16驱动实现
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
| #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include "M45PE16.h" //Configure SPI
void FLASH\_ConfigSPI(void){ // 将 SS,MOSI,SCK 引脚设置为输出 DDRB|=(1<<4)|(1<<5)|(1<<7); // 将SPI设置为主机模式MODE0, 时钟为fOsc/4 SPCR|=(1<<SPE)|(1<<MSTR)|(1<<SPR0); // 清空SPI状态寄存器 SPSR=0x00; }
void FLASH\_TXByte(uint8\_t uData) { FLASH\_chipSelectLow(); SPDR = uData; waitForTransferComplete(); FLASH\_chipSelectHigh();
}
void FLASH\_PageWrite(uint32\_t pageAddress,uint8\_t \*uData, uint8\_t sizeData) { uint8\_t iterator;
FLASH\_TXByte(WREN); \_delay\_ms(10);
FLASH\_chipSelectLow();
SPDR = PP; waitForTransferComplete();
SPDR = (uint8\_t)pageAddress; waitForTransferComplete(); SPDR = (uint8\_t)(pageAddress>>8); waitForTransferComplete(); SPDR = (uint8\_t)(pageAddress>>16); waitForTransferComplete();
for(iterator = 0; iterator < sizeData; iterator++) { SPDR = uData[iterator]; waitForTransferComplete(); } FLASH\_chipSelectHigh(); }
void FLASH\_PageRead(uint32\_t pageAddress,uint8\_t \*uData, uint8\_t sizeData){ uint8\_t iterator;
FLASH\_TXByte(WREN); \_delay\_ms(10);
FLASH\_chipSelectLow();
SPDR = READ; waitForTransferComplete();
SPDR = (uint8\_t)pageAddress; waitForTransferComplete(); SPDR = (uint8\_t)(pageAddress>>8); waitForTransferComplete(); SPDR = (uint8\_t)(pageAddress>>16); waitForTransferComplete();
for(iterator = 0; iterator < sizeData; iterator++){ SPDR=0xf0;waitForTransferComplete(); uData[iterator] = SPDR; //waitForTransferComplete(); } FLASH\_chipSelectHigh(); }
|
3)主程序
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
| #include <SPI.h> #include "M45PE16.h"
const uint8\_t CS = 10; int readPin = 2; int writePin = 3; uint8\_t counts = 1; byte readState; byte writeState; uint8\_t data_buf[1] = {0};
void read\_interrupt(){ readState = 1; }
void write\_interrupt(){ writeState = 1; }
void setup(){ pinMode(readPin,INPUT); pinMode(writePin,INPUT); attachInterrupt(digitalPinToInterrupt(readPin),read_interrupt,RISING); attachInterrupt(digitalPinToInterrupt(writePin),write_interrupt,RISING); Serial.begin(9600); // Wire.begin(); Serial.println("\*\*\*\*EEPROM M95M256 \*\*\*\*"); FLASH\_ConfigSPI(); }
void loop(){ if(readState){ FLASH\_PageWrite(0,data_buf,1); Serial.print("read:"); Serial.print(data_buf[0]); Serial.println(); readState = 0; }
if(writeState){ Serial.print("write:"); Serial.print(counts); Serial.println(); data_buf[0] = counts; FLASH\_PageWrite(0,data_buf,1); counts++; writeState = 0; } }
|
4、仿真结果

文章来源: https://iotsmart.blog.csdn.net/article/details/121048518
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!