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,下面是整个手册的源码:
[cpp] view plaincopy
1. #define DATAOUT 11//MOSI 2. #define DATAIN 12//MISO 3. #define SPICLOCK 13//sck 4. #define SLAVESELECT 10//ss 5.
6. //opcodes 7. #define WREN 6 8. #define WRDI 4 9. #define RDSR 5 10. #define WRSR 1 11. #define READ 3 12. #define WRITE 2 13.
14. byte eeprom_output_data; 15. byte eeprom_input_data=0; 16. byte clr; 17. int address=0; 18. //data buffer 19. char buffer [128]; 20.
21. void fill_buffer() 22. {
23. for (int I=0;I<128;I++) 24. {
25. buffer[I]=I; 26. } 27. } 28.
29. char spi_transfer(volatile char data) 30. {
31. SPDR = data; // Start the transmission
32. while (!(SPSR & (1< 35. return SPDR; // return the received byte 36. } 37. 38. void setup() 39. { 40. Serial.begin(9600); 41. 42. pinMode(DATAOUT, OUTPUT); 43. pinMode(DATAIN, INPUT); 44. pinMode(SPICLOCK,OUTPUT); 45. pinMode(SLAVESELECT,OUTPUT); 46. digitalWrite(SLAVESELECT,HIGH); //disable device 47. // SPCR = 01010000 48. //interrupt disabled,spi enabled,msb 1st,master,clk low when idle, 49. //sample on leading edge of clk,system clock/4 rate (fastest) 50. SPCR = (1< 54. //fill buffer with data 55. fill_buffer(); 56. //fill eeprom w/ buffer 57. digitalWrite(SLAVESELECT,LOW); 58. spi_transfer(WREN); //write enable 59. digitalWrite(SLAVESELECT,HIGH); 60. delay(10); 61. digitalWrite(SLAVESELECT,LOW); 62. spi_transfer(WRITE); //write instruction 63. address=0; 64. spi_transfer((char)(address>>8)); //send MSByte address first 65. spi_transfer((char)(address)); //send LSByte address 66. //write 128 bytes 67. for (int I=0;I<128;I++) 68. { 69. spi_transfer(buffer[I]); //write data byte 70. } 71. digitalWrite(SLAVESELECT,HIGH); //release chip 72. //wait for eeprom to finish writing 73. delay(3000); 74. Serial.print('h',BYTE); 75. Serial.print('i',BYTE); 76. Serial.print('\\n',BYTE);//debug 77. delay(1000); 78. } 79. 80. byte read_eeprom(int EEPROM_address) 81. { 82. //READ EEPROM 83. int data; 84. digitalWrite(SLAVESELECT,LOW); 85. spi_transfer(READ); //transmit read opcode 86. spi_transfer((char)(EEPROM_address>>8)); //send MSByte address first 87. spi_transfer((char)(EEPROM_address)); //send LSByte address 88. data = spi_transfer(0xFF); //get data byte 89. digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer 90. return data; 91. } 92. 93. void loop() 94. { 95. eeprom_output_data = read_eeprom(address); 96. Serial.print(eeprom_output_data,DEC); 97. Serial.print('\\n',BYTE); 98. address++; 99. if (address == 128) 100. address = 0; 101. delay(500); //pause for readability 102. } 个人一些小tip: 一定要记得,其实整个programing有2个部分,一个部分是操作Arduino中的SPI,一个部分是EEPROM板子哪些操作是操作Arduino,哪些是操作EEPROM,自己一定要清楚。