MSP430单片机驱动ADXL345程序
ADXL345数字加速度传感器通过IIC协议传输数据的使用方法(一)
ADXL345数字加速度传感器通过IIC协议传输数据的使⽤⽅法(⼀)ADXL345是ADI公司推出的具有SPI和IIC数字输出功能的三轴加速度计,其最⼤的量程可达到 -16g,另外可选择 -2, -4,-8g量程,可采⽤4mg/LSB分辨率,该分辨率可测得0.25的倾⾓变化16g量程,意思就是16g时输出32768,-16g时输出-32768,2的16次⽅LSB的意思是最⼩有效位,为数字输出⽅式,⼀般我们可以⽤mg/LSB来表⽰灵敏度例如ADXL345量程为 /2g,输出的位数为10位(2的10次⽅共1024个LSB)对应满量程,那么灵敏度就为4g/1024LSB=3.9mv/g,取倒数为256LSB/g。
ADXL345引脚功能图⾃动休眠模式静⽌期间⾃动切换到休眠模式,可以省电。
要使能此功能,如果ADXL345在静⽌期在THRESH_INACT寄存器(地址0x25) 和TIME_INACT寄存器(地址0x26)设置⼀个值表⽰静⽌(适当值视应⽤⽽定),然后在POWER_CTL寄存器(地址0x2D) 中设置AUTO_SLEEP位(位D4)和链接位(位D5)。
VS为2.5V 时,该模式下低于12.5 Hz数据速率的功耗通常为23 µA。
待机模式更低功率操作,也可以使⽤待机模式。
待机模式下,功耗降低到0.1µA(典型值)。
该模式中,⽆测量发⽣。
在 POWER_CTL寄存器(地址0x2D)中,清除测量位(位D3),可进⼊待机模式。
器件在待机模式下保存FIFO内容串⾏通信可采⽤IIC和SPI数字通信。
上述两种情况下,ADXL345作为从机运⾏。
CS引脚上拉⾄VDD I/O,I2C模式使能模式使能。
CS引脚应始终上拉⾄VDD I/O或由外部控制器驱动,因为CS引脚⽆连接时,默认模式不存在。
因此,如果没有采取这些措施,可能会导致该器件⽆法通信。
SPI模式下,CS引脚由总线主机控制。
SPI和I2C两种操作模式下,ADXL345写⼊期间,应忽略从ADXL345传输到主器件的数据。
(完整版)arduino应用:ADXL345
前两天我们做了温度传感器实验,大家一定还有印象。
今天我们来研究另外一种传感器加速度传感器。
什么是加速度传感器加速度传感器,作用是测量在加速过程中产生的力。
最基本的如咱们平常所熟悉的是重力加速度,大小是1g。
加速度传感器一般用于什么地方通过测量由重力引起的加速度,你可以计算出设备相对于水平面的倾斜角度。
通过分析动态加速度,你可以分析出设备的移动方式。
自平衡车中就是使用加速度传感器与陀螺仪进行卡尔曼滤波进行姿态矫正。
本次试验使用的ADXL345数字传感器,通过I2C或者SPI接口直接输出数字信号。
在1g的加速度下,输出数值为256.下面是硬件连接图2011-7-28 22:56 上传下载附件(203.65 KB)ARDUINO 代码复制打印1.#include <Wire.h> //调用arduino自带的I2C库2.#include <LiquidCrystal.h> //调用arduino自带的LiquidCrystal库3.4.#define Register_ID 05.#define Register_2D 0x2D6.#define Register_X0 0x327.#define Register_X1 0x338.#define Register_Y0 0x349.#define Register_Y1 0x3510.#define Register_Z0 0x3611.#define Register_Z1 0x3712.13.LiquidCrystal lcd(12, 11, 10, 9, 8, 7);//设置接口14.15.int ADXAddress = 0xA7>>1; //转换为7位地址16.int reading = 0;17.int val = 0;18.int X0,X1,X_out;19.int Y0,Y1,Y_out;20.int Z1,Z0,Z_out;21.double Xg,Yg,Zg;22.23.void setup()24.{25. lcd.begin(16, 2); //初始化LCD26.delay(100);27.Wire.begin(); //初始化I2C28.delay(100);29.Wire.beginTransmission(ADXAddress);30.Wire.write(Register_2D);31.Wire.write(8);32.Wire.endTransmission();33.}34.35.void loop()36.{37.Wire.beginTransmission(ADXAddress);38.Wire.write(Register_X0);39.Wire.write(Register_X1);40.Wire.endTransmission();41.Wire.requestFrom(ADXAddress,2);42.if(Wire.available()<=2);43.{44. X0 = Wire.read();45. X1 = Wire.read();46. X1 = X1<<8;47. X_out = X0+X1;48.}49.50.Wire.beginTransmission(ADXAddress);51.Wire.write(Register_Y0);52.Wire.write(Register_Y1);53.Wire.endTransmission();54.Wire.requestFrom(ADXAddress,2);55.if(Wire.available()<=2);56.{57. Y0 = Wire.read();58. Y1 = Wire.read();59. Y1 = Y1<<8;60. Y_out = Y0+Y1;61.}62.63.Wire.beginTransmission(ADXAddress);64.Wire.write(Register_Z0);65.Wire.write(Register_Z1);66.Wire.endTransmission();67.Wire.requestFrom(ADXAddress,2);68.if(Wire.available()<=2);69.{70. Z0 = Wire.read();71. Z1 = Wire.read();72. Z1 = Z1<<8;73. Z_out = Z0+Z1;74.}75.76. Xg = X_out/256.00;//把输出结果转换为重力加速度g,精确到小数点后2位。
MSP430单片机入门例程
MSP430单片机入门例程MSP430单片机是一款低功耗、高性能的16位单片机,广泛应用于各种嵌入式系统。
下面是一个简单的MSP430单片机入门例程,可以让大家初步了解MSP430单片机的基本使用方法。
所需材料:1、MSP430单片机开发板2、MSP430单片机编译器3、MSP430单片机调试器4、电脑和相关软件步骤:1、安装MSP430单片机编译器首先需要安装MSP430单片机的编译器,该编译器可以将C语言代码编译成MSP430单片机可以执行的机器码。
在安装编译器时,需要选择与您的单片机型号匹配的编译器。
2、编写程序下面是一个简单的MSP430单片机程序,可以让LED灯闪烁:c本文include <msp430.h>int main(void)本文P1DIR |= 0x01; //设置P1.0为输出while(1){P1OUT ^= 0x01; //反转P1.0的状态,LED闪烁__delay_cycles(); //延时一段时间,控制闪烁频率}本文上述程序中,首先定义了P1DIR寄存器,将P1.0设置为输出。
然后进入一个无限循环,在循环中反转P1.0的状态,使LED闪烁。
使用__delay_cycles()函数实现延时,控制LED闪烁频率。
3、编译程序使用MSP430单片机编译器将程序编译成机器码,生成可执行文件。
在编译时,需要注意选择正确的编译器选项和单片机型号。
4、调试程序使用MSP430单片机调试器将可执行文件下载到单片机中,并使用调试器进行调试。
在调试时,可以观察单片机的输出口状态和LED灯的闪烁情况,确保程序正常运行。
随着嵌入式系统的发展,MSP430单片机作为一种低功耗、高性能的微控制器,在各种应用领域中得到了广泛的应用。
为了更好地理解和应用MSP430单片机,我在学习过程中积累了一些经验,现在分享给大家。
MSP430单片机是一种超低功耗的微控制器,由德州仪器(Texas Instruments)推出。
加速度传感器ADXL345模块测试程序
/** ADXL345模块** 用途:ADXL345模块IIC测试程序*/#include<REG51.H>#include <math.h> //Keil library#include <stdio.h> //Keil library#include <INTRINS.H>#define uchar unsigne d char#define uint unsigne d int#defineDataPort P2 //LCD1602数据端口sbit SCL=P0^4; //IIC时钟引脚定义sbit SDA=P0^3; //IIC数据引脚定义sbit LCM_RS=P0^2; //LCD1602命令端口sbit LCM_RW=P0^1; //LCD1602命令端口sbit LCM_EN=P0^0; //LCD1602命令端口#defineSlaveAd dress0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS 地址引脚不同修改//ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3Atypedef unsigne d char BYTE;typedef unsigne d short WORD;BYTE BUF[8]; //接收数据缓存区uchar ge,shi,bai,qian,wan; //显示变量int dis_data; //变量void delay(unsigne d int k);void InitLcd(); //初始化lcd1602void Init_AD XL345(void); //初始化ADXL345void WriteDa taLCM(uchar dataW);void WriteCo mmandL CM(uchar CMD,uchar Attribc);void Display OneCha r(uchar X,uchar Y,uchar DData);void convers ion(uint temp_da ta);void Single_W rite_A DXL345(uchar REG_Add ress,uchar REG_dat a); //单个写入数据uchar Single_Read_A DXL345(uchar REG_Add ress); //单个读取内部寄存器数据void Multipl e_Read_ADXL345(); //连续的读取内部寄存器数据//------------------------------------void Delay5u s();void Delay5m s();void ADXL345_Start();void ADXL345_Stop();void ADXL345_SendA CK(bit ack);bit ADXL345_RecvA CK();void ADXL345_SendB yte(BYTE dat);BYTE ADXL345_RecvB yte();void ADXL345_ReadP age();void ADXL345_Write Page();//-----------------------------------//********************************************************* void convers ion(uint temp_da ta){wan=temp_da ta/10000+0x30 ;temp_da ta=temp_da ta%10000; //取余运算qian=temp_da ta/1000+0x30 ;temp_da ta=temp_da ta%1000; //取余运算bai=temp_da ta/100+0x30 ;temp_da ta=temp_da ta%100; //取余运算shi=temp_da ta/10+0x30 ;temp_da ta=temp_da ta%10; //取余运算ge=temp_da ta+0x30;}/*******************************/void delay(unsigne d int k){unsigne d int i,j;for(i=0;i<k;i++){for(j=0;j<121;j++){;}}}/*******************************/void WaitFor Enable(void){DataPor t=0xff;LCM_RS=0;LCM_RW=1;_nop_();LCM_EN=1;_nop_();_nop_();while(DataPor t&0x80);LCM_EN=0;}/*******************************/void WriteCo mmandL CM(uchar CMD,uchar Attribc){if(Attribc)WaitFor Enable();LCM_RS=0;LCM_RW=0;_nop_();DataPor t=CMD;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}/*******************************/void WriteDa taLCM(uchar dataW){WaitFor Enable();LCM_RS=1;LCM_RW=0;_nop_();DataPor t=dataW;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}/***********************************/void InitLcd(){WriteCo mmandL CM(0x38,1);WriteCo mmandL CM(0x08,1);WriteCo mmandL CM(0x01,1);WriteCo mmandL CM(0x06,1);WriteCo mmandL CM(0x0c,1);}/***********************************/void Display OneCha r(uchar X,uchar Y,uchar DData){Y&=1;X&=15;if(Y)X|=0x40;X|=0x80;WriteCo mmandL CM(X,0);WriteDa taLCM(DData);}/**************************************延时5微秒(STC90C52RC@12M)不同的工作环境,需要调整此函数,注意时钟过快时需要修改当改用1T的M CU时,请调整此延时函数**************************************/void Delay5u s(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/**************************************延时5毫秒(STC90C52RC@12M)不同的工作环境,需要调整此函数当改用1T的M CU时,请调整此延时函数**************************************/ void Delay5m s(){WORD n = 560;while (n--);}/**************************************起始信号**************************************/ void ADXL345_Start(){SDA = 1; //拉高数据线SCL = 1; //拉高时钟线Delay5u s(); //延时SDA = 0; //产生下降沿Delay5u s(); //延时SCL = 0; //拉低时钟线}/**************************************停止信号**************************************/ void ADXL345_Stop(){SDA = 0; //拉低数据线SCL = 1; //拉高时钟线Delay5u s(); //延时SDA = 1; //产生上升沿Delay5u s(); //延时}/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void ADXL345_SendA CK(bit ack){SDA = ack; //写应答信号SCL = 1; //拉高时钟线Delay5u s(); //延时SCL = 0; //拉低时钟线Delay5u s(); //延时}/**************************************接收应答信号**************************************/bit ADXL345_RecvA CK(){SCL = 1; //拉高时钟线Delay5u s(); //延时CY = SDA; //读应答信号SCL = 0; //拉低时钟线Delay5u s(); //延时returnCY;}/**************************************向IIC总线发送一个字节数据**************************************/void ADXL345_SendB yte(BYTE dat){BYTE i;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY; //送数据口SCL = 1; //拉高时钟线Delay5u s(); //延时SCL = 0; //拉低时钟线Delay5u s(); //延时}ADXL345_RecvA CK();}/**************************************从IIC总线接收一个字节数据**************************************/BYTE ADXL345_RecvB yte(){BYTE i;BYTE dat = 0;SDA = 1; //使能内部上拉,准备读取数据,for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线Delay5u s(); //延时dat |= SDA; //读数据SCL = 0; //拉低时钟线Delay5u s(); //延时}returndat;}//******单字节写入*******************************************void Single_Write_ADXL345(uchar REG_Add ress,uchar REG_dat a){ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(REG_Add ress); //内部寄存器地址,请参考中文pd f22页ADXL345_SendB yte(REG_data); //内部寄存器数据,请参考中文pd f22页ADXL345_Stop(); //发送停止信号}//********单字节读取*****************************************uchar Single_Read_A DXL345(uchar REG_Add ress){ uchar REG_dat a;ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(REG_Add ress); //发送存储单元地址,从0开始ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress+1); //发送设备地址+读信号REG_dat a=ADXL345_RecvB yte(); //读出寄存器数据ADXL345_SendA CK(1);ADXL345_Stop(); //停止信号returnREG_dat a;}//*********************************************************////连续读出ADX L345内部加速度数据,地址范围0x32~0x37////*********************************************************void Multipl e_read_ADXL345(void){ uchar i;ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(0x32); //发送存储单元地址,从0x32开始ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress+1); //发送设备地址+读信号for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF{BUF[i] = ADXL345_RecvB yte(); //BUF[0]存储0x32地址中的数据if (i == 5){ADXL345_SendA CK(1); //最后一个数据需要回NOACK }else{ADXL345_SendA CK(0); //回应ACK}}ADXL345_Stop(); //停止信号Delay5m s();}//*****************************************************************//初始化ADXL345,根据需要请参考p df进行修改************************void Init_AD XL345(){Single_W rite_A DXL345(0x31,0x0B); //测量范围,正负16g,13位模式Single_W rite_A DXL345(0x2C,0x08); //速率设定为12.5 参考pdf13页Single_W rite_A DXL345(0x2D,0x08); //选择电源模式参考pdf24页Single_W rite_A DXL345(0x2E,0x80); //使能DA TA_READY中断Single_W rite_A DXL345(0x1E,0x00); //X 偏移量根据测试传感器的状态写入p d f29页Single_W rite_A DXL345(0x1F,0x00); //Y偏移量根据测试传感器的状态写入p d f29页Single_W rite_A DXL345(0x20,0x05); //Z 偏移量根据测试传感器的状态写入p d f29页}//显示x轴void display_x(){ float temp;dis_dat a=(BUF[1]<<8)+BUF[0]; //合成数据if(dis_dat a<0){dis_dat a=-dis_dat a;Display OneCha r(10,0,'-'); //显示正负符号位}else Display OneCha r(10,0,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversi on(temp); //转换出显示需要的数据Display OneCha r(8,0,'X');Display OneCha r(9,0,':');Display OneCha r(11,0,qian);Display OneCha r(12,0,'.');Display OneCha r(13,0,bai);Display OneCha r(14,0,shi);Display OneCha r(15,0,' ');}//*********************************************************************** //显示y轴void display_y(){ float temp;dis_dat a=(BUF[3]<<8)+BUF[2]; //合成数据if(dis_dat a<0){dis_dat a=-dis_dat a;Display OneCha r(2,1,'-'); //显示正负符号位}else Display OneCha r(2,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversi on(temp); //转换出显示需要的数据Display OneCha r(0,1,'Y'); //第1行,第0列显示yDisplay OneCha r(1,1,':');Display OneCha r(3,1,qian);Display OneCha r(4,1,'.');Display OneCha r(5,1,bai);Display OneCha r(6,1,shi);Display OneCha r(7,1,' ');}//显示z轴void display_z(){float temp;dis_dat a=(BUF[5]<<8)+BUF[4]; //合成数据if(dis_dat a<0){dis_dat a=-dis_dat a;Display OneCha r(10,1,'-'); //显示负符号位}else Display OneCha r(10,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversi on(temp); //转换出显示需要的数据Display OneCha r(8,1,'Z'); //第0行,第10列显示ZDisplay OneCha r(9,1,':');Display OneCha r(11,1,qian);Display OneCha r(12,1,'.');Display OneCha r(13,1,bai);Display OneCha r(14,1,shi);Display OneCha r(15,1,' ');}//*********************************************************//******主程序********//*********************************************************void main(){uchar devid;delay(500); //上电延时InitLcd(); //液晶初始化AD XL345Display OneCha r(0,0,'A');Display OneCha r(1,0,'D');Display OneCha r(2,0,'X');Display OneCha r(3,0,'L');Display OneCha r(4,0,'3');Display OneCha r(5,0,'4');Display OneCha r(6,0,'5');Init_AD XL345(); //初始化ADXL345devid=Single_Read_A DXL345(0X00); //读出的数据为0XE5,表示正确while(1) //循环{Multipl e_Read_ADXL345(); //连续读出数据,存储在BUF中display_x(); //---------显示X轴display_y(); //---------显示Y轴display_z(); //---------显示Z轴delay(200); //延时}}#include<reg52.h>#include<math.h>#include<stdio.h>#include<intrins.h>#defineuint unsigne d int#defineuchar unsigne d charuchar code shu[]={0xF8,0x04,0x04,0x04,0xF8,0x00,0x01,0x02,0x02,0x02,0x01,0x00, //00x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x02,0x03,0x02,0x00,0x00, //10x18,0x84,0x44,0x24,0x18,0x00,0x03,0x02,0x02,0x02,0x02,0x00, //20x08,0x04,0x24,0x24,0xD8,0x00,0x01,0x02,0x02,0x02,0x01,0x00, //30x40,0xB0,0x88,0xFC,0x80,0x00,0x00,0x00,0x00,0x03,0x02,0x00, //40x3C,0x24,0x24,0x24,0xC4,0x00,0x01,0x02,0x02,0x02,0x01,0x00, //50xF8,0x24,0x24,0x2C,0xC0,0x00,0x01,0x02,0x02,0x02,0x01,0x00, //60x0C,0x04,0xE4,0x1C,0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00, //70xD8,0x24,0x24,0x24,0xD8,0x00,0x01,0x02,0x02,0x02,0x01,0x00, //80x38,0x44,0x44,0x44,0xF8,0x00,0x00,0x03,0x02,0x02,0x01,0x00, //90x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x00, //. 100x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //- 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // 空白12 };uchar BUF[6]={0,0,0,0,0,0};int date;sbit SCL=P2^0; //IIC时钟引脚定义sbit SDA=P2^1; //IIC数据引脚定义sbit CE=P2^3; //片选sbit RES=P2^4; //复位sbit DC=P2^5; //数据1和命令0切换sbit DA TE=P2^6; //数据输入端sbit CLK=P2^7; //同步时钟输入端void init_5110();void init_S51();void write_b yte(uchar); //写入一个字节void write_a dd(uchar,uchar); //写位置地址void write_A(uchar);void write_B(uchar);void write_I D(uchar,uchar,uchar);void clear_5110();void delayms(uint);#defineSlaveAd dress0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS 地址引脚不同修改void Single_W rite_A DXL345(uchar REG_Add ress,uchar REG_dat a); //单个写入数据uchar Single_Read_A DXL345(uchar REG_Add ress); //单个读取内部寄存器数据void Multipl e_Read_ADXL345(); //连续的读取内部寄存器数据//------------------------------------void Init_AD XL345();void ADXL345_Start();void ADXL345_Stop();void ADXL345_SendA CK(bit ack);bit ADXL345_RecvA CK();void ADXL345_SendB yte(uchar dat);uchar ADXL345_RecvB yte();void ADXL345_ReadP age();void ADXL345_Write Page();//-----------------------------------void main(){uchar devid;delayms(500); //上电延时init_5110();write_I D(0,0,1);// write_I D(0,2,2);Init_AD XL345(); //初始化ADXL345 // 4.5MS devid=Single_Read_A DXL345(0X00); //读出的数据为0XE5,表示正确// delayms(2000);BUF[2]=0x7f;BUF[3]=1;while(1) //循环{Multipl e_Read_ADXL345(); //连续读出数据,存储在BUF中读数据时间2毫秒多Multipl e_Read_ADXL345(); //连续读出数据,存储在BUF中读数据时间2毫秒多delayms(2);write_I D(0,0,1);write_I D(0,2,2);write_I D(0,4,3);delayms(400); //延时// clear_5110();// delayms(1000);}}/**************************************起始信号**************************************/void ADXL345_Start(){uchar i;SDA = 1; //拉高数据线SCL = 1; //拉高时钟线for(i=2;i>0;i--); //延时5usSDA = 0; //产生下降沿for(i=2;i>0;i--); //延时5usSCL = 0; //拉低时钟线}/**************************************停止信号**************************************/void ADXL345_Stop(){uchar i;SDA = 0; //拉低数据线SCL = 1; //拉高时钟线for(i=2;i>0;i--); //延时5usSDA = 1; //产生上升沿for(i=2;i>0;i--); //延时5us}/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void ADXL345_SendA CK(bit ack){uchar i;SDA = ack; //写应答信号SCL = 1; //拉高时钟线for(i=2;i>0;i--); //延时5usSCL = 0; //拉低时钟线for(i=2;i>0;i--); //延时5us}/**************************************接收应答信号**************************************/bit ADXL345_RecvA CK(){uchar i;SCL = 1; //拉高时钟线for(i=2;i>0;i--); //延时5usCY = SDA; //读应答信号SCL = 0; //拉低时钟线for(i=2;i>0;i--); //延时5usreturnCY;}/**************************************向IIC总线发送一个字节数据**************************************/void ADXL345_SendB yte(uchar dat){uchar i,j;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY; //送数据口SCL = 1; //拉高时钟线for(j=2;j>0;j--); //延时5usSCL = 0; //拉低时钟线for(j=2;j>0;j--); //延时5us}ADXL345_RecvA CK();}/**************************************从IIC总线接收一个字节数据**************************************/uchar ADXL345_RecvB yte(){uchar i,j;uchar dat = 0;SDA = 1; //使能内部上拉,准备读取数据,for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线for(j=2;j>0;j--); //延时5usdat |= SDA; //读数据SCL = 0; //拉低时钟线for(j=2;j>0;j--); //延时5us}returndat;}//******单字节写入*******************************************void Single_Write_ADXL345(uchar REG_Add ress,uchar REG_dat a){ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(REG_Add ress); //内部寄存器地址,请参考中文pd f22页ADXL345_SendB yte(REG_data); //内部寄存器数据,请参考中文pd f22页ADXL345_Stop(); //发送停止信号}//********单字节读取*****************************************uchar Single_Read_A DXL345(uchar REG_Add ress){ uchar REG_dat a;ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(REG_Add ress); //发送存储单元地址,从0开始ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress+1); //发送设备地址+读信号REG_dat a=ADXL345_RecvB yte(); //读出寄存器数据ADXL345_SendA CK(1);ADXL345_Stop(); //停止信号returnREG_dat a;}//*********************************************************//连续读出ADX L345内部加速度数据,地址范围0x32~0x37//*********************************************************void Multipl e_read_ADXL345(void){ uchar i;ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress);//发送设备地址+写信号ADXL345_SendB yte(0x32); //发送存储单元地址,从0x32开始ADXL345_Start(); //起始信号ADXL345_SendB yte(SlaveAd dress+1); //发送设备地址+读信号for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF{BUF[i] = ADXL345_RecvB yte(); //BUF[0]存储0x32地址中的数据if (i == 5){ADXL345_SendA CK(1); //最后一个数据需要回NOACK }else{ADXL345_SendA CK(0); //回应ACK}}ADXL345_Stop(); //停止信号for(i=2;i>0;i--); //延时5us}//*****************************************************************//初始化ADXL345,根据需要请参考p df进行修改************************void Init_AD XL345(){Single_W rite_A DXL345(0x31,0x0B); //测量范围,正负16g,13位模式Single_W rite_A DXL345(0x2C,0x08); //速率设定为12.5 参考pdf13页Single_W rite_A DXL345(0x2D,0x08); //选择电源模式参考pdf24页Single_W rite_A DXL345(0x2E,0x80); //使能DA TA_READY中断Single_W rite_A DXL345(0x1E,0x00); //X 偏移量根据测试传感器的状态写入p d f29页Single_W rite_A DXL345(0x1F,0x00); //Y偏移量根据测试传感器的状态写入p d f29页Single_W rite_A DXL345(0x20,0x05); //Z 偏移量根据测试传感器的状态写入p d f29页}void init_5110(){RES=1; //可以没有RES=0;RES=1;DC=0;write_b yte(0x21);write_b yte(0xc8);write_b yte(0x20);write_b yte(0x0c);clear_5110();}void write_b yte(uchar add){uchar i;CE=0;for(i=0;i<8;i++){CLK=0;if(add&0x80)DA TE=1;elseDA TE=0;CLK=1;add<<=1;}CE=1;CLK=0;}void write_a dd(uchar x,uchar y) //横纵坐标X 0~83 Y 0~5{write_b yte(0x80|x); //横坐标write_b yte(0x40|y); //纵坐标}void clear_5110(){uint i;write_a dd(0,0);DC=1;for(i=0;i<504;i++){write_b yte(0x00); //wri te_b yte(0);}DC=0;}void write_I D(uchar x,uchar y,uchar z){uchar a;uint temp;if(z==1){date=(int)(BUF[1]<<8)+BUF[0];}if(z==2){date=(BUF[3]<<8)+BUF[2]; //}if(z==3){date=(BUF[5]<<8)+BUF[4];}if(date<0) // - 号{a=11;date=-date;}else{a=12;// date=date;}temp=(float)date*3.9; //计算数据和显示,查考ADXL345快速入门第4页// 空白// temp=(float)date*3.9; // 应该可以减少两个字节// temp=z;date=temp;/* temp=date;date=date/10;temp=temp*4+date; */// date=temp;write_a dd(x,y);DC=1;write_A(a);write_A(temp/10000);temp=temp%10000;write_A(temp/1000); temp=temp%1000;write_A(10); // 小数点write_A(temp/100);temp=temp%100;write_A(temp/10); temp=temp%10;write_A(temp);DC=0;temp=date; //确定temp值不发生变化write_a dd(x,y+1);DC=1;write_B(a);write_B(temp/10000);temp=temp%10000;write_B(temp/1000); temp=temp%1000;write_B(10); // 小数点write_B(temp/100);temp=temp%100;write_B(temp/10); temp=temp%10;write_B(temp);DC=0;}void write_A(uchar date){uchar i,m;m=date*12;for(i=0;i<6;i++){write_b yte(shu[m]);m++;}}void write_B(uchar date){uchar i,m;m=date*12+6;for(i=0;i<6;i++){write_b yte(shu[m]);m++;}}void delayms(uint a){uchar x,y;uint z;for(z=a;z>0;z--)for(x=2;x>0;x--)for(y=226;y>0;y--); }。
基于3轴加速度计ADXL345的全功能计步器设计
基于3轴加速度计ADXL345的全功能计步器设计摘要计步器是一种颇受欢迎的日常锻炼进度监控器,可以激励人们挑战自己,增强体质,帮助瘦身。
早期设计利用加重的机械开关检测步伐,并带有一个简单的计数器。
晃动这些装置时,可以听到有一个金属球来回滑动,或者一个摆锤左右摆动敲击挡块。
计步器功能可以根据计算人的运动情况来分析人体的健康状况。
而人的运动情况可以通过很多特性来进行分析。
比如人在运动时会产生加速度。
本文介绍了利用人运动时产生加速度变化来检测步数的计步器实现方案,利用具有体积小,功耗低,三轴高精度加速度传感器ADXL345,芯片内部即可把数据采集来的数据处理为数字数据,采集到加速度数据以后加以适当的算法就可以实现计步功能。
本文设计了一款基于加速度传感器ADXL345的计步器。
详细介绍了计步器的软件算法的实同时芯片中还集成了SPI和I²C接口,可以方便地将数据传输到主控芯片。
该系统设计简单,实现方便。
该芯片也可以扩展到其它需要测量加速度的应用场合,具有非常广阔的应用前景。
关键字:计步器加速度传感器ADXL345 低功耗Based on three accelerometer ADXL345 company-wide functionalpedometer designAbstractPedometer is a popular daily exercise, can inspire people progress monitors challenge yourself, enhanced physique, help thin body. Early design of mechanical switch detection using aggravated with a simple steps, and the counter. When shaking these devices, can hear a metal ball slide back and forth, or a pendulum swings around percussion block pieces.Pedometer function can according to the calculated a people's movement situation to analyze a healthy condition of body. But the person's movements can pass a lot of properties for analysis. Such as people in motion produces acceleration. This paper describes the use of people move to detect changes generated when the acceleration of steps, utilization of implementation scheme pedometer, small size, low power consumption, high ADXL345 three axis acceleration sensor, chip can put the data acquisition to internal data processing for the digital data acquisition to acceleration data, after appropriate algorithm can achieve plan step function. This paper introduces the design of a paragraph of the pedometer ADXL345 based on acceleration sensor. Introduces the software algorithm real pedometer while the SPI has integrated chip I²C interface, and I can be conveniently data transmission to the main control chip. The system is simple in design, realization convenient. The chip can also extend to other need to measure the applications, the acceleration is very broad application prospect.KEY WORDS pedometer acceleration sensor ADXL345 low power consumption目录中文摘要 (I)英文摘要 (II)1 绪论 (1)2 课题研究背景及意义 (2)2.1 光电计步器 (2)2.2基于射频技术的短跑训练计步器 (3)2.3 基于加速度传感器的计步器 (5)3 ADXL3XX系列产品简介及本次设计方案的提出 (5)3.1 ADXL335, ADXL345和ADXL346三轴加速度计的区别 (6)3.1.1 ADXL335的简介、特点及功能框图 (7)3.1.2 ADXL346的简介、特点及功能框图 (8)3.1.3 ADXL345的简介、特点及功能框图 (10)3.2 本次系统总体设计方案的提出 (13)3.2.1 ADXL345中断及寄存器功能分析 (13)3.2.2 系统总体设计方案 (15)4 系统硬件设计各模块电路 (16)4.1 传感器电路连接模块 (16)4.1.1 ADXL345的两种串行通信模式简介 (16)4.1.2 传感器模块连接 (18)4.2 微处理器模块 (19)4.3 EEPROM模块 (22)4.4 显示模块 (23)5 软件设计 (25)5.1 软件总体设计 (25)5.2 算法的实现 (26)6 结论 (32)致谢 (33)参考文献 (34)附录1 加速度计步器ADXL345简介 (36)附录2 整机电路图 (38)附录3 源程序 (38)1 绪论随着社会的发展,人们的物质生活水平日渐提高,人们也越来越关注自己的健康。
adxl345实用电路中文版
Rev.0“Circuits from the Lab” from Analog Devices have been designed and built by Analog Devices engineers. Standard engineering practices have been employed in the design and construction of each circuit, and their function and performance have been tested and verified in a lab environment at room temperature. However, you are solely responsible for testing the circuit and determining its suitability and applicability for your use and application. Accordingly, in no event shall Analog Devices be liable for direct, indirect, special, incidental, consequential or One Technology Way, P.O. Box 9106, Norwood, MA 02062-9106, U.S.A. Tel: 781.329.4700 电路笔记CN-0133连接/参考器件 利用ADI 公司产品进行电路设计3轴、±2 g /±4 g /±8 g /±16 g 数字加速度计ADXL345放心运用这些配套产品迅速完成设计。
欲获得更多信息和技术支持,请拨打4006-100-006或访问精密模拟微控制器,12位模拟I/O ,ARM7TDMI /zh/circuits 。
ADXL345编程
//********ADXL345.C#include <REG51.H>#include <math.h> //Keil library#include <INTRINS.H>#include<dingyi.h>#include<1602.h>#include<Reluctance.h>#include<xianshi.h>void main(){unsigned int i;delay(500);init_com();Init_ADXL345();while(1) //循环{delay(100);Multiple_read_SHEBEI(0xA6,0x32);display_x(); //---------显示X轴display_y(); //---------显示Y轴display_z(); //---------显示Z轴delay(100);}}//***********************xianshi.H//显示x轴void display_x(){ float temp;dis_data=(BUF[1]<<8)+BUF[0]; //合成数据X1=(float)dis_data*3.9/10000;if(dis_data<0){dis_data=-dis_data;DisplayOneChar(10,0,'-'); //显示正负符号位}else DisplayOneChar(10,0,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversion(temp); //转换出显示需要的数据DisplayOneChar(8,0,'X'); //第0行,第0列显示XDisplayOneChar(9,0,':');DisplayOneChar(11,0,qian);DisplayOneChar(12,0,'.');DisplayOneChar(13,0,bai);DisplayOneChar(14,0,shi);DisplayOneChar(15,0,'g');}//***********************************************************************//显示y轴void display_y(){ float temp;dis_data=(BUF[3]<<8)+BUF[2]; //合成数据Y1=(float)dis_data*3.9/10000;if(dis_data<0){dis_data=-dis_data;DisplayOneChar(2,1,'-'); //显示正负符号位}else DisplayOneChar(2,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversion(temp); //转换出显示需要的数据DisplayOneChar(0,1,'Y'); //第1行,第0列显示yDisplayOneChar(1,1,':');DisplayOneChar(3,1,qian);DisplayOneChar(4,1,'.');DisplayOneChar(5,1,bai);DisplayOneChar(6,1,shi);DisplayOneChar(7,1,'g');}//***********************************************************************//显示z轴void display_z(){ float temp;dis_data=(BUF[5]<<8)+BUF[4]; //合成数据Z1=(float)dis_data*3.9/10000;if(dis_data<0){dis_data=-dis_data;DisplayOneChar(10,1,'-'); //显示负符号位}else DisplayOneChar(10,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,查考ADXL345快速入门第4页conversion(temp); //转换出显示需要的数据DisplayOneChar(8,1,'Z'); //第0行,第10列显示Z DisplayOneChar(9,1,':');DisplayOneChar(11,1,qian);DisplayOneChar(12,1,'.');DisplayOneChar(13,1,bai);DisplayOneChar(14,1,shi);DisplayOneChar(15,1,'g');}/*void display(int k,uchar i,uchar m){if(k<0){k=-k;DisplayOneChar(i,m,'-'); //显示负符号位}else DisplayOneChar(i,m,' '); //显示空格conversion(k); //转换出显示需要的数据DisplayOneChar(i+1,m,qian);DisplayOneChar(i+2,m,'.');DisplayOneChar(i+3,m,bai);DisplayOneChar(i+4,m,shi);} *///*********************************************Reluctance.h***** void IIC_Start(){SDA = 1; //拉高数据线SCL = 1; //拉高时钟线Delay5us(); //延时SDA = 0; //产生下降沿Delay5us(); //延时SCL = 0; //拉低时钟线}/**************************************停止信号**************************************/void IIC_Stop(){SDA = 0; //拉低数据线SCL = 1; //拉高时钟线SDA = 1; //产生上升沿Delay5us(); //延时}/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void SHEBEI_SendACK(bit ack){SDA = ack; //写应答信号SCL = 1; //拉高时钟线Delay5us(); //延时SCL = 0; //拉低时钟线Delay5us(); //延时}/**************************************接收应答信号**************************************/bit SHEBEI_RecvACK(){SCL = 1; //拉高时钟线Delay5us(); //延时CY = SDA; //读应答信号SCL = 0; //拉低时钟线Delay5us(); //延时return CY;}/**************************************向IIC总线发送一个字节数据**************************************/void SHEBEI_SendByte(BYTE dat){BYTE i;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY; //送数据口SCL = 1; //拉高时钟线SCL = 0; //拉低时钟线Delay5us(); //延时}SHEBEI_RecvACK();}/**************************************从IIC总线接收一个字节数据**************************************/BYTE SHEBEI_RecvByte(){BYTE i;BYTE dat = 0;SDA = 1; //使能内部上拉,准备读取数据,for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线Delay5us(); //延时dat |= SDA; //读数据SCL = 0; //拉低时钟线Delay5us(); //延时}return dat;}//***************************************************void Single_Write_SHEBEI(uchar SlaveAddress,uchar REG_Address,uchar REG_data){IIC_Start(); //起始信号SHEBEI_SendByte(SlaveAddress); //发送设备地址+写信号SHEBEI_SendByte(REG_Address); //内部寄存器地址,请参考中文pdf SHEBEI_SendByte(REG_data); //内部寄存器数据,请参考中文pdf IIC_Stop(); //发送停止信号}////******************************************************void Multiple_read_SHEBEI(uchar SlaveAddress,uchar address){ uchar i;IIC_Start(); //起始信号SHEBEI_SendByte(SlaveAddress); //发送设备地址+写信号SHEBEI_SendByte(address); //发送存储单元地址,从0x32开始IIC_Start(); //起始信号SHEBEI_SendByte(SlaveAddress+1); //发送设备地址+读信号for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF{BUF[i] = SHEBEI_RecvByte(); //BUF[0]存储0x32地址中的数据if (i == 5){SHEBEI_SendACK(1); //最后一个数据需要回NOACK}else{SHEBEI_SendACK(0); //回应ACK}}IIC_Stop(); //停止信号Delay5ms();}void Init_ADXL345(){Single_Write_SHEBEI(0xA6,0x31,0x0B); //测量范围,正负16g,13位模式Single_Write_SHEBEI(0xA6,0x2C,0x08); //速率设定为12.5 参考pdf13页Single_Write_SHEBEI(0xA6,0x2D,0x08); //选择电源模式参考pdf24页Single_Write_SHEBEI(0xA6,0x2E,0x80); //使能DATA_READY 中断Single_Write_SHEBEI(0xA6,0x1E,0x00); //X 偏移量根据测试传感器的状态写入pdf29页Single_Write_SHEBEI(0xA6,0x1F,0x00); //Y 偏移量根据测试传感器的状态写入pdf29页Single_Write_SHEBEI(0xA6,0x20,0x05); //Z 偏移量根据测试传感器的状态写入pdf29页}//*****************************dingyi.h#define uchar unsigned char#define uint unsigned int#define DataPort P0 //LCD1602数据端口sbit SCL=P1^0; //IIC时钟引脚定义sbit SDA=P1^1; //IIC数据引脚定义sbit RS=P2^0; //LCD1602命令端口sbit RW=P2^1; //LCD1602命令端口sbit E=P2^2; //LCD1602命令端口//#define SlaveAddress 0x3C //定义器件在IIC总线中的从地址//uchar SlaveAddress;typedef unsigned char BYTE;typedef unsigned short WORD;BYTE BUF[8]; //接收数据缓存区uchar ge,shi,bai,qian,wan; //显示变量int dis_data;float X1;float Y1;float Z1;int x;int y;int z;int Hx;int Hy;//*************************************************************************************** **************void delay(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<121;j++){;}}}void Delay5us(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}void Delay5ms(){WORD n = 560;while (n--);}//************************************************************************************************ void conversion(uint temp_data){wan=temp_data/10000+0x30 ;temp_data=temp_data%10000; //取余运算qian=temp_data/1000+0x30 ;temp_data=temp_data%1000; //取余运算bai=temp_data/100+0x30 ;temp_data=temp_data%100; //取余运算shi=temp_data/10+0x30 ;temp_data=temp_data%10; //取余运算ge=temp_data+0x30;}//***********************1602.hvoid write_commend(uchar com){P0=com;RS=0;E=1;delay(2);E=0;}void write_data(uchar dat){P0=dat;RS=1;E=1;delay(2);E=0;}void write_string(uchar x,uchar y,uchar *s){if (y == 0){write_commend(0x80 + x); //表示第一行}else{write_commend(0xC0 + x); //表示第二行}while (*s){write_data( *s);s ++;}}void DisplayOneChar(uchar X,uchar Y,uchar DData) {Y&=1;X&=15;if(Y)X|=0x40;X|=0x80;write_commend(X);write_data(DData);}void init_com(){RW =0;delay(10);write_commend(0x02);delay(10);write_commend(0x38);delay(10);write_commend(0x38);delay(10);write_commend(0x38);write_commend(0x0c);write_commend(0x06);write_commend(0x01);write_commend(0x01);}以前玩过,手头没模块没测试。
adxl345使用手册
Measurement range is the level of acceleration supported by the sensor’s output signal specifications, typically specified in ±g. This is the greatest amount of acceleration the part can measure and accurately represent as an output. For example, the output of a ±3g accelerometer is linear with acceleration up to ±3g. If it is accelerated at 4g, the output may rail. Note that the breaking point is specified by the Absolute Maximum Acceleration, NOT by the measurement range. A 4g acceleration will not break a ±3g accelerometer.Sensitivity is the ratio of change in acceleration (input) to change in the output signal. This defines the ideal, straight-line relationship between acceleration and output (Figure 1, gray line). Sensitivity is specified at a particular supply voltage and is typically expressed in units of mV/g for analog-output accelerometers, LSB/g, or mg/LSB for digital-output accelerometers. It is usually specified in a range (min, typ, max) or as a typical figure and % deviation. For analog-output sensors, sensitivity is ratiometric to supply voltage; doubling the supply, for example, doubles the sensitivity.Sensitivity change due to Temperature is generally specified as a % change per °C. Temperature effects are caused by a combination of mechanical stresses and circuit temperature coefficients.Figure 1. Nonlinearity is a measurement of the deviation of an accelerometer response (illustrated in black) from a perfectly linear response (in gray). This graph is for illustration purposes only and does not show real accelerometer data. Nonlinearity: Ideally, the relationship between voltage and acceleration is linear and described by the sensitivity of the device. Nonlinearity is a measurement of deviation from a perfectly constant sensitivity, specified as a percentage with respect to either full-scale range (%FSR) or ± full scale (%FS). Typically, FSR = FS+FS. Nonlinearity of Analog Devices accelerometers is low enough that it can most often be ignored.Package Alignment Error is the angle between the accelerometer-sensing axes and the referenced package feature (see Figure 2). "Input Axis Alignment" is another term used for this error. The units for package alignment error are "degrees." Packaging technology typically aligns the die to within about 1° of the package.(Orthogonal) Alignment Error is the deviation from the ideal angular displacement (typically 90°) between multi-axis devices (see Figure 2). Analog Devices accelerometers are manufactured using photolithography on a single piece of silicon, so axis-to-axis alignment error is not generally a problem.Cross-axis sensitivity is a measure of how much output is seen on one axis when acceleration is imposed on a different axis, typically specified as a percentage. The coupling between two axes results from a combination of alignment errors, etching inaccuracies, and circuit crosstalk.Zero-g Bias Level specifies the output level when there is no acceleration (zero input). Analog sensors typically express this in volts (or mV) and digital sensors in codes (LSB). Zero-g Bias is specified at a particular supply voltage and is typically ratiometric with supply voltage (most often, zero-g bias is nominally half the supply voltage).Several aspects of zero-g bias are often specified:∙Zero-g Voltage, in V, specifies the range of voltages that may be expected at the output under 0g of acceleration.∙Output Deviation from Ideal, also called Initial Bias Error, is specified at 25°C, either in terms of acceleration error (g) or output signal: mV for analog sensors and LSB for digital sensors.∙Zero-g Offset vs. Temperature, or Bias Temperature Coefficient, in m g/°C, describes how much the output shifts for each °C temperature change; and∙Bias Voltage Sensitivity is the change in "Zero-Bias Level" with respect to change in power supply. The units for this parameter are typically, mv/V, mg/V, or LSB/V.∙Zero-g Total Error includes all errors.Noise Density, in u g/rt(Hz) RMS, is the square root of the power spectral density of the noise output. Total noise is determined by the equation:Noise = Noise Density * sqrt(BW * 1.6)where BW is the accelerometer bandwidth, set by capacitors on the accelerometer outputs.Analog Devices accelerometers' noise is Gaussian and uncorrelated, so noise can be reduced by averaging the outputs from several accelerometers. supply voltage (most often, zero-g bias is nominally half the supply voltage).Total Noise is the random deviation from the ideal output and is equal to the multiplied product of the Noise Density and the square root of the Noise Bandwidth. The units for this parameter are typicallym g-RMS.Figure 2. Showing package alignment error α and sensor alignment error θ. α is the angle between the sensor axes and the package axes. θ is the deviation of the sensor axes from orthogonal, i.e., the difference between (ysensor – xsensor) and 90°.Output Data Rate, in digital-output accelerometers, defines the rate at which data is sampled. Bandwidth is the highest frequency signal that can be sampled without aliasing by the specified Output Data Rate. Per the Nyquist sampling criterion, bandwidth is half the Output Data Rate.In analog-output accelerometers, bandwidth is defined as the signal frequency at which the response falls to -3dB of the response to DC (or low-frequency) acceleration.。
adxl345的STM32驱动程序和硬件设计
adxl345的STM32驱动程序和硬件设计⼀、硬件电路接⼝图⽚1.ADXL345硬件接⼝图⽚使⽤的是SPI端⼝进⾏通信,这样读取数据⽐较快且后续也可以转化为IIC通信接⼝。
在⽹上找⼀些发现IIC接⼝的⽐较多,所以本⼈就DIY做SPI的通信。
2.STM32F103T系列单⽚机作为MCU 资源⽐较丰富、本⼈⽐较熟悉开发速度较快硬件电路⾸先是为了实现功能,所以设计⽐较简单。
后续⼩编想做⽆线蓝⽛的数据传输,所以硬件上也留了蓝⽛串⼝通信的硬件接⼝和3.3V电源管理。
⼆、单⽚机驱动代码1.ADXL345的端⼝配置函数#define ADXL345_FLAG_TIMEOUT ((uint32_t)0x1000)#define ADXL345_SPI SPI1#define ADXL345_SPI_CLK RCC_APB2Periph_SPI1#define ADXL345_SPI_SCK_PIN GPIO_Pin_5#define ADXL345_SPI_SCK_GPIO_PORT GPIOA#define ADXL345_SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_SCK_SOURCE GPIO_PinSource5#define ADXL345_SPI_SCK_AF GPIO_AF_5#define ADXL345_SPI_MISO_PIN GPIO_Pin_6#define ADXL345_SPI_MISO_GPIO_PORT GPIOA#define ADXL345_SPI_MISO_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_MISO_SOURCE GPIO_PinSource6#define ADXL345_SPI_MISO_AF GPIO_AF_5#define ADXL345_SPI_MOSI_PIN GPIO_Pin_7#define ADXL345_SPI_MOSI_GPIO_PORT GPIOA#define ADXL345_SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_MOSI_SOURCE GPIO_PinSource7#define ADXL345_SPI_MOSI_AF GPIO_AF_5#define ADXL345_SPI_CS_PIN GPIO_Pin_2#define ADXL345_SPI_CS_GPIO_PORT GPIOB#define ADXL345_SPI_CS_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT1_PIN GPIO_Pin_0#define ADXL345_SPI_INT1_GPIO_PORT GPIOB#define ADXL345_SPI_INT1_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT1_EXTI_LINE EXTI_Line0#define ADXL345_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB#define ADXL345_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0#define ADXL345_SPI_INT1_EXTI_IRQn EXTI0_IRQn#define ADXL345_SPI_INT2_PIN GPIO_Pin_1#define ADXL345_SPI_INT2_GPIO_PORT GPIOB#define ADXL345_SPI_INT2_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT2_EXTI_LINE EXTI_Line1#define ADXL345_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB #define ADXL345_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1#define ADXL345_SPI_INT2_EXTI_IRQn EXTI1_IRQn#define ADXL345_WHO_AM_I_ADDR 0x0F#define ADXL345_CTRL_REG1_ADDR 0x20#define ADXL345_CTRL_REG2_ADDR 0x21#define ADXL345_CTRL_REG3_ADDR 0x22#define ADXL345_CTRL_REG4_ADDR 0x23#define ADXL345_CTRL_REG5_ADDR 0x24#define ADXL345_REFERENCE_REG_ADDR 0x25#define ADXL345_OUT_TEMP_ADDR 0x26#define ADXL345_STATUS_REG_ADDR 0x27#define ADXL345_OUT_X_L_ADDR 0x28#define ADXL345_OUT_X_H_ADDR 0x29#define ADXL345_OUT_Y_L_ADDR 0x2A#define ADXL345_OUT_Y_H_ADDR 0x2B#define ADXL345_OUT_Z_L_ADDR 0x2C#define ADXL345_OUT_Z_H_ADDR 0x2D#define ADXL345_FIFO_CTRL_REG_ADDR 0x2E#define ADXL345_FIFO_SRC_REG_ADDR 0x2F#define ADXL345_INT1_CFG_ADDR 0x30#define ADXL345_INT1_SRC_ADDR 0x31#define ADXL345_INT1_TSH_XH_ADDR 0x32#define ADXL345_INT1_TSH_XL_ADDR 0x33#define ADXL345_INT1_TSH_YH_ADDR 0x34#define ADXL345_INT1_TSH_YL_ADDR 0x35#define ADXL345_INT1_TSH_ZH_ADDR 0x36#define ADXL345_INT1_TSH_ZL_ADDR 0x37#define ADXL345_INT1_DURATION_ADDR 0x38#define I_AM_ADXL345 ((uint8_t)0xD4)#define ADXL345_MODE_POWERDOWN ((uint8_t)0x00)#define ADXL345_MODE_ACTIVE ((uint8_t)0x08)#define ADXL345_OUTPUT_DATARATE_1 ((uint8_t)0x00)#define ADXL345_OUTPUT_DATARATE_2 ((uint8_t)0x40)#define ADXL345_OUTPUT_DATARATE_3 ((uint8_t)0x80)#define ADXL345_OUTPUT_DATARATE_4 ((uint8_t)0xC0)#define ADXL345_X_ENABLE ((uint8_t)0x02)#define ADXL345_Y_ENABLE ((uint8_t)0x01)#define ADXL345_Z_ENABLE ((uint8_t)0x04)#define ADXL345_AXES_ENABLE ((uint8_t)0x07)#define ADXL345_AXES_DISABLE ((uint8_t)0x00)#define ADXL345_BANDWIDTH_1 ((uint8_t)0x00)#define ADXL345_BANDWIDTH_2 ((uint8_t)0x10)#define ADXL345_BANDWIDTH_3 ((uint8_t)0x20)#define ADXL345_BANDWIDTH_4 ((uint8_t)0x30)#define ADXL345_FULLSCALE_250 ((uint8_t)0x00)#define ADXL345_FULLSCALE_500 ((uint8_t)0x10)#define ADXL345_FULLSCALE_2000 ((uint8_t)0x20)#define ADXL345_BlockDataUpdate_Continous ((uint8_t)0x00) #define ADXL345_BlockDataUpdate_Single ((uint8_t)0x80)#define ADXL345_BLE_LSB ((uint8_t)0x00)#define ADXL345_BLE_MSB ((uint8_t)0x40)#define ADXL345_HIGHPASSFILTER_DISABLE ((uint8_t)0x00) #define ADXL345_HIGHPASSFILTER_ENABLE ((uint8_t)0x10)#define ADXL345_INT1INTERRUPT_DISABLE ((uint8_t)0x00) #define ADXL345_INT1INTERRUPT_ENABLE ((uint8_t)0x80)#define ADXL345_INT2INTERRUPT_DISABLE ((uint8_t)0x00) #define ADXL345_INT2INTERRUPT_ENABLE ((uint8_t)0x08)#define ADXL345_INT1INTERRUPT_LOW_EDGE ((uint8_t)0x20)#define ADXL345_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00)#define ADXL345_BOOT_NORMALMODE ((uint8_t)0x00)#define ADXL345_BOOT_REBOOTMEMORY ((uint8_t)0x80)#define ADXL345_HPM_NORMAL_MODE_RES ((uint8_t)0x00)#define ADXL345_HPM_REF_SIGNAL ((uint8_t)0x10)#define ADXL345_HPM_NORMAL_MODE ((uint8_t)0x20)#define ADXL345_HPM_AUTORESET_INT ((uint8_t)0x30)#define ADXL345_HPFCF_0 0x00#define ADXL345_HPFCF_1 0x01#define ADXL345_HPFCF_2 0x02#define ADXL345_HPFCF_3 0x03#define ADXL345_HPFCF_4 0x04#define ADXL345_HPFCF_5 0x05#define ADXL345_HPFCF_6 0x06#define ADXL345_HPFCF_7 0x07#define ADXL345_HPFCF_8 0x08#define ADXL345_HPFCF_9 0x09#define ADXL345_CS_LOW() GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN) #define ADXL345_CS_HIGH() GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN)void ADXL345_Init(ADXL345_InitTypeDef *ADXL345_InitStruct);void ADXL345_RebootCmd(void);void ADXL345_INT1InterruptCmd(uint8_t InterruptState);void ADXL345_INT2InterruptCmd(uint8_t InterruptState);void ADXL345_INT1InterruptConfig(ADXL345_InterruptConfigTypeDef *ADXL345_IntConfigStruct);uint8_t ADXL345_GetDataStatus(void);void ADXL345_FilterConfig(ADXL345_FilterConfigTypeDef *ADXL345_FilterStruct);void ADXL345_FilterCmd(uint8_t HighPassFilterState);void ADXL345_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);void ADXL345_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead);2.ADXL345的SPI配置函数void SPI_init(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(ADXL345_SPI_CLK ,ENABLE);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_CS_PIN ;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADXL345_SPI_CS_GPIO_PORT, &GPIO_InitStructure);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT,ADXL345_SPI_CS_PIN);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_SCK_PIN|ADXL345_SPI_MISO_PIN|ADXL345_SPI_MOSI_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADXL345_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode=SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial=7;SPI_Init(ADXL345_SPI, &SPI_InitStructure);SPI_Cmd(ADXL345_SPI,ENABLE);}3.ADXL345初始化配置函数void ADXL345_init(void){SPI_init(); //ADXL345¶Ë¿Ú³õʼ»¯ÅäÖÃSPIͨÐÅADXL345_write_byte(0x1E,0x00); //X Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x1F,0x00); //Y Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x20,0x00); //Z Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x21,0x00); //Çû÷ÑÓʱ0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x22,0x00); //¼ì²âµÚÒ»´ÎÇû÷ºóµÄÑÓʱ0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x23,0x00); //Çû÷´°¿Ú0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x24,0x01); //±£´æ¼ì²â»î¶¯·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x25,0x01); //±£´æ¼ì²â¾²Ö¹·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x26,0x2B); //¼ì²â»î¶¯Ê±¼ä·§Öµ; (1s/LSB)ADXL345_write_byte(0x27,0x00); //ADXL345_write_byte(0x28,0x09); //×ÔÓÉÂäÌå¼ì²âÍƼö·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x29,0xFF); //×ÔÓÉÂäÌå¼ì²âʱ¼ä·§Öµ,ÉèÖÃΪ×î´óʱ¼ä; (5ms/LSB)ADXL345_write_byte(0x2A,0x80); ////ADXL345_read_byte(0x2B); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡ADXL345_write_byte(0x2C,0x0F); //ËÙÂÊÉ趨Ϊ3200HZ²Î¿¼pdf13Ò³ 0X0A 1OO,0X0E 1600HZADXL345_write_byte(0x2D,0x08); //Ñ¡ÔñµçԴģʽ¹Ø±Õ×Ô¶¯ÐÝÃß,ÐÝÃß,»½Ðѹ¦Äܲο¼pdf24Ò³ADXL345_write_byte(0x2E,0x80); //ʹÄÜ DATA_READY ÖжÏADXL345_write_byte(0x2F,0x00);//ADXL345_read_byte(0x30); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡ADXL345_write_byte(0x31,0X0B);//Êý¾ÝͨПñʽ;ÉèÖÃΪ×Լ칦ÄܽûÓÃ,4ÏßÖÆSPI½Ó¿Ú,µÍµçƽÖжÏÊä³ö,13λȫ·Ö±æÂÊ,Êä³öÊý¾ÝÓÒ¶ÔÆë,16gÁ¿³Ì ADXL345_write_byte(0x38,0x00); //FIFOģʽÉ趨,Streamģʽ£¬´¥·¢Á¬½ÓINT1,31¼¶Ñù±¾»º³å//ADXL345_read_byte(0x39); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡}4.ADXL345的读写函数u8 ADXL345_read_byte(u8 add){GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_SendData(ADXL345_SPI,(add|0x80)<<8|0x00);while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);return SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;}void ADXL345_write_byte(u8 add,u8 val){GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_SendData(ADXL345_SPI,add<<8|val);while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;}void ADXL345_ReadXYZ(float *g){uint8_t BUF[6]; // ´æ·ÅX,Y,ZÖáµÄÊý¾Ýint16_t temp;BUF[0] = ADXL345_read_byte(0x32);BUF[1] = ADXL345_read_byte(0x33);delay_ms(1);BUF[2] = ADXL345_read_byte(0x34);BUF[3] = ADXL345_read_byte(0x35);delay_ms(1);BUF[4] = ADXL345_read_byte(0x36);BUF[5] = ADXL345_read_byte(0x37);delay_ms(1);temp = (BUF[1] << 8) + BUF[0];if(temp < 0)temp = -temp;g[0] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³temp = (BUF[3] << 8) + BUF[2];if(temp < 0)temp = -temp;g[1] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³temp = (BUF[5] << 8) + BUF[4];if(temp < 0)temp = -temp;g[2] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³}。
基于单片机的智能计步器的设计
基于单片机的智能计步器的设计作者:袁宏彭森来源:《卷宗》2017年第36期摘要:计步器是近年来才兴起的监控运动量的监控器,它可以让人们知道自己一天到底走了多少步,运动量有多少,从而了解自己的运动量和身体健康指数,以往的计步器都是利用金属球或者金属块来敲击内部的一个硬块,然后得到信号,步数增加,计步器功能可以根据计算人的运动情况来分析人体的运动量。
而人的运动情况可以通过不同特性来进行分析。
与传统的机械式传感器不同,ADXL345是电容式三轴传感器,由它得到人体运动时加速度信号,更加精准。
信号通过低通滤波器滤波,由单片机内置A/D转换器对信号进行采样、A/D转换。
软件采用相应的算法实现计步功能,减少错误率,更加精确。
单片机STC89C51控制液晶显示计步状态。
其工作电流只有1-1.5mA,实现非常低的功耗。
关键词:计步器;加速度传感器;ADXL345;低功耗1引言随着二十一世纪,随着经济的飞速发展,人们生活的越来越好,从而使人越来越懒,也导致了疾病的发生率也变高了。
所以,人们越来越关注自己的健康问题,通过锻炼可以减少疾病的产生,因此计步器应此而生,就成了当下受欢迎的趋势。
走路时,通过步行使全身都得到运动。
经常步行和跑步运动的人一般不会患高血压或低血压病。
也能使得自身获得一个非常强的体制,坚持运动能增强体制也能减少身体器官的负担,还能塑性,拥有坚强的体魄。
而基于单片机为核心控制的计步器有着稳定,方便,精确,可靠等优点,很受欢迎。
通过计步器我们可以了解自己走了多少步,掌握自己的锻炼情况及运动量。
2工作原理本系统采用单片机STC89C51作为本设计的核心元件。
计步器分为几部分,由复位电路、显示电路、按键电路以及振荡电路几个部分组成。
系统结构图如下图所示。
3电路设计AT89C51单片机内设有一个由反向放大器所构成的振荡电路,振荡器要正常工作就需要起振,我们一般都是使用石英晶体的振荡器,这款振荡器是以前接触过的,它的电路一般在3V左右起振信号,还有不同的振荡器的频率也各不相同,所以不同的振荡器有不同的结果。
ADXL345经验总结,采用SPI和I2C总线操作
ADXL345经验总结,采⽤SPI和I2C总线操作⼀、 ADXL345简介ADXL345是ADI公司推出的三轴(x,y,z)iMEMS数字加速度计(digital accelerometer ),具有在16G下⾼分辨率(13Bit)测量能⼒,同时具备16Bit数字输出。
ADXL345 适⽤于静态倾⾓测量以及动态加速度测量,⾼达4mg/LSB的灵敏度允许测量⼩于1度的倾⾓。
该传感器还具备单击 /双击探测,⾃由落体探测,并允许⽤户设置⼀个加速度阀值,当加速度值超过设定阀值后可以产⽣⼀个信号输出。
所有这些功能都可以映射到2个中断上。
内置的32级FIFO缓存可以极⼤的缓解处理器的压⼒。
特点:2.0 -3.6VDC供电电压超低功耗: 40uA的测量模式, 0.1uA在standby@2.5V单击/双击检测⾃由落体检测⽤户阀值设定SPI和I2C接⼝ADXL345以+2.5V的电源电压⼯作时的消耗电流控制为标准25µ~130µA。
该产品可⽐与3轴惯性传感器节约80%的耗电量。
主要⾯向⼿机、便携式游戏机、游戏机控制器以及PND等。
还⽀持硬盘的跌落检测等。
可检测的加速度范围为±2/4/8/16G。
集成了FIFO(First-in, First-out)型存储器,最多可存储32组3轴数据。
耐冲击性为1万G。
输出接⼝备有I2C和SPI。
数据输出速度为0.1~3.2kHz。
电源电压(Vs)为+2.0~3.6V,接⼝部分为+1.8V~Vs。
⼯作温度范围为-40~+85℃。
封装采⽤14端⼦的LFCSP。
⼆、 SPI-4线模式操作ADXL345内部寄存器编程要点1.ADXL345 SPI-4线模式的硬件连接电路SPI-4线模式是adxl345默认的操作总线,⽆需配置即可⽤。
,详见datasheet page25 DAT A_FORMAT寄存器。
2.关于ADXL345的PI总线协议与标准的SPI协议的⼀些差异(标准的SPI协议可以参考这⾥不做详细介绍)标准的SPI总线时序中,每个字节之间的操作是断开的,即⽚选线SS_n和串⾏时钟线SCLK 正在传输该字节时有效,其余时刻保持⽆效状态(即SS_n=1,SCLK=1)如下图:ADXL345 datasheet中要求clock polarity (CPOL) = 1 and clock phase (CPHA) = 1,这可以在SOPC中选择SPI IP核作为nios2外设构建系统时,⽤GUI的⽅式⽅便的设置,其SPI操作的时序如下图:从图中可以看到:SPI总线对ADXL345内部寄存器的读写操作都是以字节为单位进⾏的(这是由ADXL345内部30个可操作寄存器均为字节寄存器所决定的),然⽽每两个字节数据/地址之间CS_n和SCLK⼀直需要保持有效。
(完整版)三轴数字加速度传感器ADXL345技术资料
概述:ADXL345 是一款小而薄的超低功耗3 轴加速度计,分辨率高(13 位),测量范围达± 16g。
数字输出数据为16 位二进制补码格式,可通过SPI(3 线或4 线)或I2C 数字接口访问。
ADXL345 非常适合移动设备应用。
它可以在倾斜检测应用中测量静态重力加速度,还可以测量运动或冲击导致的动态加速度。
其高分辨率(3.9mg/LSB),能够测量不到1.0°的倾斜角度变化。
该器件提供多种特殊检测功能。
活动和非活动检测功能通过比较任意轴上的加速度与用户设置的阈值来检测有无运动发生。
敲击检测功能可以检测任意方向的单振和双振动作。
自由落体检测功能可以检测器件是否正在掉落。
这些功能可以独立映射到两个中断输出引脚中的一个。
正在申请专利的集成式存储器管理系统采用一个32 级先进先出(FIFO)缓冲器,可用于存储数据,从而将主机处理器负荷降至最低,并降低整体系统功耗。
低功耗模式支持基于运动的智能电源管理,从而以极低的功耗进行阈值感测和运动加速度测量。
ADXL345 采用3 mm × 5 mm × 1 mm,14 引脚小型超薄塑料封装。
对比常用的飞思卡尔的MMZ7260三轴加速度传感器,ADXL345,具有测量精度高、可以通过SPI或I2C 直接和单片机通讯等优点。
特性:超低功耗:VS= 2.5 V 时(典型值),测量模式下低至23uA,待机模式下为0.1μA 功耗随带宽自动按比例变化用户可选的分辨率10 位固定分辨率全分辨率,分辨率随g 范围提高而提高,±16g 时高达13 位(在所有g 范围内保持4 mg/LSB 的比例系数)正在申请专利的嵌入式存储器管理系统采用FIFO 技术,可将主机处理器负荷降至最低。
单振/双振检测,活动/非活动监控,自由落体检测电源电压范围:2.0 V 至3.6 VI / O 电压范围:1.7 V 至VSSPI(3 线和4 线)和I2C 数字接口灵活的中断模式,可映射到任一中断引脚通过串行命令可选测量范围通过串行命令可选带宽宽温度范围(-40°C 至+85℃)抗冲击能力:10,000 g无铅/符合RoHS 标准小而薄:3 mm× 5 mm× 1 mm,LGA 封装模组尺寸:23*18*11mm(高度含插针高度应用:机器人控制、运动检测过程控制,电池供电系统硬盘驱动器(HDD)保护,单电源数据采集系统手机,医疗仪器,游戏和定点设备,工业仪器仪表,个人导航设备电路功能与优势ADXL345是一款小巧纤薄的低功耗三轴加速度计,可以对高达±16 g的加速度进行高分辨率(13位)测量。
基于3轴加速度计ADXL345的全功能计步器设计
基于3轴加速度计ADXL345的全功能计步器设计简介计步器是一种颇受欢迎的日常锻炼进度监控器,可以激励人们挑战自己,增强体质,帮助瘦身。
早期设计利用加重的机械开关检测步伐,并带有一个简单的计数器。
晃动这些装置时,可以听到有一个金属球来回滑动,或者一个摆锤左右摆动敲击挡块。
如今,先进的计步器利用MEMS(微机电系统)惯性传感器和复杂的软件来精确检测真实的步伐。
MEMS惯性传感器可以更准确地检测步伐,误检率更低。
MEMS惯性传感器具有低成本、小尺寸和低功耗的特点,因此越来越多的便携式消费电子设备开始集成计步器功能,如音乐播放器和手机等。
ADI公司的3轴加速度计ADXL335, ADXL345和 ADXL346小巧纤薄,功耗极低,非常适合这种应用。
本文以对步伐特征的研究为基础,描述一个采用3轴图1. 各轴的定义让我们考虑步行的特性。
图2描绘了一个步伐,我们将其定义为单位步行周期,图中显示了步行周期各阶段与竖向和前向加速度变化之间的关系。
图2. 步行阶段与加速度模式图3显示了与一名跑步者的竖向、前向和侧向加速度相对应的x、y和z轴测量结果的典型图样。
无论如何穿戴计步器,总有至少一个轴具有相对较大的周期性加速度变化,因此峰值检测和针对所有三个轴上的加速度的动态阈值决策算法对于检测单位步行或跑步周期至关重要。
图3. 从一名跑步者测得的x、y和z轴加速度的典型图样算法步伐参数数字滤波器:首先,为使图3所示的信号波形变得平滑,需要一个数字滤波器。
可以使用四个寄存器和一个求和单元,如图4所示。
当然,可以使用更多寄存器以使加速度数据更加平滑,但响应时间会变慢。
图4. 数字滤波器图5显示了来自一名步行者所戴计步器的最活跃轴的滤波数据。
对于跑步者,峰峰值会更高。
图5. 最活跃轴的滤波数据动态阈值和动态精度:系统持续更新3轴加速度的最大值和最小值,每采样50次更新一次。
平均值(Max + Min)/2称为“动态阈值”。
接下来的50次采样利用此阈值判断个体是否迈出步伐。
ADXL345快速使用指南
ADXL345快速运用指南作者 zagGard 2011年1月10日描述:ADXL345是一款体型小而轻薄的超低功耗3轴加速度计,分辨率高13位,测量范围± 16g。
数字输出数据为16位二进制补码格式,可通过SPI(3线或4线)或I2C 数字接口访问。
ADXL345非常适合应用于移动设备。
它可以在倾斜检测应用中测量静态重力加速度,还可以测量运动或冲击导致的动态加速度。
其高分辨率为4mg/LSB,能够测量不到1.0°的倾斜角度变化。
该器件提供多种特殊检测功能。
活动和非活动检测功能通过比较任意轴上的加速度与用户设置的阈值来检测有无运动发生。
敲击检测功能可以检测任意方向的单振和双振动作。
自由落体检测功能可以检测器件是否正在掉落。
这些功能可以独立映射到两个中断输出引脚中的一个。
正在申请专利的集成式存储器管理系统采用一个32级先进先出(FIFO)缓冲器,可用于存储数据,从而将主机处理器负荷降至最低,并降低整体系统功耗。
低功耗模式支持基于运动的智能电源管理,从而以极低的功耗进行阈值感测和运动加速度测量。
特征:2.0-3.6V直流供电超低功耗:测量模式时40uA,待机时0.1uA@2.5V单振/双振检测自由落体检测SPI和I2C数字接口数据传输:这部分的指南说明了如何把Arduino ADXL345连接到面包板。
下面是一个描述Arduino引脚应该连接到的加速度计引脚的表:初学者的示例代码:让我们看一个获得ADXL345和Arduino运行的示例。
你可以在这里下载完整的代码。
下面我们将检查该代码的不同部分。
这是代码的初始化部分,这真的非常基本,这里是正在发生的。
SPI.h库被添加到程序。
SPI是Arduino使用于传达给ADLX345的通信协议,一个名为CS的变量存储片选信号的针数,是为ADXL345寄存器创建的变量,这些变量存储的指示的寄存器的地址和用于从加速计设置和检索的值。
数据表显示所有可用的ADXL345及其地址寄存器。
角度传感器ADXL345程序代码(AVR)
} else { Send_DATA('+'); } Temp=(float)Dis_data*3.9; Temp_x=Temp; } /*Y 轴*/ void Display_Y(void) { float Temp; Dis_data=(Re_data[3]<<8)+Re_data[2]; Send_COM(0x84); if(Dis_data<0) { Dis_data=-Dis_data; Send_DATA('-'); } else { Send_DATA('+'); } Temp=(float)Dis_data*3.9; Temp_y=Temp; } /*Z 轴*/ void Display_Z(void) { float Temp; Dis_data=(Re_data[5]<<8)+Re_data[4]; Send_COM(0x91); if(Dis_data<0) { Dis_data=-Dis_data; Send_DATA('-'); } else { Send_DATA('+'); } Temp=(float)Dis_data*3.9; Temp_z=Temp; }
Order=Data; Order<<=4; for(i=0;i<8;i++) { if(Order&0x80) SID_set; else SID_clr; SCLK_clr; SCLK_set; Order<<=1; } CS_clr; Delay(20); } /*显示一字符串*/ void Dis_str(uchar Addr,uchar *str) { Send_COM(Addr); Delay(100); while(*str!='\0') { Send_DATA(*str); str++; Delay(20); } } /*LCD12232 初始化*/ void Init_LCD(void) { Delay(2000); Send_COM(0x06); Delay(200); Send_COM(0x02); Delay(200); Send_COM(0x0c); Delay(200); Send_COM(0x80); Delay(200); Send_COM(0x30); Delay(200); Send_COM(0x01); Delay(2000); }
手势控制的程序(ADXL345加速度传感器)
}
}
/*******************************/
void Delay20ms()//@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 1;
j = 216;
k = 35;
do
{
do
{
while (--k);
} while (--j);
**************************************/
void Delay5us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
接收应答信号
**************************************/
bit ADXL345_RecvACK()
{
SCL = 1; //拉高时钟线
Delay5us(); //延时
CY = SDA; //读应答信号
SCL = 0; //拉低时钟线
Delay5us(); //延时
return CY;
ADXL345_SendByte(REG_Address); //发送存储单元地址,从0开始
ADXL345_Start(); //起始信号
ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号
基于ADXL345的超低功耗倾角测量仪的设计
基于ADXL345的超低功耗倾角测量仪的设计肖茜;陈庆【期刊名称】《电脑知识与技术》【年(卷),期】2014(000)016【摘要】该文完成一款基于ADXL345三轴加速度传感器设计的超低功耗倾角测量仪。
系统采用Msp430F413作为控制核心,系统包括ADXL345倾角测量电路、段式液晶显示电路等,对其硬件电路和软件进行了完整设计,通过调试测试,该测量仪倾角测量范围0到90度,设计小巧新颖,集成度高。
%In this paper, based on the completion of a three-axis accelerometer ADXL345 ultra-low power design angle mea-surement instrument. System uses Msp430F413 as the control system including ADXL345 angle measurement circuitry, segment LCD circuits, etc., for the complete design of its hardware and software, through commissioning tests, the gauge angle measure-ment range of 0 to 90 degrees, compact design novel high integration.【总页数】4页(P3923-3925,3932)【作者】肖茜;陈庆【作者单位】长沙理工大学,湖南长沙410004;湖南铁道职业技术学院,湖南株洲412001【正文语种】中文【中图分类】TN492【相关文献】1.超低功耗倾角测量仪的设计 [J], 穆伟平;马文忠;赵仁德;李震;包学菠2.超低功耗倾角测量仪的设计 [J], 张昌州;史小明;3.基于Cortex M0+的超低功耗多路高精度数字频率测量仪的设计 [J], 王静;郑晖晖4.超低功耗倾角测量仪的设计与研究 [J], 张彦宇5.一种基于MEMS倾角测量仪的设计与验证 [J], 李冰;韩彦东因版权原因,仅展示原文概要,查看原文内容请购买。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//起始信号 //发送设备地址+读信号 //连续读取 6 个地址数据,存储中 BUF //BUF[0]存储 0x32 地址中的数据
//最后一个数据需要回 NOACK
//回应 ACK
//停止信号
//初始化 ADXL345,根据需要请参考 pdf 进行修改************************ void Init_ADXL345() { Single_Write_ADXL345(0x31,0x0B); //测量范围,正负 16g,13 位模式 Single_Write_ADXL345(0x2C,0x08); //速率设定为 12.5 参考 pdf13 页 Single_Write_ADXL345(0x2D,0x08); //选择电源模式 参考 pdf24 页 Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中断 Single_Write_ADXL345(0x1E,0x00); //X 偏移量 根据测试传感器的状态写入 pdf29 页 Single_Write_ADXL345(0x1F,0x00); //Y 偏移量 根据测试传感器的状态写入 pdf29 页 Single_Write_ADXL345(0x20,0x05); //Z 偏移量 根据测试传感器的状态写入 pdf29 页 } void conversion(int temp_data) { wan=temp_data/10000+0x30 ; temp_data=temp_data%10000; qian=temp_data/1000+0x30 ; temp_data=temp_data%1000; bai=temp_data/100+0x30 ; temp_data=temp_data%100; shi=temp_data/10+0x30 ; temp_data=temp_data%10; ge=temp_data+0x30; }
//******单字节写入******************************************* void Single_Write_ADXL345(uchar REG_Address,uchar REG_data) { start(); //起始信号 write1byte(SlaveAddress); //发送设备地址+写信号 cack(); write1byte(REG_Address); //内部寄存器地址,请参考中文 pdf22 页 cack(); write1byte(REG_data); //内部寄存器数据,请参考中文 pdf22 页 cack(); stop(); //发送停止信号 } //********单字节读取***************************************** uchar Single_Read_ADXL345(uchar REG_Address) { uchar REG_data; start(); //起始信号 write1byte(SlaveAddress); //发送设备地址+写信号 cack(); write1byte(REG_Address); //发送存储单元地址,从 0 开始 cack(); start(); //起始信号 write1byte(SlaveAddress+1); //发送设备地址+读信号 cack(); REG_data=read1byte(); //读出寄存器数据 mnack(); stop(); //停止信号 return REG_data; } //********************************************************* // //连续读出 ADXL345 内部加速度数据,地址范围 0x32~0x37 // //********************************************************* void Multiple_read_ADXL345(void) { uchar i; start(); //起始信号 write1byte(SlaveAddress); //发送设备地址+写信号 cack(); write1byte(0x32); //发送存储单元地址,从 0x32 开始
SCL_OUT; SDA_L; SCL_H; delayus(2); SCL_L; SDA_H; } /********************:mnack 功 能:完成 IIC 的主机无应答操作 参 数:无 返回值 :无 ********************************************/ void mnack(void) { SDA_OUT; SCL_OUT; SDA_H; delayus(2); SCL_H; delayus(2); SCL_L; SDA_L; } /*判断应答或非应答子程序 */ void cack() { SDA_IN; SCL_OUT; SCL_L; delayus(1); SCL_H; err=0; if(SDA_DATE)err=1; SCL_L; SDA_OUT; } /******************************************* 函数名称:write1byte 功 能:向 IIC 总线发送一个字节的数据 参 数:wdata--发送的数据 返回值 :无 ********************************************/
#include <msp430x14x.h> #include <math.h> #include"LCD1602.c" #define uint unsigned int #define uchar unsigned char #define #define #define #define #define #define #define #define SDA_L P2OUT&=~BIT3//EEPROM 数据线低 SDA_H P2OUT|=BIT3//数据线高 SDA_OUT P2DIR|=BIT3//设置数据线为输出状态 SDA_IN P2DIR&=~BIT3//设置数据线为输入状态 SDA_DATE P2IN & BIT3//读入 SDA 线的状态 SCL_L P2OUT&=~BIT2//串行时钟线低 SCL_H P2OUT|=BIT2//时钟高 SCL_OUT P2DIR|=BIT2//设置时钟线为输出状态 1 0 0xA6
cack(); start(); write1byte(SlaveAddress+1); cack(); for (i=0; i<6; i++) { BUF[i] = read1byte(); if (i == 5) { mnack(); } else { mack(); } } stop(); delayus(100); }
//取余运算 //取余运算 //取余运算 //取余运算
//*********************************************************************** //显示 x 轴 void display_x() { int temp; dis_data=(BUF[1]<<8)+BUF[0]; //合成数据 if(dis_data<0){ dis_data=-dis_data; DisplayOneChar(2,0,'-'); //显示正负符号位 } else DisplayOneChar(2,0,' '); //显示空格 temp=(int)(dis_data*3.9); //计算数据和显示,查考 ADXL345 快速入门第 4 页 conversion(temp); //转换出显示需要的数据 DisplayOneChar(0,0,'X'); //第 0 行,第 0 列 显示 X DisplayOneChar(1,0,':'); DisplayOneChar(3,0,qian); DisplayOneChar(4,0,'.'); DisplayOneChar(5,0,bai); DisplayOneChar(6,0,shi); DisplayOneChar(7,0,'g'); } //*********************************************************************** //显示 y 轴 void display_y() { int temp; dis_data=(BUF[3]<<8)+BUF[2]; //合成数据 if(dis_data<0){ dis_data=-dis_data; DisplayOneChar(2,1,'-'); //显示正负符号位 } else DisplayOneChar(2,1,' '); //显示空格 temp=(int)(dis_data*3.9); //计算数据和显示,查考 ADXL345 快速入门第 4 页 conversion(temp); //转换出显示需要的数据 DisplayOneChar(0,1,'Y'); //第 1 行,第 0 列 显示 y DisplayOneChar(1,1,':'); DisplayOneChar(3,1,qian); DisplayOneChar(4,1,'.');
#define TRUE #define FALSE
#define SlaveAddress char BUF[8]; uchar devid; uchar err; int dis_data; uchar ge,shi,bai,qian,wan;
//显示变量
/******************************************* 函数名称:delay 功 能:延时约 15us 的时间 参 数:无 返回值 :无 ********************************************/ void delayus(unsigned int i)//delay 2.5us at 8M { unsigned int ii; for(ii =i;ii > 0;ii--) { _NOP();_NOP();_NOP();_NOP(); _NOP();_NOP();_NOP();_NOP(); _NOP();_NOP();_NOP();_NOP(); _NOP();_NOP();_NOP();_NOP(); }