iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Arm Platforms

基於ARM-M0架構MCU之落摔檢測韌體開發系列 第 12

[DAY 12] _三軸感測器讀取函示講解 (ADXL345)

續昨天的bdp_I2C_ADXL345.c實現讀寫說明,
首先先看到Datasheet的第7頁引腳說明,在使用任何感測器前都要先看看引腳的功能描述:
https://ithelp.ithome.com.tw/upload/images/20210925/20141979JkkFqFuw2k.png]
1. VDD I/O :數位IO口的電壓
2. GND :接地
3. RESERVED :接Vs或著空接都可以
4. GND :接地
5. GND :接地
6. Vs :電源的電壓
7. CS| :芯片選擇腳位(手冊後面有說明接地的話是使用SPI通訊接VDD是使用I2C)
8. INT1 :中斷輸出1
9. INT2 :中斷輸出2
10.NC :內部空接
11.RESERVED :接GND或著空接都可以
12.SDO/ALT ADDRESS:可當SPI傳輸的SDO/用I2C的話可以決定設備地址
13.SDA/SDI/SDIO :由於我們是用I2C這腳就是資料線SDA
14.SCL/SCLK :由於我們是用I2C這腳就是時脈線SCL

懂了每隻腳的功能,再來就是要知道ADXL345的設備地址,看Datasheet的第18頁的I2C說明:
https://ithelp.ithome.com.tw/upload/images/20210925/20141979nvCMxDTwgj.png
我解釋紅框的部分,首先第一行就說明CS腳拉high是使用I2C模式,再來看下半部的紅框,
這裡面是在說當
12腳(ALT ADDRESS)接VDD時設備地址是0x1D,寫是0x3A、讀是0x3B
12腳(ALT ADDRESS)接GND時設備地址是0x53,寫是0xA6、讀是0xA7
這邊我要講個I2C的觀念,目前感測器用I2C讀取的設備地址幾乎都是7bit,第8bit決定要讀還是寫
可以看上面,0x53左移一位就是0xA6,在加個1就是讀取
不懂的話可以看這2進制的位移 0x53(0101 0011)左移一位後0xA6(1010 0110),數位邏輯的概念
再來看看手冊的讀寫時序說明,18頁下半部:
https://ithelp.ithome.com.tw/upload/images/20210925/201419798DvL3N4KRk.png
看紅框部份在看我昨天的讀寫函式:

//寫ADXL345寄存器		  addr:暫存器地址			al:要寫入的值
void ADXL345_WR_Reg(uint8_t addr,uint8_t val)  //void ADXL345_write(u8 addr, u8 data)
{
	i2c_Start();                 
	i2c_SendByte(ADXL_WRITE);   
	i2c_WaitAck();    
	i2c_SendByte(addr);
	i2c_WaitAck();                                                         
	i2c_SendByte(val);                                
	i2c_WaitAck();                    
	i2c_Stop();                     
	
} 
//讀ADXL345寄存器			addr:寄存器地址			返回值:讀到的值
uint8_t ADXL345_RD_Reg(uint8_t addr)
{
	uint8_t temp=0;  
	i2c_Start();                   
	i2c_SendByte(ADXL_WRITE);      
	i2c_WaitAck();       
	i2c_SendByte(addr);        //發送寄存器地址
	i2c_WaitAck();                                                       
	i2c_Start();               
	i2c_SendByte(ADXL_READ);       
	i2c_WaitAck();        
	temp=i2c_ReadByte();       
	i2c_NAck();
	i2c_Stop();                      
	return temp;              
} 

看的出來是一樣的時序嗎?,看不出來的話建議拿張白紙出來畫時序,不是開玩笑我一開始學I2C也是這樣過來的
用手寫出時序會更好懂。
然後我看看我昨天的主函式main.c

#include "bsp_I2C_adxl345.h"
#include "bsp_SysTick.h"    //操作MO內核暫存器使用滴答計時器來做精準計時
                            //參考網站:https://kknews.cc/zh-tw/news/96p52m5.html
int main(void)
{
  int8_t x0,x1,y0,y1,z1,z0; //宣告3個軸的變數,1個軸有高8為和低8位
  SysTick_Init(48);         //配置Delay函式
  
  DEBUG_USART_Config();     //初始化UART
  ADXL345_Init();           //初始化ADXL345
  
  while(1)
  {
    x0=ADXL345_RD_Reg(0xAA);// 取得 X 軸 低位元資料
	x1=ADXL345_RD_Reg(0x33);// 取得 X 軸 高位元資料
	x=(((x1 << 8)+x0)/256.0);
    
	y0=ADXL345_RD_Reg(0x34);// 取得 Y 軸 低位元資料
    y1=ADXL345_RD_Reg(0x35);// 取得 Y 軸 高位元資料
    y=(((y1 << 8)+y0)/256.0);
    
    z0=ADXL345_RD_Reg(0x36);// 取得 Z 軸 低位元資料
    z1=ADXL345_RD_Reg(0x37);// 取得 Y 軸 高位元資料
    z=(((z1 << 8)+z0)/256.0);
    
	printf("X=%.3f  Y=%.3f  Z=%.3f\r\n",x,y,z);
	delay_ms(100);
   }
}

然後再來看看網路上用Arduino讀取三軸的範例,網址:https://lolikitty.pixnet.net/blog/post/165475299
看一下跟我有沒有差別,幾乎一樣吧XD,我前面坐的那些配置Arduino已經在底層都幫你寫好了。
我在這邊分享一下我學習STM32的方法,我自己會先用Arduino跟感測器模組來用,先看她怎麼動作的再來寫STM32,寫好後我會先用我第二天說講的開發板來接模組測試看看有沒有抓到數值,有抓到後我才會開始製作最小系統板,確定沒問題才會開始製作自己的系統板,之後我也會教學製作最小系統板的原理圖。
這邊先附上我第二天的開發板送洗出來的PCB
https://ithelp.ithome.com.tw/upload/images/20210925/20141979RZOct9CkhF.jpg
有興趣的可以自己做一片來,照著我第2天所說明的,做哪顆MCU絕對都可以用~,我都原理圖開放了
照第二天的方式去做,通常不能燒錄都是沒焊接好,我剛開始學也是不太會焊接,除錯除很久才發現是自己焊接焊不好。


上一篇
[DAY 11] _軟體實現I2C協議以三軸感測器為例 (ADXL345)
下一篇
[DAY 13] _ADXL345_I2C時序說明 (ADXL345)
系列文
基於ARM-M0架構MCU之落摔檢測韌體開發32

尚未有邦友留言

立即登入留言