Red de conocimiento del abogados - Ley de patentes - 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.

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; 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; //puerto de comando LCD1602

p>

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 el pin de dirección ALT ADDRESS

//Cuando el pin ALT ADDRESS 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 //Mostrar 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

<; p>LCM_RS =0;LCM_RW=1;_nop_();

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

mientras(DataPortamp;0x80

LCM_ES=0;

}

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

void WriteCommandLCM(uchar CMD, uchar Attribc)

{

if(Attribc)WaitForEnable()

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

Puerto de datos=CMD; =0;

}

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

void WriteDataLCM(uchar dataW)

{

WaitForEnable()

LCM_RS=1; ; _nop_();

p>

DataPort=datosW;

LCM_EN=1; _nop_(); p>}

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

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()

{

PALABRA n = 560

mientras (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 //Bajar la línea del reloj

}

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

Señal de parada

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

void ADXL345_Stop()

{

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

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

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 //Escribe señal de respuesta

p>

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

Delay5us(); //Delay

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

p>

Retraso5us(); //Retraso

}

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

Recibir señal de respuesta

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

bit ADXL345_RecvACK()

{

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

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

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

void ADXL345_SendByte(BYTE dat)

{

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

{

dat lt; = 1; data

SDA = CY; // Puerto de envío de datos

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

Delay5us() // Retraso

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

Delay5us(); //Retraso

}

ADXL345_RecvACK();

}

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

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; //tirar 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************

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

void main()

{

uchar devid;

float Roll, Pitch, Q, T, K

retardo(500); Retraso de encendido

InitLcd(); //Inicialización de LCD ADXL345

Init_ADXL345(); //Inicialización de ADXL345

devid=Single_Read_ADXL345(0X00); /Leer Los datos son 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];

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 necesarios para la visualización, o eje Y

DisplayOneChar(9, 1, 'A'

DisplayOneChar(10, 1, ':'); p> DisplayOneChar(11, 1, bai);

DisplayOneChar(12, 1, shi

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

}

}