此篇以89C51单片机为主,实现MPU6050的应用。
这个显示屏有2行,每行可显示16个字符。
对于LCD详细操作1602液晶显示屏请参考相关文件和程序,此处不再赘述。
为了使代码简介清晰,我是对的LCD密封1602代码,便于调用。下面贴出来
sbit RS = P1^0; //定义端口 sbit RW = P1^1; sbit EN = P2^5; sbit DU = P2^0; sbit WE = P2^1; #define RS_CLR RS=0 #define RS_SET RS=1 #define RW_CLR RW=0 #define RW_SET RW=1 #define EN_CLR EN=0 #define EN_SET EN=1 #define DataPort P0 //**************************************** ///整数转字符串 //保存转换结果uchar类型字符数组 //函数只负责转换三位数的整数,如果实现更多的转换,可以修改代码 //**************************************** void lcd_printf(uchar *s,int temp_data) { if(temp_data<0) { temp_data=-temp_data; //temp_data负数转换为正数运算 *s='-'; ///此时字符串应从‘-’负号开始 } else *s=' '; ///正数字从空白字符开始 此时s[0]='-'或者‘ ’ * s =temp_data/100 0x30; ///百位数字转换ASCII码形式 s[1]千位数字ASCII码 temp_data=temp_data0; ///取余运算 * s =temp_data/10 0x30; //同样,这里有十位数字ASCII码,赋给s[2] temp_data=temp_data; ///取余运算 * s =temp_data 0x30; //得到个位数字的ASCII码,赋给s[3] } void cmg88()//关数码管,点阵函数 { DU=1; P0=0X00; DU=0; } /*------------------------------------------------ uS包含输入参数的延迟函数 unsigned char t,无返回值 unsigned char 定义无符号字符变量,其的范围是 0~255 晶振12在这里使用M,请使用汇编来准确延迟,大致延时 长度如下 T=tx2 5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,包含输入参数 unsigned char t,无返回值 unsigned char 它定义了无符号字符变量,其值的范围是 0~255 晶振12在这里使用M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延迟1mS DelayUs2x(245); DelayUs2x(245); } } /*------------------------------------------------ 判忙函数 ------------------------------------------------*/ bit LCD_Check_Busy(void) { DataPort= 0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET; return (bit)(DataPort & 0x80); } /*------------------------------------------------ 写命令函数 ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) { while(LCD_Check_Busy()); //忙就等 RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR; } /*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) { while(LCD_Check_Busy()); //忙就等 RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_(); EN_CLR; } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ void LCD_Clear(void) { LCD_Write_Com(0x01); DelayMs(5); } /*------------------------------------------------ 写字符串函数 ------------------------------------------------*/ void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) { if (y == 0) { LCD_Write_Com(0x80 x); //表示第一行 } else { LCD_Write_Com(0xC0 x); //表示第二行 } while (*s) { LCD_Write_Data( *s); s ; } } /*------------------------------------------------ 写入字符函数 ------------------------------------------------*/ void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0) { LCD_Write_Com(0x80 x); } else { LCD_Write_Com(0xC0 x); } LCD_Write_Data( Data); } /*------------------------------------------------ 初始化函数 ------------------------------------------------*/ void LCD_Init(void) { LCD_Write_Com(0x38); /*设置显示模式*/ DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); /*显示关闭*/ LCD_Write_Com(0x01); /*显示清屏*/ LCD_Write_Com(0x06); /*显示光标移动设置*/ DelayMs(5); LCD_Write_Com(0x0C); /*显示开和光标设置*/ }
使用此头文件时需要
cmg88();/关数码管,
LCD_Init()//液晶初始化
LCD_Clear();//清屏
之后就可以用了LCD_Write_Char写字符或使用函数LCD_Write_String写字符串。
常见总线有IIC总线,SPI总线等。IIC采用双线控制,接入设备简单,SPI四线(三线也可以),全双工作。
有关IIC以上文章为准:http://blog.csdn.net/yibu_refresh/article/details/23354245
这里也贴出
/********************************************* *IIC总线程序 void init()初始化 void write_add(uchar address,uchar date)写 uchar read_add(uchar address) 读 ***********************************************/ #define uchar unsigned char sbit sda=P2^0; sbit scl=P2^1; uchar a; void delay1() { ;; } void start() //开始信号 { sda=1; delay1(); scl=1; delay1(); sda=0; delay1(); } void stop() //停止 { sda=0; delay1(); scl=1; delay1(); sda=1; delay1(); } void respons() //应答 { uchar i; scl=1; delay1(); while((sda==1)&&(i<250))i++; scl=0; delay1(); } void init() { sda=1; delay1(); scl=1; delay1(); } void write_byte(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; scl=0; delay1(); sda=CY; delay1(); scl=1; delay1(); // scl=0; // delay(); } scl=0; delay1(); sda=1; delay1(); } uchar read_byte() { uchar i,k; scl=0; delay1(); sda=1; delay1(); for(i=0;i<8;i++) { scl=1; delay1(); k=(k<<1)|sda; scl=0; delay1(); } return k; } void write_add(uchar address,uchar date) { start(); write_byte(0xa0); respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); } uchar read_add(uchar address) { uchar date; start(); write_byte(0xa0); respons(); write_byte(address); respons(); start(); write_byte(0xa1); respons(); date=read_byte(); stop(); return date; }
3.MPU6050某些参数定义: //****************************************
// 定义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 //x轴加速度
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E //y轴加速度
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40 //z轴加速度
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44 //x轴角速度
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46 //y轴角速度
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48 //z轴角速度
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
write_add(PWR_MGMT_1, 0x00); //解除休眠状态
write_add(SMPLRT_DIV, 0x07);
write_add(CONFIG, 0x06);
write_add(GYRO_CONFIG, 0x18);
write_add(ACCEL_CONFIG, 0x01);
}
4.主程序:
/*
* MPU6050模块测试程序
* MCU: STC89C52
* OSCILLATOR:11.0592M
* LCD:LCD1602
*
*/
#include <REG52.H>
#include <math.h>
#include <stdio.h>
#include <INTRINS.H>
#include "IIC.h"
#include "LCD1602.h"
#include "MPU6050.h"
//****************************************
//定义类型及变量
//****************************************
uchar dis[4]; //显示数字(-511至512)的字符数组
//**************************************
//合成数据:从IIC总线上读取两次,合成16位数据
//**************************************
int GetData(uchar REG_Address)
{
char H,L;
H=read_add(REG_Address);
L=read_add(REG_Address+1);
return (H<<8)+L; //合成数据
}
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(int value,uchar x,uchar y)
{
value/=64; //转换为10位数据
lcd_printf(dis, value); //转换数据显示
LCD_Write_String(x,y,dis); //启始列,行,显示数组,显示长度
}
//*********************************************************
//主程序
//*********************************************************
void delay(uchar x)
{
uchar i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void main()
{
delay(500); //上电延时
LCD_Init(); //液晶初始化
init(); //IIC总线初始化
InitMPU6050(); //初始化MPU6050
delay(150);
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); //显示Z轴角速度
delay(500);
}
}
这样程序看起来就简单了许多,也方便了很多。