在使用SPI最基本會有四個腳位:
- MISO:Master In, Slave Out
- MOSI:Master Out, Slave In
- SCK(SCLK or Clock):Serial 時脈
- SS/CS(Slave Select/Chip Select):LOW表示裝置可以與Master通訊;HIGH表示不與Master通訊
此四個腳位與Arduino UNO對應的腳位如下:
- SS/CS -- Pin 10
- MOSI -- Pin 11
- MISO -- Pin 12
- SCK -- Pin 13
對於SPI的使用,我們只要了解這幾個腳位即可。接下來,我們以SD卡模組來實作練習看看(因為SD卡也是使用SPI來和Arduino進行通訊)。需要準備的材料如下:
- Arduino控制板(我的版本是Arduino UNO)
- SD卡模組(這個是很久之前買的模組,現在很多都出Micro SD(小卡)的了,但使用方法大同小異)
- 六條連接線
硬體的接線方法,可參考在官網上找到的這張圖接線即可:
在程式碼的部份,我以Arduino 內建的範例來示範。請先開啟Arduino IDE,依序選擇File > Examples > SD > Datalogger
完整的程式碼如下:
/* ==================================================== */
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
pinMode(10,OUTPUT); // 嚴謹一點的話,程式應該加上此行
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop() {
// make a string for assembling the data to log:
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
delay(1000); // 增加此行,減少寫入失敗
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
/* ==================================================== */
有幾個地方需要注意一下:
完整的程式碼如下:
/* ==================================================== */
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
pinMode(10,OUTPUT); // 嚴謹一點的話,程式應該加上此行
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop() {
// make a string for assembling the data to log:
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
delay(1000); // 增加此行,減少寫入失敗
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
有幾個地方需要注意一下:
- const int chipSelect = 4;
這個範例裡,我們指定Pin 4為CS Pin。在查詢官網的相關訊息發現,因為我們是引用SD Library,即使沒有使用到硬體的SS/CS Pin,也需要將SS/CS Pin保留為輸出模式(以UNO為例,就是Pin 10),否則SD Library無法正常執行。所以在setup()裡我加上了一行pinMode(10,OUTPUT) ,但實驗發現,此行沒加也可以正常執行。 - 在寫入到SD卡的程式裡,我有加上讓它延遲一秒再寫入。因為實驗發現,沒有加上這行,寫入失敗的機率好像蠻高的。
作者已經移除這則留言。
回覆刪除
回覆刪除// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
改成 while (!SD.begin(chipSelect)) ;
就可以