原文:http://www.arduino.cc/en/Tutorial/SPIEEPROM
1.串行外围设备接口入门(Introduction to the Serial Peripheral Interface)
2.串行EEPROM简介
3.面包板的准备
4.Arduino SPI 编程
spi_transfer函数将要传出的数据放入数据传输寄存器,然后就开始SPI传输了哈。可以通过SPI状态寄存器(SPSR)的某个位(SPIF)来查看数据传输是否结束了。关于位掩码(bit mask)可以参考这里:http://www.arduino.cc/en/Tutorial/。最后返回写入EEPROM的数据。
read_eeprom函数允许我们从EEPROM中读入数据,首先设置SLAVESELECT为低来enable设备。接下来送入一个读指定,接下来送入要读的16位地址,最高有效位有限。接下来我们发送一个假数据到EEPROM中以将数据传出。最后我们在读入一个字节后,再次设置SLAVESELECT线为高来释放设备,并返回数据,如果我们想要一次读入多个数据,那么当我们重复data=spi_transfer(0XFF)时,需要将SLAVESELECT一直设置为低,这样来回128次后读出整个页的数据:
为了方便大家CTRL+c、 CTRL+v,下面是整个手册的源码:
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK 13//sck
#define SLAVESELECT 10//ss
//opcodes
#define WREN 6
#define WRDI 4
#define RDSR 5
#define WRSR 1
#define READ 3
#define WRITE 2
byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];
void fill_buffer()
{
for (int I=0;I<128;I++)
{
buffer[I]=I;
}
}
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}
void setup()
{
Serial.begin(9600);
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(SLAVESELECT,OUTPUT);
digitalWrite(SLAVESELECT,HIGH); //disable device
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 rate (fastest)
SPCR = (1<<SPE)|(1<<MSTR);
clr=SPSR;
clr=SPDR;
delay(10);
//fill buffer with data
fill_buffer();
//fill eeprom w/ buffer
digitalWrite(SLAVESELECT,LOW);
spi_transfer(WREN); //write enable
digitalWrite(SLAVESELECT,HIGH);
delay(10);
digitalWrite(SLAVESELECT,LOW);
spi_transfer(WRITE); //write instruction
address=0;
spi_transfer((char)(address>>8)); //send MSByte address first
spi_transfer((char)(address)); //send LSByte address
//write 128 bytes
for (int I=0;I<128;I++)
{
spi_transfer(buffer[I]); //write data byte
}
digitalWrite(SLAVESELECT,HIGH); //release chip
//wait for eeprom to finish writing
delay(3000);
Serial.print('h',BYTE);
Serial.print('i',BYTE);
Serial.print('\n',BYTE);//debug
delay(1000);
}
byte read_eeprom(int EEPROM_address)
{
//READ EEPROM
int data;
digitalWrite(SLAVESELECT,LOW);
spi_transfer(READ); //transmit read opcode
spi_transfer((char)(EEPROM_address>>8)); //send MSByte address first
spi_transfer((char)(EEPROM_address)); //send LSByte address
data = spi_transfer(0xFF); //get data byte
digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
return data;
}
void loop()
{
eeprom_output_data = read_eeprom(address);
Serial.print(eeprom_output_data,DEC);
Serial.print('\n',BYTE);
address++;
if (address == 128)
address = 0;
delay(500); //pause for readability
}
个人一些小tip:
一定要记得,其实整个programing有2个部分,一个部分是操作Arduino中的SPI,一个部分是EEPROM板子哪些操作是操作Arduino,哪些是操作EEPROM,自己一定要清楚。