求GY5216050stm32程序,详细一点的,谢谢

求GY5216050stm32程序,详细一点的,谢谢,第1张

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

// 使用单片机STC89C51

// 晶振:11.0592M

// 显示:LCD1602

// 编译环境 Keil uVision2

// 参考宏晶网站24c04通信程序

// 时间:2011年9月1日

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

#include <REG51.H>

#include <math.h> //Keil library

#include <stdio.h> //Keil library

#include <INTRINS.H>

#define uchar unsigned char

#define uint unsigned int

#define DataPort P0//LCD1602数州携据端口

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

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

sbit LCM_RS=P2^0 //LCD1602命令端口

sbit LCM_RW=P2^1 //LCD1602命令端口

sbit LCM_EN=P2^2 //LCD1602命令端口拦世

//定义ITG3205内部地址********************

#define WHO 0x00

#define SMPL 0x15

#define DLPF 0x16

#define INT_C 0x17

#define INT_S 0x1A

#define TMP_H 0x1B

#define TMP_L 0x1C

#define GX_H 0x1D

#define GX_L 0x1E

#define GY_H 0x1F

#define GY_L 0x20

#define GZ_H 0x21

#define GZ_L 0x22

#define PWR_M 0x3E

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

#define SlaveAddress 0xD0 //定义器件册衡伏在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改

typedef unsigned char BYTE

typedef unsigned short WORD

uchar dis[4]//显示数组

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

int dis_data //变量

int Temperature,Temp_h,Temp_l

void delay(unsigned int k)

void InitLcd()//初始化lcd1602

void InitITG3205()//初始化ITG3205

void WriteDataLCM(uchar dataW)

void WriteCommandLCM(uchar CMD,uchar Attribc)

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

void DisplayListChar(uchar X,uchar Y,uchar *DData,L)

void Single_WriteITG3205(uchar REG_Address,uchar REG_data) //单个写入数据

uchar Single_ReadITG3205(uchar REG_Address) //单个读取内部寄存器数据

//****************************************模拟IIC使用函数

void Delay5us()

void ITG3205_Start()

void ITG3205_Stop()

void ITG3205_SendACK(bit ack)

bit ITG3205_RecvACK()

void ITG3205_SendByte(BYTE dat)

BYTE ITG3205_RecvByte()

void ITG3205_ReadPage()

void ITG3205_WritePage()

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

void display_x()

void display_y()

void display_z()

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

void lcd_printf(uchar *s,int temp_data)

{

if(temp_data<0){

temp_data=-temp_data

*s='-'

}

else *s=' '

*++s =temp_data/100+0x30

temp_data=temp_data%100//取余运算

*++s =temp_data/10+0x30

temp_data=temp_data%10 //取余运算

*++s =temp_data+0x30

}

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

void delay(unsigned int k)

{

unsigned int i,j

for(i=0i<ki++)

{

for(j=0j<121j++)

{}}

}

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

void WaitForEnable(void)

{

DataPort=0xff

LCM_RS=0LCM_RW=1_nop_()

LCM_EN=1_nop_()_nop_()

while(DataPort&0x80)

LCM_EN=0

}

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

void WriteCommandLCM(uchar CMD,uchar Attribc)

{

if(Attribc)WaitForEnable()

LCM_RS=0LCM_RW=0_nop_()

DataPort=CMD_nop_()

LCM_EN=1_nop_()_nop_()LCM_EN=0

}

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

void WriteDataLCM(uchar dataW)

{

WaitForEnable()

LCM_RS=1LCM_RW=0_nop_()

DataPort=dataW_nop_()

LCM_EN=1_nop_()_nop_()LCM_EN=0

}

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

void InitLcd()

{

WriteCommandLCM(0x38,1)

WriteCommandLCM(0x08,1)

WriteCommandLCM(0x01,1)

WriteCommandLCM(0x06,1)

WriteCommandLCM(0x0c,1)

DisplayOneChar(0,0,'x')

DisplayOneChar(1,0,':')

DisplayOneChar(0,1,'y')

DisplayOneChar(1,1,':')

DisplayOneChar(9,0,'z')

DisplayOneChar(10,0,':')

DisplayOneChar(9,1,'T')

DisplayOneChar(10,1,':')

}

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

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

{

Y&=1

X&=15

if(Y)X|=0x40

X|=0x80

WriteCommandLCM(X,0)

WriteDataLCM(DData)

}

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

void DisplayListChar(uchar X,uchar Y,uchar *DData,L)

{

uchar ListLength=0

Y&=0x1

X&=0xF

while(L--)

{

DisplayOneChar(X,Y,DData[ListLength])

ListLength++

X++

}

}

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

延时5微秒(STC90C52RC@12M)

不同的工作环境,需要调整此函数,注意时钟过快时需要修改

当改用1T的MCU时,请调整此延时函数

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

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

}

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

起始信号

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

void ITG3205_Start()

{

SDA = 1 //拉高数据线

SCL = 1 //拉高时钟线

Delay5us()//延时

SDA = 0 //产生下降沿

Delay5us()//延时

SCL = 0 //拉低时钟线

}

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

停止信号

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

void ITG3205_Stop()

{

SDA = 0 //拉低数据线

SCL = 1 //拉高时钟线

Delay5us()//延时

SDA = 1 //产生上升沿

Delay5us()//延时

}

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

发送应答信号

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

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

void ITG3205_SendACK(bit ack)

{

SDA = ack //写应答信号

SCL = 1 //拉高时钟线

Delay5us()//延时

SCL = 0 //拉低时钟线

Delay5us()//延时

}

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

接收应答信号

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

bit ITG3205_RecvACK()

{

SCL = 1 //拉高时钟线

Delay5us()//延时

CY = SDA //读应答信号

SCL = 0 //拉低时钟线

Delay5us()//延时

return CY

}

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

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

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

void ITG3205_SendByte(BYTE dat)

{

BYTE i

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

{

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

SDA = CY //送数据口

SCL = 1 //拉高时钟线

Delay5us()//延时

SCL = 0 //拉低时钟线

Delay5us()//延时

}

ITG3205_RecvACK()

}

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

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

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

BYTE ITG3205_RecvByte()

{

BYTE i

BYTE dat = 0

SDA = 1 //使能内部上拉,准备读取数据,

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

{

dat <<= 1

SCL = 1 //拉高时钟线

Delay5us()//延时

dat |= SDA//读数据

SCL = 0 //拉低时钟线

Delay5us()//延时

}

return dat

}

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

void Single_WriteITG3205(uchar REG_Address,uchar REG_data)

{

ITG3205_Start() //起始信号

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

ITG3205_SendByte(REG_Address) //内部寄存器地址,

ITG3205_SendByte(REG_data) //内部寄存器数据,

ITG3205_Stop() //发送停止信号

}

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

uchar Single_ReadITG3205(uchar REG_Address)

{ uchar REG_data

ITG3205_Start() //起始信号

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

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

ITG3205_Start() //起始信号

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

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

ITG3205_SendACK(1)

ITG3205_Stop() //停止信号

return REG_data

}

//初始化ITG3205,根据需要请参考pdf进行修改************************

void InitITG3205()

{

Single_WriteITG3205(PWR_M, 0x80) //

Single_WriteITG3205(SMPL, 0x07) //

Single_WriteITG3205(DLPF, 0x1E) //±2000°

Single_WriteITG3205(INT_C, 0x00 ) //

Single_WriteITG3205(PWR_M, 0x00) //

}

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

//显示x轴

void display_x()

{

BUF[0]= Single_ReadITG3205(GX_L)

BUF[1]= Single_ReadITG3205(GX_H)

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

dis_data/=14.375 //计算对应 度/秒

lcd_printf(dis, dis_data)//转换数据显示

DisplayListChar(2,0,dis,4) //启始列,行,显示数组,显示长度

}

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

//显示y轴

void display_y()

{

BUF[2]= Single_ReadITG3205(GY_L)

BUF[3]= Single_ReadITG3205(GY_H)

dis_data=(BUF[3]<<8)+BUF[2] //合成数据

dis_data/=14.375 //计算对应 度/秒

lcd_printf(dis, dis_data)//转换数据显示

DisplayListChar(2,1,dis,4) //启始列,行,显示数组,显示位数

}

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

//显示z轴

void display_z()

{

BUF[4]= Single_ReadITG3205(GZ_L)

BUF[5]= Single_ReadITG3205(GZ_H)

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

dis_data/=14.375 //计算对应 度/秒

lcd_printf(dis, dis_data) //转换数据显示

DisplayListChar(11,0,dis,4)//启始列,行,显示数组,显示位数

}

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

//显示温度

void display_temp()

{

Temp_h=Single_ReadITG3205(TMP_H)//读取温度

Temp_l=Single_ReadITG3205(TMP_L)//读取温度

Temperature=Temp_h<<8|Temp_l//合成温度

Temperature = 35+ ((double) (Temperature + 13200)) / 280// 计算出温度

lcd_printf(dis,Temperature)//转换数据显示

DisplayListChar(11,1,dis,4)//启始列,行,显示数组,显示位数

}

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

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

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

void main()

{

delay(500) //上电延时

InitLcd() //液晶初始化

InitITG3205() //初始化ITG3205

delay(50)

while(1) //循环

{

display_x() //---------显示X轴

display_y() //---------显示Y轴

display_z() //---------显示Z轴

display_temp() //---------显示温度

delay(100) //延时

}

}

GY521是IIC接口,直耐核接用单片机清亩瞎普通IO模拟就可以了。得到数据加速度和角速度的原始数据后,就可以用串口传给上位机显示。可以用自带的DMP,可以得到处理后的数据,就可以得到横滚、俯仰、偏航的角度了。也可以自己写算法来处理原答空始数据。

//从串口得到GY521 MPU6050的数据

#include "Wire.h"

#include "I2Cdev.h"

#include "MPU6050.h"

MPU6050 accelgyro

int16_t ax, ay, az

int16_t gx, gy, gz

float C_Z = -1343.91//Z轴零点偏移量

float C_Gyro = -99.90/誉绝/陀螺仪零点偏移量

float Z_Min = -17873.76//物虚岩最小极值

float Z_Max = 15186.91//最大极值

float T_Z = 3//Z轴角度补偿时间常数

float R_Z = 180/(Z_Max - Z_Min)//Z轴比例

float R_Gyro = 0.081//陀螺仪比例

unsigned long T_Now =0//系统当前时间

unsigned long T_Last//上次时间

float Angle_G,Angle_AG,Angle_GG

int i

float GYRO

void setup() {

Wire.begin()

Serial.begin(38400)

// initialize device

Serial.println("Initializing I2C devices...")

accelgyro.initialize()

// verify connection

Serial.println("Testing device connections...")

Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed")

}

void loop() {

accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz)//读取6050数据

if (i>20)

{

GYRO = GYRO/20

float Angle_Z = (az-C_Z)*R_Z//加速度计 角度计算 (读取值-偏移量)*比例 单位:°

Angle_G = -(GYRO-C_Gyro)*R_Gyro//陀螺仪采样 (采样值-偏移量)*比例 单位:°/s

Angle_AG = Angle_AG + (((Angle_Z-Angle_AG)*1/T_Z)+Angle_G)*0.005/罩御/滤波

Angle_GG = Angle_GG + Angle_G*0.005//陀螺仪对X轴积分 得出角度。

Serial.print(Angle_Z)

Serial.print(",")

Serial.print(Angle_GG)

Serial.print(",")

Serial.print(Angle_AG)

Serial.print("\n")

i=0

}

GYRO = GYRO + gx

i++

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8205400.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存