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