0;i--);}while((IFG1&OFIFG));//等待时钟稳定BCSC" />
//includes.h
#include
#include "LCD1602.h"
#include "mpu6050.h"
//main.c
#include "includes.h"
void main()
{
WDTCTL = WDTPW + WDTHOLD;
BCSCTL1 &=~XT2OFF;
do
{
IFG1 &=~OFIFG;
for(uinti=0xff;i>0;i--);
}while((IFG1&OFIFG)); //等待时钟稳定BCSCTL2 |=SELM_2+SELS; //主、从系统时钟均为高频
DATA_DIR=0XFF;
DATA_OUT=0X00;
P6DIR=0XFF;
P6OUT=0X00;
init();
InitMPU6050();
while(1)
{
Display10BitData(GetData(ACCEL_XOUT_H),2,0); //显示X轴加速度
Display10BitData(GetData(ACCEL_YOUT_H),7,0); //显示Y轴加速度
Display10BitData(GetData(ACCEL_ZOUT_H),12,0); //显示Z轴加速度
Display10BitData(GetData(GYRO_XOUT_H),2,1); //显示X轴角速度
Display10BitData(GetData(GYRO_YOUT_H),7,1); //显示Y轴角速度
Display10BitData(GetData(GYRO_ZOUT_H),12,1);
delayms(300);
}
}
//以下是传感器相关文件
//mpu6050.h
#define CPU_F ((double)8000000)
#define delayus(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) //宏定义延时函数
#define delayms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define SCL1 P5OUT |=BIT0
#define SCL0 P5OUT &=~BIT0
#define SCLOUT P5DIR |= BIT0;
#define SDA1 P5OUT |=BIT1 //IIC数据引脚
#define SDA0 P5OUT &=~BIT1
#define SDAIN P5DIR &=~BIT1
#define SDAOUT P5DIR |=BIT1
#define SDADATA (P5IN & BIT1)
//****************************************
// 定义MPU6050内部地址
//****************************************
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) #define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
//显示数字(-511至512)的字符数组
void I2C_Start();
void I2C_Stop();
void I2C_SendACK(ucharack);
uchar I2C_RecvACK();
void I2C_SendByte(uchardat);
uchar I2C_RecvByte();
void Single_WriteI2C(ucharREG_Address,ucharREG_data); uchar Single_ReadI2C(ucharREG_Address);
void InitMPU6050();
voidlcd_printf(uchar *s,inttemp_data); voidDisplayListChar(ucharX,ucharY,uchar *DData,uchar L); intGetData(ucharREG_Address);
void Display10BitData(intvalue,ucharx,uchar y);
//mpu6050.c
#include "includes.h"
uchar dis[4];
intdis_data;
//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
SDAOUT;
SDA1; //拉高数据线
SCLOUT;
SCL1; //拉高时钟线delayus(5); //延时
SDA0; //产生下降沿delayus(5); //延时
SCL0; //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
SDAOUT;
SDA0; //拉低数据线
SCLOUT;
SCL1; //拉高时钟线delayus(5); //延时
SDA1; //产生上升沿delayus(5); //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(ucharack)
{
SDAOUT;
SCLOUT;
if(ack) SDA1;
else SDA0;
// SDA = ack; //写应答信号SCL1; //拉高时钟线delayus(5); //延时
SCL0; //拉低时钟线delayus(5); //延时
}
//**************************************
//I2C接收应答信号
//************************************** uchar I2C_RecvACK()
{
uchar cy;
SCLOUT;
SCL1; //拉高时钟线
SDAIN;
delayus(5); //延时
if(SDADATA)
{
cy=1;
}
else
{
cy=0;
}
// cy = SDA; //读应答信号SCL0; //拉低时钟线delayus(5); //延时
SDAOUT;
return cy;
}
//**************************************
//向I2C总线发送一个字节数据
//************************************** void I2C_SendByte(uchardat)
{
uchari;
SDAOUT;
for (i=0; i<8; i++) //8位计数器
{
if((dat<
{
SDA1;
}
else
{
SDA0;
}
// SDA = cy; //送数据口
SCLOUT;
SCL1; //拉高时钟线
delayus(5); //延时
SCL0; //拉低时钟线
delayus(5); //延时
}
I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte()
{
uchari;
uchardat = 0,cy;
SDAOUT;
SCLOUT;
SDA1; //使能内部上拉,准备读取数据, SDAIN;
for (i=0; i<8; i++) //8位计数器
{
dat<<= 1;
SCL1; //拉高时钟线
delayus(5); //延时
if(SDADATA)
{
cy=1;
}
else
{
cy=0;
}
dat |= cy; //读数据
SCL0; //拉低时钟线
delayus(5); //延时
}
SDAOUT;
returndat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(ucharREG_Address,ucharREG_data)
{
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //内部寄存器地址,
I2C_SendByte(REG_data); //内部寄存器数据,
I2C_Stop(); //发送停止信号
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uchar Single_ReadI2C(ucharREG_Address)
{
ucharREG_data;
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=I2C_RecvByte(); //读出寄存器数据
I2C_SendACK(1); //接收应答信号
I2C_Stop(); //停止信号
returnREG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_DIV, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
voidlcd_printf(uchar *s,inttemp_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;
}
//****************************************
//LCD1602显示字符串
//**************************************** voidDisplayListChar(ucharX,ucharY,uchar *DData,uchar L) {
ucharListLength=0;
Y&=0x1;
X&=0xF;
while(L--)
{
Disp1Char(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
//**************************************
//合成数据
//************************************** intGetData(ucharREG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //合成数据
}
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(intvalue,ucharx,uchar y)
{
value/=64; //转换为10位数据lcd_printf(dis, value); //转换数据显示
DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度}
//以下是LCD1602相关文件
#define uchar unsigned char
#define uint unsignedint
#define DATA_DIR P2DIR
#define DATA_OUT P2OUT
#define CLR_RS P6OUT&=~BIT3; //RS=0;
#define SET_RS P6OUT|=BIT3; //RS=1;
#define CLR_RW P6OUT&=~BIT4; //RW=0;
#define SET_RW P6OUT|=BIT4; //RW=1;
#define CLR_EN P6OUT&=~BIT5; //EN=0;
#define SET_EN P6OUT|=BIT5; //EN=1;
void delay1(uint z);
void write_com(uchar com);
void write_data(uchardat);
voidinit();
void display(void);
voidLocateXY(ucharx,uchar y);
void Disp1Char(ucharx,uchary,ucharDataByte);
voidDispStr(ucharx,uchary,uchar *ptr);
voidDispNChar(ucharx,uchar y, ucharn,uchar *ptr);
#include "includes.h"
void delay1(uint z)
{
uintt,y;
for(t=z;t>0;t--)
for(y=110;y>0;y--);
}
/////////////////写命令///////////////
void write_com(uchar com)
{
CLR_RS;
CLR_RW;
CLR_EN;
DATA_OUT=com;
delay1(20);
SET_EN;
CLR_EN;
delay1(20);
}
////////////////写数据///////////////
void write_data(uchardat)
{
SET_RS;
CLR_RW;
CLR_EN;
DATA_OUT=dat;
delay1(20);
SET_EN;
delay1(20);
CLR_EN;
delay1(20);
}
/////////////////液晶初始化/////////////
voidinit()
{
delay1(30);
write_com(0x38);
delay1(10);
write_com(0x38);
delay1(10);
write_com(0x38);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void display(void)
{
write_com(0x80+0x40);
write_data(0x31);
}
/******************************************* 131 函数名称:LocateXY
132 功能:向液晶输入显示字符位置的坐标信息133 参数:x--位置的列坐标0-15
134 y--位置的行坐标0-1
136 ********************************************/ voidLocateXY(ucharx,uchar y)
{
uchar temp;
temp = x&0x0f;
y&= 0x01;
if(y) temp |= 0x40; //如果在第2行
temp |= 0x80;//第一行为0x80,第二行为0x80+0x40
write_com(temp);
}
/*******************************************
149 函数名称:Disp1Char
150 功能:在某个位置显示一个字符
151 参数:x--位置的列坐标0-15
152 y--位置的行坐标0-1
153 data--显示的字符数据
154 返回值:无
155 ********************************************/ void Disp1Char(ucharx,uchary,ucharDataByte)
{
LocateXY( x, y );
write_data(DataByte );
}
/***********************************************
2 函数名称:DispStr
63 功能:让液晶从某个位置起连续显示一个字符串
64 参数:x--位置的列坐标0-15
65 y--位置的行坐标0-1
166 ptr--指向字符串存放位置的指针
167 返回值:无
168 ***********************************************/ voidDispStr(ucharx,uchary,uchar *ptr)
{
uchar *temp;
uchari,n = 0;
temp = ptr;
while(*ptr++ != '\0') n++; //计算字符串有效字符的个数
for (i=0;i { Disp1Char(x++,y,temp[i]); if (x == 0x0f) { x = 0; y ^= 1;//异或操作,换行 } } } /******************************************* 188 函数名称:DispNchar 189 功能:让液晶从某个位置起连续显示N个字符190 参数:x--位置的列坐标0-15 191 y--位置的行坐标0-1 192 n--字符个数 193 ptr--指向字符存放位置的指针 194 返回值:无 195 ********************************************/ voidDispNChar(ucharx,uchar y, ucharn,uchar *ptr) { uchari; for (i=0;i { Disp1Char(x++,y,ptr[i]); if (x == 0x0f) { x = 0; y ^= 1; } } }