讓我們解構複雜的 ADXL345 三軸加速規吧!(第七彈)

實作 4-wire SPI 寫入函數

前面已經介紹過用 GPIO 自幹給 ADXL345 用的 3 個 function 實作細節:

  • void _SPI_CS(bit isSelect);
  • void _SPI_SCL(bit bLevel);
  • unsigned char ADXL345_SPI_Read(unsigned char Address);

而且已經用讀取 Register map 來驗證以上三個自幹 function 的正確性。

這篇要介紹最後一個:

void ADXL345_SPI_Write(unsigned char Address, unsigned char WriteData);

作用是讓 Master 對 Slave 寫資料,沒有回傳值,但一定要傳入 Address 和 WriteData 。所以,其實就是對下圖這張 Register Map 寫資料(Type 那欄要有 W-bar 才能寫資料只有 R 的就是唯讀,不可寫)

沒錯,這個表格又出現了。

Step1: 啟動 ADXL345

_SPI_CS(0);

這邊沒什麼好說明的。


Step2: 由 MCU 寫入位址到 ADXL345

for(i=7 ; i>=0; i--)
{
// F-Edge
_SPI_SCL(1);
SDA = 0x1 & ((0x7F & Address) >> i);
_SPI_SCL(0);
}

//===========================
_SPI_SCL(1);
//===========================

這邊跟 unsigned char ADXL345_SPI_Read(unsigned char Address) 一樣,第一步都要寫位置進去,流程上也完全相同,唯一不同的就是 Address mask 有變。

上一篇有提過一個概念, ADXL345 的 Address 其實只有 7bit , MSB 是決定送完這個位址的下一步是要讀或寫? 1 就是讀、 0 就是寫。

這篇的 0x7F 或上一篇的 0x80 都是 Address mask。

(0x7F & Address)

這一行是為了令 Address 的 MSB 為 0(因為下一步要寫資料到ADXL345),剩下 7bit 不變。

>> i

「>>」是右移運算子,看目前送到哪個 bit?就把該 bit 拉到 LSB 。因為等等丟到 Output 去時只能丟 LSB。

0x1 &

確保除了 LSB 以外都是 0。


Step3: 由 MCU 寫入資料到 ADXL345

for(i=7; i >= 0; i--)
{
// F-Edge
_SPI_SCL(1);
SDA = 0x1 & ((WriteData) >> i);
_SPI_SCL(0);
}

程式碼跟上一步幾乎相同,只是少掉 Address mask,因為這次要寫入完整的8bit 資料,而不是 1+7bit 的 R/W+ 位址。細節就不再贅述。


Step4: 關閉 ADXL345

_SPI_CS(1);

這邊沒什麼好說明的。


一步一步介紹完了,完整的 function 就是長這樣惹

void ADXL345_SPI_Write(unsigned char Address, unsigned char WriteData)
{
char i;

_SPI_CS(0);

for(i=7; i >= 0; i--)
{
// F-Edge
_SPI_SCL(1);
SDA = 0x1 & ((0x7F & Address) >> i);
_SPI_SCL(0);
}

for(i=7; i >= 0; i--)
{
// F-Edge
_SPI_SCL(1);
SDA = 0x1 & ((WriteData) >> i);
_SPI_SCL(0);
}

_SPI_CS(1);
}

到這裡,終於把 SPI.h 裡面 4 個用 GPIO 自幹的 function 介紹完了。光是這樣你就可以參考 AN-1077( ADXL345 Quick Start Guide) 嘗試自己從 int main() 或 void loop() 開始寫起。

還是不會嗎?沒關係,下一篇會教大家從 int main() 開始寫起,一步步讀出三軸加速度!