[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绝对都可以用~,我都原理图开放了
照第二天的方式去做,通常不能烧录都是没焊接好,我刚开始学也是不太会焊接,除错除很久才发现是自己焊接焊不好。


<<:  C国某大学生在校看色色的东西被简讯通知「...文明上网...写心得报告 」

>>:  自动化 End-End 测试 Nightwatch.js 之踩雷笔记:等待物件

Day 05-撰文在疫苗发作时,之module 是 terraform 执行与调用的基本单位

module 是 terraform 执行与调用的基本单位。本章简单介绍 module 的内容与使用...

[Day20] Laravel起步走

Laravel起步走 Laravel是一个MVC架构的PHP框架,分别是model(资料处理),co...

{DAY 17} Pandas 学习笔记part.3

前言 Pandas 是强大的资料科学分析工具, 今天要进入DataFrame的介绍 首先简介Data...

Day 29 : C语言 - 河内塔的程序递回执行顺序为何?

如标题,这篇想用「图解」去解释河内塔的「程序递回执行顺序」为何 因为当初C有一项作业,叫我们用程序去...

[第四天]从0开始的UnityAR手机游戏开发-介绍Unity介面和常用快捷键

Unity介面介绍 Unity最上方的工具列。 File:打开旧场景,开新场景、储存场景、开新旧或...