资讯详情

ADXL345测倾斜角(程序)

#include

#include //Keil library

#include //Keil library

#include

#define uchar unsigned char

#define uint unsigned int

#define DataPort P0 //LCD1602数据端口

sfr TUXR=0x8E;

sfr CMOD=0xD9;

sfr CCON=0xD8;

sfr CL=0xE9;

sfr CH=0xF9;

sfr CCAPM0=0xDA;

sfr CCAPM1=0xDB;

sfr CCAP0L=0xEA;

sfr CCAP0H=0xFA;

sfr CCAP1L=0xEB;

sfr CCAP1H=0xFB;

sbit CR=CCON^6;

sbit SCL=P2^0; //IIC时钟引脚定义

sbit SDA=P2^1; //IIC数据引脚定义

sbitp22=P2^2;

sbitp31=P3^1;

sbitp33=P3^3;

sbit LCM_RS=P2^6; //LCD1602命令端口

sbit LCM_RW=P2^5; //LCD1602命令端口

sbit LCM_EN=P2^7; //LCD1602命令端口

#define SlaveAddress 0xA6 //定义器件在IIC根据总线的地址ALTADDRESS不同修改地址引脚

//ALTADDRESS引脚接地时地址为0xA6.接电源时地址为0x3A

typedef unsigned charBYTE;

typedef unsigned short WORD;

BYTE BUF[8]; //接收数据缓存区

uchar ge,shi,bai,qian,wan; //显示变量个十百千万

intdis_data; //变量

float jd;

uint PWMH;

void InitLcd(); //初始化lcd1602

void Init_ADXL345(void); //初始化ADXL345

void WriteDataLCM(uchar dataW); // LCD1602相关函数

void WriteCommandLCM(uchar CMD,uchar Attribc); //

void DisplayOneChar(uchar X,uchar Y,uchar DData); //

void conversion(uint temp_data); ///数据处理

voidSingle_Write_ADXL345(uchar REG_Address,uchar REG_data); //单独写入数据

uchar Single_Read_ADXL345(uchar REG_Address); ///单独读取内部寄存器数据

voidMultiple_Read_ADXL345(); ///连续读取内部寄存器数据

//------------------------------------

void Delay5us();

void Delay5ms();

void ADXL345_Start(); //与iic有关函数

void ADXL345_Stop();

void ADXL345_SendACK(bit ack); //传输响应

bitADXL345_RecvACK(); //接收应答

void ADXL345_SendByte(BYTE dat);

BYTE ADXL345_RecvByte();

void ADXL345_ReadPage();

void ADXL345_WritePage();

/*******************************/

void WaitForEnable(void)

{

DataPort=0xff;

LCM_RS=0;

LCM_RW=1;

_nop_(); _nop_();

LCM_EN=1;

_nop_();_nop_(); _nop_();_nop_();

while(DataPort&0x80);

LCM_EN=0;

}

/*******************************/

void WriteCommandLCM(uchar CMD,uchar Attribc)

{

if(Attribc)

WaitForEnable();

LCM_RS=0;

LCM_RW=0;

_nop_();_nop_();

DataPort=CMD;

_nop_();_nop_();

LCM_EN=1;

nop_();_nop_();nop_();_nop_();

LCM_EN=0;

}

/*******************************/

void WriteDataLCM(uchar dataW)

{

WaitForEnable();

LCM_RS=1;LCM_RW=0;

_nop_();_nop_();

DataPort=dataW;_nop_();

LCM_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCM_EN=0;

}

/***********************************/

void InitLcd()

{

WriteCommandLCM(0x38,1);

WriteCommandLCM(0x08,1);

WriteCommandLCM(0x01,1);

WriteCommandLCM(0x06,1);

WriteCommandLCM(0xc,1);

}

/***********************************/

void DisplayOneChar(uchar X,uchar Y,uchar DData) //X,Y为字符坐标

{

Y&=0x01;

X&=0x0f;

if(Y)

X|=0x40;   //8+4=c

X|=0x80;

WriteCommandLCM(X,1);

WriteDataLCM(DData);

}

void Delay5us()                //@12.000MHz

{

unsigned char i;

i = 12;

while (--i);

}

void Delay5ms()                //@12.000MHz

{

unsigned char i, j;

_nop_();

_nop_();

i = 59;

j = 89;

do

{

while (--j);

} while (--i);

}

/**************************************

起始信号

**************************************/

void ADXL345_Start()

{

SDA = 1;                    //拉高数据线

SCL = 1;                    //拉高时钟线

Delay5us();                 //延时

SDA = 0;                    //产生下降沿

Delay5us();                 //延时

SCL = 0;                    //拉低时钟线

}

/**************************************

停止信号

**************************************/

void ADXL345_Stop()

{

SDA = 0;                    //拉低数据线

SCL = 1;                    //拉高时钟线

Delay5us();                 //延时

SDA = 1;                    //产生上升沿

Delay5us();                 //延时

}

/**************************************

发送应答信号

入口参数:ack (0:ACK 1:NAK)

**************************************/

void ADXL345_SendACK(bit ack)

{

SDA = ack;                  //写应答信号

SCL = 1;                    //拉高时钟线

Delay5us();                 //延时

SCL = 0;                    //拉低时钟线

Delay5us();                 //延时

}

/**************************************

接收应答信号

**************************************/

bit ADXL345_RecvACK()

{

SCL = 1;                    //拉高时钟线

Delay5us();                 //延时

CY = SDA;                   //读应答信号

SCL = 0;                    //拉低时钟线

Delay5us();                 //延时

return CY;

}

/**************************************

向IIC总线发送一个字节数据

**************************************/

void ADXL345_SendByte(BYTE dat)

{

BYTE i;

for (i=0; i<8; i++)         //8位计数器

{

dat <<= 1;              //移出数据的最高位

SDA = CY;               //送数据口

SCL = 1;                //拉高时钟线

Delay5us();             //延时

SCL = 0;                //拉低时钟线

Delay5us();             //延时

}

ADXL345_RecvACK();

}

/**************************************

从IIC总线接收一个字节数据

**************************************/

BYTE ADXL345_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;

}

//******单字节写入*******************************************

//用于ADXL345初始化

void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)

{

ADXL345_Start();                  //起始信号

ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号

ADXL345_SendByte(REG_Address);  //内部寄存器地址,请参考中文pdf22页

ADXL345_SendByte(REG_data);    //内部寄存器数据,请参考中文pdf22页

//相当于 向相应的地址写入命令字

ADXL345_Stop();                 //发送停止信号

}

//********单字节读取*****************************************

uchar Single_Read_ADXL345(uchar REG_Address)

{

uchar REG_data;

ADXL345_Start();                          //起始信号

ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号,//0xA6写入

ADXL345_SendByte(REG_Address);            //发送存储单元地址,从0开始

ADXL345_Start();                          //起始信号

ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号,//0xA7读取

REG_data=ADXL345_RecvByte();              //读出寄存器数据

ADXL345_SendACK(1);

ADXL345_Stop();                           //停止信号

return REG_data;

}

//*********************************************************

//

//连续读出ADXL345内部加速度数据,地址范围0x32~0x37

//

//*********************************************************

void Multiple_read_ADXL345(void)

{

uchar i;

ADXL345_Start();                          //起始信号

ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号

ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始

ADXL345_Start();                          //起始信号

ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号

for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF

{

BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据

if (i == 5)

{

ADXL345_SendACK(1);                //最后一个数据需要回NOACK

}

else

{

ADXL345_SendACK(0);                //回应ACK

}

}

ADXL345_Stop();                          //停止信号

Delay5ms();

}

//*****************************************************************

//初始化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(uint temp_data)

{

wan=temp_data/10000+0x30 ;              //0x30='0'

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;

}

//显示x轴倾斜角,即x轴与垂线所成角度

void display_jd_x()

{

bit bj=0;//标记

int  dis_data_x,dis_data_z;  //x,y轴加速度的原始数据,用补码形式表示

float mg_x,mg_z;           //角度,加速度

dis_data_x=(BUF[1]<<8)+BUF[0];  //合成数据

dis_data_z=(BUF[5]<<8)+BUF[4];  //合成数据

if((dis_data_x<=0)&&(dis_data_z>0))          //第二象限

{

dis_data_x=-dis_data_x;

DisplayOneChar(8,0,' ');

bj=1;

}

else if((dis_data_z<0)&&(dis_data_x>=0))         //第四象限

{

dis_data_z=-dis_data_z;

DisplayOneChar(8,0,'-');  //显示正负符号位

}

else if((dis_data_z<=0)&&(dis_data_x<0))           //第三象限

{

bj=1;

dis_data_z=-dis_data_z;

dis_data_x=-dis_data_x;

DisplayOneChar(8,0,'-');  //显示正负符号位

}

else if((dis_data_z>=0)&&(dis_data_x>0))

DisplayOneChar(8,0,' ');                //第一象限

mg_x=(float)dis_data_x*3.9;  //计算数据和显示,查看ADXL345快速入门第4页,1LSB=3.9mg(毫g)

mg_z=(float)dis_data_z*3.9;         //强制类型转换,dis_data_z的类型和值不会发生改变

jd=atan2(mg_z,mg_x)*(180/3.14159);

if(bj==1)jd=180-jd;

//jd=jd*10;  消除小数点,便于转换数据和显示

conversion(jd*10);      //转换出显示需要的数据                                        //

DisplayOneChar(6,0,'X');

DisplayOneChar(7,0,':');

DisplayOneChar(9,0,qian);

DisplayOneChar(10,0,bai);

DisplayOneChar(11,0,shi);

DisplayOneChar(12,0,'.');

DisplayOneChar(13,0,ge);

DisplayOneChar(14,0,0xdf);            //显示 °

DisplayOneChar(15,0,' ');

}

void PCAinit()        //PCA模块初始化

{

CCON=0;

CL=0;

CH=0;

CMOD=0x00;        //sysclk/12

CCAPM0=0x42;//8位PWM,无中断

CR=1;

CCAP0H=CCAP0L=256-240;

}

void init_t0()         //定时器0初始化

{

TUXR&=0x7f;         //12T

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TR0=1;

EA=1;

ET0=1;

}

//*********************************************************

//******主程序********

//*********************************************************

void main()

{

char H;

InitLcd();               //液晶初始化ADXL345

Delay5ms();

Init_ADXL345();                 //初始化ADXL345

PCAinit();

init_t0();

H=CCAP0H;

while(1)

{

if(p33==0)

{

Delay5ms();

if(p33==0)

{

H=H+5;

if(H>255)H=255;

CCAP0H=H;

CCAP0L=H;

while(p33==0);

}

}

if(p31==0)

{

Delay5ms();

if(p31==0)

{

H=H-5;

if(H<0)H=0;

……………………

…………限于本文篇幅 余下代码请从51黑下载附件…………

标签: 传感器adxl001加速度传感器adxl345

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台