Buscando un programa para usar el microcontrolador 51 para controlar ADXL345 para medir el ángulo. A través del sensor ADXL345, use el microcontrolador 51 para controlar el programa para medir el ángulo de inclinación.

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

// Programa de prueba GY-29 ADXL345 IIC

// Usando el microcontrolador STC89C51

// Oscilador de cristal: 11.0592M

// Pantalla: LCD1602

// Entorno de compilación Keil uVision2

// Consulte el programa de comunicación 24c04 del sitio web de Acer

// Hora: 1 de marzo de 2011

// QQ: 531389319

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

#include lt;REG51.Hgt

#include lt;math.hgt; //Biblioteca Keil

#include lt;REG51.Hgt; p>

# include lt; stdio.hgt; //Biblioteca Keil

#include lt; INTRINS.Hgt

#define uchar unsigned char

#define uint unsigned int

#define DataPort P0 //puerto de datos LCD1602

sbit SCL=P1^0 //definición del pin del reloj IIC

sbit; SDA=P1^1 ; //Definición del pin de datos IIC

sbit LCM_RS=P2^0; //Puerto de comando LCD1602

sbit LCM_RW=P2^1;

sbit LCM_EN=P2^2; //puerto de comando LCD1602

#define SlaveAddress 0xA6 //Definir la dirección esclava del dispositivo en el bus IIC, modificada según la DIRECCIÓN ALT pin de dirección

//Cuando el pin ALT DIRECCIÓN está conectado a tierra, la dirección es 0xA6, y cuando está conectado a la alimentación, la dirección es 0x3A

typedef unsigned char BYTE;

typedef unsigned short WORD;

BYTE BUF[8]; //Recibir área de búfer de datos

uchar ge, shi, bai, qian, wan; variables

int dis_data; //Variable

int data_xyz[3];

retraso vacío (unsigned int k);

void InitLcd(); //Inicializar lcd1602

void Init_ADXL345(void); //Inicializar ADXL345

<

p>void WriteDataLCM(uchar dataW);

void WriteCommandLCM(uchar CMD, uchar Attribc);

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

void conversion(uint temp_data);

void Single_Write_ADXL345(uchar REG_Address, uchar REG_data); //datos de escritura única

uchar Single_Read_ADXL345(uchar REG_Address); //lectura única; datos de registro interno

void Multiple_Read_ADXL345(); //Leer continuamente datos de registro interno

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

void Delay5us();

void Delay5ms();

void ADXL345_Start ();

void ADXL345_Stop();

void ADXL345_SendACK(bit ack);

bit ADXL345_RecvACK();

void ADXL345_SendByte (BYTE dat);

BYTE ADXL345_RecvByte();

void ADXL345_ReadPage();

void ADXL345_WritePage();

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

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

conversión nula (uint temp_data)

{

wan=temp_data/10000 0x30

temp_data=temp_data10000; operación

qian=temp_data/1000 0x30;

temp_data=temp_data1000; //Operación restante

bai=temp_data/100 0x30; > temp_data=temp_data100; //operación restante

shi=temp_data/10 0x30;

temp_data=temp_data10; //operación restante

ge=temp_data 0x30;

}

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

retraso nulo(unsigned int k)

{

unsign

ed int i, j;

for(i=0;ilt;k;i)

{

for(j=0;jlt;121; j )

{;}}

}

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

void WaitForEnable(void)

{

DataPort=0xff

LCM_RS =0;LCM_RW=1;_nop_();

LCM_EN=1;_nop_();_nop_();

mientras(DataPortamp;0x80

<); p >LCM_ES=0;

}

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

void WriteCommandLCM(uchar CMD, uchar Attribc)

{

if(Attribc)WaitForEnable()

>LCM_RS =0; LCM_RW=0; _nop_(); _nop_(); ;

}

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

void WriteDataLCM(uchar dataW)

{

WaitForEnable()

LCM_RS=1; ();

p>

DataPort=datosW;

LCM_EN=1; _nop_(); }

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

void InitLcd()

{

WriteCommandLCM(0x38, 1);

WriteCommandLCM(0x08, 1); /p>

WriteCommandLCM(0x01, 1);

WriteCommandLCM(0x06, 1);

WriteCommandLCM(0x0c, 1); /p>

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

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

{

Yamp;=1

Xamp;=15; >if(Y)X|=0x40;

X|=0x80;

WriteCommandLCM(X, 0);

WriteDataLCM(DData); p>

}

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

p>

Retraso de 5 microsegundos (STC90C52RC@12M)

Esta función debe ajustarse para diferentes entornos de trabajo. Tenga en cuenta que debe modificarse cuando el reloj es demasiado rápido.

Al cambiar a 1T Cuando utilice una MCU, ajuste esta función de retardo

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

void Delay5us()

{

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

p>

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

}

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

Retraso de 5 milisegundos (STC90C52RC@12M)

Esta función debe ajustarse para diferentes entornos de trabajo

Al cambiar a una MCU 1T, ajuste esta función de retardo

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

void Delay5ms()

{

WORD n = 560

while (n; --);

}

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

Señal de inicio

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

void ADXL345_Start()

{

SDA = 1; //Sube la línea de datos

SCL = 1; //Sube la línea de reloj

Delay5us(); //Retraso

SDA = 0; //Generar flanco descendente

Delay5us(); //Retraso cuando

SCL = 0 //baja la línea del reloj

}

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

Señal de parada

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

void ADXL345_Stop()

{

SDA = 0; // Baja la línea de datos

SCL = 1 ; //Sube la línea del reloj

Delay5us(); //Retraso

SDA = 1; //Genera flanco ascendente

Delay5us(); /Retraso

}

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

Enviar señal de respuesta

Parámetros de entrada: ack (0: ACK 1: NAK)

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

void ADXL345_SendACK(bit ack)

{

SDA = ack //Escribir señal de respuesta;

SCL = 1; // Baja la línea del reloj

Delay5us(); // Retraso

SCL = 0;

Delay5us(); //Retraso

}

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

Recibir señal de respuesta

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

bit ADXL345_RecvACK()

{

SCL = 1; // Tire de la línea del reloj hacia arriba

Delay5us(); //Retraso

CY = SDA //Leer señal de respuesta

p>

SCL = 0; //Tirar de la línea de reloj baja

Delay5us(); //Retraso

return CY;

}

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

Enviar un byte de datos al bus IIC

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

anular ADXL345_SendByte(BYTE dat)

{

BYTE i; (i=0; ilt; 8; i) // Contador de 8 bits

{

dat lt; = 1 // Elimina el bit de datos más alto

SDA = CY; //Enviar puerto de datos

SCL = 1; //Sube la línea del reloj

Delay5us(); >

SCL = 0; // Baja la línea del reloj

Delay5us(); //Retraso

}

ADXL345_RecvACK(); p>

}

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

Recibir un byte de datos del bus IIC

*************************** *****

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

BYTE ADXL345_RecvByte()

{

BYTE i;

BYTE dat = 0;

SDA = 1; //Habilitar pull-up interno, listo para leer datos,

for (i=0; ilt; 8; i) //8 Contador de bits

{

dat lt; = 1;

SCL = 1; // tira de la línea del reloj hacia arriba

Delay5us (); //Retraso

dat |= SDA; //Leer datos

SCL = 0; //Bajar la línea del reloj

Delay5us() ; //Retraso

}

return dat;

}

//******Escritura de un solo byte Enter* *****************************************

void Single_Write_ADXL345 (uchar REG_Address, uchar REG_data)

{

ADXL345_Start(); //Señal de inicio

ADXL345_SendByte(SlaveAddress); //Enviando señal de escritura de dirección del dispositivo

ADXL345_SendByte(REG_Address); //Dirección de registro interno, consulte la página 22 del pdf en chino

ADXL345_SendByte(REG_data); //Datos del registro interno, consulte la página 22 del pdf en chino

ADXL345_Stop(); //Enviar señal de parada

}

//*********Lectura de un solo byte***** ** ********************************

uchar Single_Read_ADXL345(uchar REG_Address)

{ uchar REG_data;

ADXL345_Start(); //Iniciar señal

ADXL345_SendByte(SlaveAddress); //Enviar señal de escritura de dirección del dispositivo

ADXL345_SendByte (REG_Address); //Envía la dirección de la unidad de memoria, comenzando desde 0

ADXL345_Start(); //Señal de inicio

ADXL345_SendByte(SlaveAddress 1);

//Enviar señal de lectura de dirección del dispositivo

REG_data=ADXL345_RecvByte(); //Leer datos de registro

ADXL345_SendACK(1);

ADXL345_Stop(); Señal de parada

return REG_data

}

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

//

//Lea continuamente los datos de aceleración interna de ADXL345, rango de direcciones 0x32~0x37

//

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

void Multiple_read_ADXL345(void)

{ uchar i;

ADXL345_Start(); //Señal de inicio

ADXL345_SendByte(SlaveAddress); Signal

ADXL345_SendByte(0x32); //Enviar dirección de unidad de almacenamiento, comenzando desde 0x32

ADXL345_Start(); //Iniciar señal

ADXL345_SendByte(SlaveAddress 1 ) ; //Enviar señal de lectura de dirección del dispositivo

for (i=0; ilt; 6; i) //Leer continuamente 6 datos de dirección, almacenados en BUF

{

BUF[i] = ADXL345_RecvByte(); //BUF[0] almacena los datos en la dirección 0x32

if (i == 5)

{

ADXL345_SendACK(1); //Los últimos datos deben devolver NOACK

}

else

{

ADXL345_SendACK( 0); //Respuesta a ACK

}

}

ADXL345_Stop(); //Señal de parada

Delay5ms() ;

}

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

//Inicialice ADXL345, consulte el pdf según sea necesario Realizar cambios************************

<

p>void Init_ADXL345()

{

Single_Write_ADXL345(0x31, 0x0B); //Rango de medición, más o menos 16 g, modo de 13 bits

Single_Write_ADXL345 (0x2C, 0x08); //Establezca la velocidad en 12,5, consulte la página 13 del pdf

Single_Write_ADXL345(0x2D, ​​​​0x08); //Seleccione el modo de energía, consulte la página 24 del pdf

Single_Write_ADXL345(0x2E, 0x80); //Habilitar interrupción DATA_READY

Single_Write_ADXL345(0x1E, 0x00); //El desplazamiento X se escribe en la página pdf29 según el estado del sensor de prueba

Single_Write_ADXL345(0x1F, 0x00); / /El desplazamiento Y se escribe en la página 29 del pdf según el estado del sensor de prueba

Single_Write_ADXL345(0x20, 0x05); pdf página 29 según el estado del sensor de prueba

}

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

//Mostrar eje x

void display_x()

{ float temp;

dis_data=(BUF[1]lt; lt;8) BUF[0]; //Datos sintéticos

if(dis_datalt; 0){

dis_data=-dis_data;

DisplayOneChar(2, 0, '-'); //Mostrar los bits de signo positivo y negativo

}

else DisplayOneChar(2, 0, ' ');

temp=(float)dis_data*3.9; //Calcule los datos y visualícelos, consulte la página de inicio rápido 4 de ADXL345

conversion(temp); p> DisplayOneChar(0, 0, 'X'); // Línea 0, no. La columna 0 muestra ,'.

DisplayOneChar(5, 0, bai); p> DisplayOneChar(6, 0, shi);

DisplayOneChar(7, 0 ,'g');

}

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

>Mostrar eje y

void display_y()

{ temperatura flotante;

dis_data=(BUF[3]

lt;lt;8) BUF[2]; //Datos sintéticos

if(dis_datalt;0){

dis_data=-dis_data;

DisplayOneChar( 2, 1, '-'); //Mostrar bits de signo positivos y negativos

}

else DisplayOneChar(2, 1, ' '); >

temp=(float)dis_data*3.9; //Calcule los datos y visualícelos, consulte la página 4 del inicio rápido de ADXL345

conversion(temp); //Convierta los datos necesarios para la visualización

DisplayOneChar(0, 1, 'Y'); // Fila 1, columna 0 muestra y

DisplayOneChar(1, 1, ':'); (3, 1, qian);

DisplayOneChar(4, 1, '.');

DisplayOneChar(5, 1, bai

DisplayOneChar); (6, 1, shi);

DisplayOneChar(7, 1, 'g'

}

//****** *); ************************************************** ***************

//Mostrar eje z

void display_z()

{ float temp;

dis_data=(BUF[5]lt;lt;8) BUF[4]; //Datos sintéticos

if(dis_datalt;0){

dis_data =-dis_data;

DisplayOneChar(10, 1, '-'); //Mostrar bit de signo negativo

}

else DisplayOneChar(10, 1 , ' '); //Mostrar espacios

temp=(float)dis_data*3.9; //Calcular datos y mostrar, consulte la página 4 del inicio rápido de ADXL345

conversion(temp) ; //Convierte los datos necesarios para la visualización

/*

DisplayOneChar(10, 0, 'Z'); //Fila 0, columna 10 muestra Z

DisplayOneChar(11, 0, ':');

DisplayOneChar(11, 1, qian

DisplayOneChar(12, 1, '.'); > p>

DisplayOneChar(13, 1, bai);

DisplayOneChar(14, 1, shi

DisplayOneChar(15, 1, 'g'); /p>

p>

*/

}

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

<

p>//******Programa principal************

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

anular principal ()

{

uchar devid;

float Roll, Pitch, Q, T, K

retardo(500); //Retraso de encendido

InitLcd(); //Inicialización LCD ADXL345

Init_ADXL345(); //Inicialización ADXL345

devid=Single_Read_ADXL345(0X00) ; // Leer los datos es 0XE5, lo que significa correcto

while(1) // Bucle

{

Init_ADXL345() //Inicializar ADXL345;

Multiple_Read_ADXL345(); //Leer datos continuamente y almacenarlos en BUF

data_xyz[0]=(BUF[1]lt;lt;8) BUF[0]; Datos sintéticos

p>

data_xyz[1]=(BUF[3]lt;lt;8) BUF[2] //Datos sintéticos

data_xyz[2]=(BUF [5]lt;lt ;8) BUF[4]; //Datos sintéticos

//Los datos originales de aceleración X, Y, Z respectivamente, 10 bits

Q= (float)data_xyz[ 0]*3.9;

T=(float)data_xyz[1]*3.9;

K=(float)data_xyz[2]*3.9;

Q=-Q;

Roll=(float)(((atan2(K, Q)*180)/3.14159265) 180); //Valor del ángulo del eje X

Pitch= (float)(((atan2(K, T)*180)/3.14159265) 180); //Valor del ángulo del eje Y

conversión(Roll); Datos del eje X necesarios para la visualización, o eje Y

DisplayOneChar(9, 1, 'A'

DisplayOneChar(10, 1, ':'); >

DisplayOneChar(11, 1, bai);

DisplayOneChar(12, 1, shi

DisplayOneChar(13, 1, ge); p> retraso(200); / /Retraso

}

}