电机对mpu6050 dmp影响很大怎么办

血与泪的教训,终于可以驱动mpu6050了 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
血与泪的教训,终于可以驱动mpu6050了
11:45:24  
101339&查看
论坛上对mpu6050的资料和讨论并不多,很多坛友都说驱动失败,老是显示0.
以下就谈谈我的一些血与泪的教训:
& &昨天开始接触mpu6050,在网上查了很多资料,下载程序,准备一展身手。首先看了mpu6050中文资料,之后又看了那个mpu6050的测试程序,把这些看明白之后就开始写程序了。我不是直接把程序复制过去,只是复制mpu6050的地址和初始化,IIC并没有复制,就复制我上次写的24C02的那个程序,想不到,这给了我血与泪的教训,我原来是直接把IIC复制过来的,并没有多留意。之后初始化mpu6050,写入地址,读出数据,下载到单片机之后,LCD上显示000001,我感到郁闷,之后又调试,以为是显示不对,又写显示,之后又下载,结果还是老样,这样半天就过去了。驱动没成功,又怀疑芯片或引脚有问题,继续调试,也没成功。就一一对应地看了地址,又看了初始化,发现没错,调试还是不成功。最后干脆不接IIC总线,竟然发现了个天大的秘密,接不接IIC,LCD都显示000001,我又用示波器测试波形,发现波形正确。在网上又查了别人的资料,在论坛上也很少有关于mpu6050的资料,也看了比别人的一些讨论。很多坛友都说驱动失败,老是显示0.
& &没办法,一天就这样过去了,今天早上,我又仔细看了程序,出乎我的想象,竟然是IIC的那个地址没改,原来写24C02的那个地址是a0,还是原封不动,把我吓了一跳。把这些改过来之后,一切正常,能显示加速度和陀螺仪。血与泪的教训啊,是自己不细心造成的,忘记改地址!今天早上竟然花了不到2个钟就调出来了,惊喜之时就写了这个分享,希望对大家有用。
还没经过软件滤波
23:16 上传
点击文件名下载附件
下载积分: 积分 -1 分
116.18 KB, 下载次数: 5286, 下载积分: 积分 -1 分
23:20:33  
网上要串口的MPU6050模块卖了,不用这么费劲了。人家做的还带卡尔曼滤波算法。
11:27:34  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
网上要串口的MPU6050模块卖了,不用这么费劲了。人家做的还带卡尔曼滤波算法。 ...
谢谢,不过不需要了吧,还是觉得IIC好。
14:44:30  
可以看下你的程序吗
09:37:48  
模块自带卡尔曼滤波吗?
16:05:30  
教教我{:20:}{:20:}
21:41:19  
我在调试MPU6050模块,不管有没有插上模块,串口返回值都是-1,楼主遇到过这个情况吗?应该怎么解决?
09:46:39  
我在调试MPU6050模块,不管有没有插上模块,串口返回值都是-1,楼主遇到过这个情况吗?应该怎么解决? ...
有可能是I2C总线地址不对,那次我调试的时候也是这种情况,检查你程序I2C里的那个地址,要和mpu6050那个地址一样。
21:06:45  
l楼主啊&&能让我看看你的程序吗 上天让我遇见你就是对我的眷顾啊&&请你救救我吧!
21:09:13  
楼主 能加QQ()聊一聊吗?你比我的老师靠谱多了!
16:28:16  
有可能是I2C总线地址不对,那次我调试的时候也是这种情况,检查你程序I2C里的那个地址,要和mpu6050那个 ...
谢谢楼主,今天人品爆发我的模块今天刚刚调通了。地址没有错,我没有添加应答信号,所以出错了。今天调试的时候用示波器对比51调好的程序的波形才发现的没有应答信号,加上之后人品就立马爆发了。。
16:30:47  
再说一次,楼主头像男猪脚眼神很有意思
09:39:38  
学习一下~~~
14:40:54  
你的数据准确么?还仅仅是驱动了?&&驱动很简答吧,关键是数据处理。
20:15:02  
请问引脚怎么接
02:02:07  
就是,我们好多时候偷懒两分钟反而用了更多时间
14:57:46  
谢谢楼主,今天人品爆发我的模块今天刚刚调通了。地址没有错,我没有添加应答信号,所以出错了。今天调试 ...
应答怎么加,能说说吗?我的单片机饿库就是没有应答,我也不知道怎么加,憋在I2C这里已经一周了。。。
15:47:16  
楼主你人品爆发。
高级工程师
16:40:31  
03:43:32  
正在用MPU6050模块
Powered by查看: 1737|回复: 5
用mpu6050时I2C读取速度太慢怎么办
滞后速度太大太大
I2C速度是比较慢,但还是可以用的啊,不会很大滞后
求解,i2c很慢
求解,i2c很慢
这个是i2c的特点。
i2c最大波特率为400k,实际上很多时候400k都不稳定的,一般都很慢的。
你好,为题解决了么?最近遇到同样问题,程序也是醉了,能分享一下么?
山外飞思卡尔智能车论坛这几天终于把51驱动mpu6050程序了 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
这几天终于把51驱动mpu6050程序了
17:36:00  
10031&查看
其实就是一个IIc通信
(393.86 KB, 下载次数: 346)
17:35 上传
助理工程师
19:13:47  
{:1:}{:1:}{:1:}
助理工程师
08:41:21  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
{:1:}{:1:}{:1:}
助理工程师
16:28:30  
{:1:}{:1:}{:1:}
21:30:00  
你好!我最近也在调这个,能把你的程序发我借鉴一下吗?我不知道怎么处理MPU6050输出的2进制补码
11:34:55  
能否发一份程序过来呢,我最近买了但不知咋用,求楼主大神急救。
20:10:16  
谢谢楼主慷慨赐程序
19:26:13  
楼主,还在么?求一份程序!顺便问一下:51可以用串口方式读取mpu6050么?救急救急!!!谢谢!!
19:27:26  
谢谢楼主慷慨赐程序
请问你还有那个程序的备份么?救急。谢谢!
19:31:42  
楼主,还在么?求一份程序!顺便问一下:51可以用串口方式读取mpu6050么?救急救急!!!谢谢!! ...
01:18:22  
楼主你好,第一次接触这个模块,没有找到想要的资料。如果你还有麻烦,能给我发一份么,我已经坐这一晚上了,看滤波,数据分析太不好过了……哎。帮帮忙吧,我的邮箱。谢谢。
16:18:27  
楼主有没mpu6050的原理图呀,网上的好像不行,求分享》》
16:12:07  
谢谢楼主的分享
23:52:22  
你好,我想问一下把驱动程序写好了,接下来要怎样的所测角度计算出来呢?帮帮忙,非常感谢
08:48:58  
想问一下这角度问题你是怎么解决的???
上网找了一下!!!但是不知道自己测出来的是不是准确的值!!
11:26:01  
谢了&&楼主&&求程序& &我邮箱是& &顺便问一下&&6050可以直接和单片机相连吗
11:37:37  
谢了&&楼主&&求程序& &我邮箱是& &顺便问一下&&6050可以直接和单片机相连吗
等待验证会员
16:42:38  
楼主,想要一份程序以及它与51单片机接口。。。感激不尽啊
助理工程师
01:07:21  
大神求程序谢谢谢谢谢谢
14:02:42  
楼主 还在吗?求程序& &谢谢!!
Powered by查看: 2147|回复: 16
MPU6050读到的数据跳动很大,有人知道为什么吗
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
MPU设置的寄存器的值读取正常,但是x轴
1c0cd72bb6b84a75ea9f00_859.jpg (0 Bytes, 下载次数: 0)
22:54 上传
457d9bba55ddf9ddbbe38_861.jpg (0 Bytes, 下载次数: 0)
22:54 上传
加速度计的值跳变的很厉害,有人知道为什么吗
主题帖子精华
中级会员, 积分 326, 距离下一级还需 174 积分
在线时间3 小时
你没有滤波吧
弹起华丽的乐章 撕下最后的伪装
主题帖子精华
中级会员, 积分 326, 距离下一级还需 174 积分
在线时间3 小时
加上电机。波动更大
弹起华丽的乐章 撕下最后的伪装
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【3楼】yy叶之舞是秋的讯息:
---------------------------------
没加电机呢,这波动太大了,知道为什么吗
主题帖子精华
金钱112030
在线时间794 小时
主题帖子精华
中级会员, 积分 326, 距离下一级还需 174 积分
在线时间3 小时
回复【4楼】yzx:
---------------------------------
窗口平滑滤波。也就是俗称的求平均数
弹起华丽的乐章 撕下最后的伪装
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【6楼】yy叶之舞是秋的讯息:
---------------------------------
是的,但是直接读取的这数据波动太大了也,一点都不正常啊,静态时上下差10000,太大了,总是能读到0值,这是不能理解的
主题帖子精华
中级会员, 积分 326, 距离下一级还需 174 积分
在线时间3 小时
回复【7楼】yzx:
---------------------------------
那估计是第一步读数据就出问题了、你从头到尾仔细看看程序。看哪里忘记写了
弹起华丽的乐章 撕下最后的伪装
主题帖子精华
中级会员, 积分 230, 距离下一级还需 270 积分
在线时间5 小时
楼主,我可以看看你和匿名上位机的通信协议吗?最近刚把MPU6050调试好,想用上位机观察一下数据,但不知道怎么写通信协议对这方面完全不懂,希望楼主可以指点一下!谢谢!!!
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【9楼】张晓斌:
---------------------------------
可以上优酷搜一下匿名上位机讲解&&有视频的&&并且程序中都有
主题帖子精华
高级会员, 积分 746, 距离下一级还需 254 积分
在线时间38 小时
使用&DMP&时,FIFO资料异步,所以要防止&FIFO&暴掉.
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【11楼】keyway:
---------------------------------
我这没有使用DMP,真不知道咋了
主题帖子精华
高级会员, 积分 746, 距离下一级还需 254 积分
在线时间38 小时
回复【12楼】yzx:
---------------------------------
我使用&DMP&方式,欧拉角与四元数都正常,但是陀螺数值会乱跳...
主题帖子精华
初级会员, 积分 105, 距离下一级还需 95 积分
在线时间13 小时
如果用的是外接模块&建议别用杜邦线。
主题帖子精华
金牌会员, 积分 1991, 距离下一级还需 1009 积分
在线时间189 小时
驱动有问题,采样频率或者数据传输有问题,这数据明显有问题。原始数据应该也是平滑的
彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
主题帖子精华
初级会员, 积分 123, 距离下一级还需 77 积分
在线时间7 小时
帮顶了,正在学习这方面的知识
主题帖子精华
初级会员, 积分 73, 距离下一级还需 127 积分
在线时间7 小时
如果用的是外接模块&建议别用杜邦线。
不使用杜邦线,外接模块有什么其他连接方式吗,用I2C方式的,求解答,大哥
Powered by1702人阅读
============================================================================
: ZTW_51.c
: clare_liu
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
//****************************************
// Update to MPU6050 by shinetop
// MCU: STC89C52
// 功能: 显示加速度计和陀螺仪的10位原始数据
//****************************************
// GY-52 MPU3050 IIC测试程序
// 使用单片机STC89C51
// 晶振:11.0592M
// 显示:LCD1602
// 编译环境 Keil uVision2
// 参考宏晶网站24c04通信程序
// 时间:日
//****************************************
#include &REG52.H&
#include &math.h&
//Keil library
#include &stdio.h&
//Keil library
#include &intrins.h&
//****************************************
// 定义51单片机端口
//****************************************
#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命令端口
sbit JDQ = P3 ^ 7; //继电器
//矩阵式键盘按键值的数码管显示实验
sbit P14 = P1 ^ 4; //将P14位定义为P1.4引脚
sbit P15 = P1 ^ 5; //将P15位定义为P1.5引脚
sbit P16 = P1 ^ 6; //将P16位定义为P1.6引脚
sbit P17 = P1 ^ 7; //将P17位定义为P1.7引脚
sbit P30 = P3 ^ 0;
unsigned char code Tab[ ]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9的段码
//定义变量储存按键值
//****************************************
// 定义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
#define TEMP_OUT_L
#define GYRO_XOUT_H
#define GYRO_XOUT_L
#define GYRO_YOUT_H
#define GYRO_YOUT_L
#define GYRO_ZOUT_H
#define GYRO_ZOUT_L
#define PWR_MGMT_1
0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I
0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
//****************************************
//定义类型及变量
//****************************************
////////////////////////////////////////////////////////
/******************************************************************************
*关于频率和占空比的确定,对于12M晶振,假定PWM输出频率为1KHZ,这样定时中断次数 *
*设定为C=10,即0.01MS中断一次,则TH0=FF,TL0=F6;由于设定中断时间为0.01ms,这样*
*可以设定占空比可从1-100变化。即0.01ms*100=1ms
******************************************************************************/
/*****************************************************************************
* TH0和TL0是计数器0的高8位和低8位计数器,计算办法:TL0=(65536-C)%256;
* TH0=(65536-C)/256,其中C为所要计数的次数即多长时间产生一次中断;TMOD是计数器*
* 工作模式选择,0X01表示选用模式1,它有16位计数器,最大计数脉冲为65536,最长时 *
* 间为1us*ms
******************************************************************************/
#define V_TH0
#define V_TL0
#define V_TMOD 0X11
uchar dis[4]; //显示数字(-511至512)的字符数组
int dis_ //变量
int Temperature, Temp_h, Temp_l; //温度及高低位数据
unsigned char ZKB1, ZKB2;
uchar head=2;
uchar slot_a=1;
uchar ch_a=3;
uchar ch_a_h=1;
//可调 1~2
uchar slot_b=1;
uchar ch_b=3;
uchar ch_b_h=1;
uchar slot_c=1;
uchar ch_c=3;
uchar ch_c_h=1;
uchar slot_d=1;
uchar ch_d=3;
uchar ch_d_h=1;
//****************************************
//函数声明
//****************************************
void delay(unsigned int k); //延时
//LCD相关函数
void InitLcd(); //初始化lcd1602
void lcd_printf(uchar *s, int temp_data);
void WriteDataLCM(uchar dataW); //LCD数据
void WriteCommandLCM(uchar CMD, uchar Attribc); //LCD指令
void DisplayOneChar(uchar X, uchar Y, uchar DData); //显示一个字符
void DisplayListChar(uchar X, uchar Y, uchar *DData, L); //显示字符串
//MPU6050操作函数
void InitMPU6050(); //初始化MPU6050
void Delay5us();
void I2C_Start();
void I2C_Stop();
void I2C_SendACK(bit ack);
bit I2C_RecvACK();
void I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void I2C_ReadPage();
void I2C_WritePage();
void display_ACCEL_x();
void display_ACCEL_y();
void display_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address); //读取I2C数据
void Single_WriteI2C(uchar REG_Address, uchar REG_data); //向I2C写入数据
//////////////////////////////////////////////////////////////////
void init_sys(void); /*系统初始化函数*/
void Delay5Ms(void);
//////////////////////////////////////////////////////////////////
/**************************************************************
函数功能:数码管动态扫描延时
**************************************************************/
void led_delay(void) {
for (j = 0; j & 200; j++)
/**************************************************************
函数功能:按键值的数码管显示子程序
**************************************************************/
void display(unsigned char k,unsigned char z) {
P2 = 0xf7; //点亮数码管DS0
P0 = Tab[z / 10]; //显示十位
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
P2 = 0 //点亮数码管DS1
P0 = Tab[z % 10]; //显示个位
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
P2 = 0 //点亮数码管DS6
P0 = Tab[k / 10]; //显示十位
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
P2 = 0x7f; //点亮数码管DS7
P0 = Tab[k % 10]; //显示个位
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
led_delay(); //动态扫描延时
/**************************************************************
函数功能:软件延时子程序
**************************************************************/
void delay20ms(void) {
unsigned char i,
for (i = 0; i & 100; i++)
for (j = 0; j & 60; j++)
//****************************************
//整数转字符串
//****************************************
void lcd_printf(uchar *s, int temp_data) {
if (temp_data & 0) {
temp_data = -temp_
*++s = temp_data / 100 + 0x30;
temp_data = temp_data % 100; //取余运算
*++s = temp_data / 10 + 0x30;
temp_data = temp_data % 10; //取余运算
*++s = temp_data + 0x30;
//****************************************
//延时 k 毫秒
//****************************************
void delayNms(unsigned int k) {
unsigned int i,
for (i = 0; i & i++) {
for (j = 0; j & 125; j++)
//****************************************
//LCD1602初始化
//****************************************
void InitLcd() {
WriteCommandLCM(0x38, 1);
WriteCommandLCM(0x08, 1);
WriteCommandLCM(0x01, 1);
WriteCommandLCM(0x06, 1);
WriteCommandLCM(0x0c, 1);
DisplayOneChar(0, 0, 'A');
DisplayOneChar(0, 1, 'G');
//****************************************
//LCD1602写允许
//****************************************
void WaitForEnable(void) {
DataPort = 0
LCM_RS = 0;
LCM_RW = 1;
LCM_EN = 1;
while (DataPort & 0x80)
LCM_EN = 0;
//****************************************
//LCD1602写入命令
//****************************************
void WriteCommandLCM(uchar CMD, uchar Attribc) {
if (Attribc)
WaitForEnable();
LCM_RS = 0;
LCM_RW = 0;
DataPort = CMD;
LCM_EN = 1;
LCM_EN = 0;
//****************************************
//LCD1602写入数据
//****************************************
void WriteDataLCM(uchar dataW) {
WaitForEnable();
LCM_RS = 1;
LCM_RW = 0;
DataPort = dataW;
LCM_EN = 1;
LCM_EN = 0;
//****************************************
//LCD1602写入一个字符
//****************************************
void DisplayOneChar(uchar X, uchar Y, uchar DData) {
X |= 0x40;
X |= 0x80;
WriteCommandLCM(X, 0);
WriteDataLCM(DData);
//****************************************
//LCD1602显示字符串
//****************************************
void DisplayListChar(uchar X, uchar Y, uchar *DData, L) {
uchar ListLength = 0;
while (L--) {
DisplayOneChar(X, Y, DData[ListLength]);
ListLength++;
//**************************************
//延时5微秒(STC90C52RC@12M)
//不同的工作环境,需要调整此函数
//当改用1T的MCU时,请调整此延时函数
//**************************************
void Delay5us() {
//**************************************
//I2C起始信号
//**************************************
void I2C_Start() {
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 0; //产生下降沿
Delay5us(); //延时
SCL = 0; //拉低时钟线
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop() {
SDA = 0; //拉低数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 1; //产生上升沿
Delay5us(); //延时
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(bit ack) {
SDA = //写应答信号
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
//**************************************
//I2C接收应答信号
//**************************************
bit I2C_RecvACK() {
SCL = 1; //拉高时钟线
Delay5us(); //延时
CY = SDA; //读应答信号
SCL = 0; //拉低时钟线
Delay5us(); //延时
return CY;
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(uchar dat) {
for (i = 0; i & 8; i++) //8位计数器
dat &&= 1; //移出数据的最高位
SDA = CY; //送数据口
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
I2C_RecvACK();
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte() {
uchar dat = 0;
SDA = 1; //使能内部上拉,准备读取数据,
for (i = 0; i & 8; i++) //8位计数器
dat &&= 1;
SCL = 1; //拉高时钟线
Delay5us(); //延时
dat |= SDA; //读数据
SCL = 0; //拉低时钟线
Delay5us(); //延时
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uchar REG_Address, uchar REG_data) {
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //内部寄存器地址,
I2C_SendByte(REG_data); //内部寄存器数据,
I2C_Stop(); //发送停止信号
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uchar Single_ReadI2C(uchar REG_Address) {
uchar REG_
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(); //停止信号
return REG_
//**************************************
//初始化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);
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address) {
char H, L;
H = Single_ReadI2C(REG_Address);
L = Single_ReadI2C(REG_Address + 1);
return (H && 8) + L; //合成数据
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(int value, uchar x, uchar y) {
value /= 64; //转换为10位数据
lcd_printf(dis, value); //转换数据显示
DisplayListChar(x, y, dis, 4); //启始列,行,显示数组,显示长度
//**************************************
//显示温度
//**************************************
void display_temp() {
Temp_h = Single_ReadI2C(TEMP_OUT_H); //读取温度
Temp_l = Single_ReadI2C(TEMP_OUT_L); //读取温度
Temperature = Temp_h && 8 | Temp_l; //合成温度
Temperature = 35 + ((double) (Temperature + 13200)) / 280; // 计算出温度
lcd_printf(dis, Temperature); //转换数据显示
DisplayListChar(11, 1, dis, 4); //启始列,行,显示数组,显示位数
void Delay5Ms(void) {
unsigned int TempCyc = 100000;
while (TempCyc--)
/******************************************************
*函数功能:对系统进行初始化,包括定时器初始化和变量初始化*/
void init_timer_interrupt(void) /*系统初始化函数*/
/*PWM定时器T0初始化,每隔0.2ms产生一次中断,共计100次,负责产生周期为20ms的PPM信号*/
TMOD = V_TMOD;
TH0 = V_TH0;
TL0 = V_TL0;
/*keyboard 定时器T1初始化,*/
TH1 = (65536 - 500) / 256; //定时器T0的高8位赋初值
TL1 = (65536 - 500) % 256; //定时器T0的高8位赋初值
keyval = 0x00; //按键值初始化为0
/*打开并使能中断,启动定时器T0和T1*/
// EA = 1; //开总中断
// ET0 = 1;
//定时器T0中断允许
// TR0 = 1;
//启动定时器T0
// ET1 = 1; //定时器T1中断允许
// TR1 = 1; //启动定时器T1
//允许使用外中断
//选择负跳变来触发外中断
//允许使用外中断
//选择负跳变来触发外中断
//*********************************************************
//*********************************************************
void main() {
/**************************/
/*****T0 & T1 initial******/
/**************************/
init_timer_interrupt();
/**************************/
/*****mpu6050 initial******/
/**************************/
delayNms(500);
//上电延时500ms
InitLcd();
//液晶初始化
InitMPU6050(); //初始化MPU6050
delayNms(150);
//上电延时150ms
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轴角速度
delayNms(500);
ZKB1 = 5; /*占空比初始值设定*/
ZKB2 = 99; /*占空比初始值设定*/
while (1) //无限循环
//keyboard event
display(keyval,ZKB1); //调用按键值的数码管显示子程序
led_delay(); //动态扫描延时
//hand event
if (!P1_4) //如果按了+键,增加占空比
Delay5Ms();
if (!P1_4) {
JDQ = ~JDQ;
if (!P1_5) //如果按了-键,减少占空比
Delay5Ms();
if (!P1_5) {
JDQ = ~JDQ;
/*对占空比值限定范围*/
if (ZKB1 & 10)
if (ZKB1 & 5)
ZKB1 = 10;
/**************************************************************
函数功能:外部中断1
**************************************************************/
void EXT_INIT0_interserve(void) interrupt 0 using 0
ZKB2 = 100 - ZKB1;
JDQ = ~JDQ;
/**************************************************************
函数功能:定时器T0的中断服务子程序,每隔0.2ms产生一次中断,重复100次,构成周期为20ms的周期信号(PPM信号)
**************************************************************/
void timer0_interserve(void) interrupt 1 using 1
static uchar click=0; /*中断次数计数器变量*/
TH0=V_TH0; /*恢复定时器初始值*/
TL0=V_TL0;
//启动定时器T0
if (click&100) click=0;
* 根据keyval值设置占空比ZKB1的大小(1~99),输出所需要的PPM信号
if (click&=ZKB1) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
{ P1_0=1; }
{ P1_0=0; }
/**************************************************************
函数功能:外部中断1
**************************************************************/
void EXT_INIT1_interserve(void) interrupt 2 using 2
ZKB2 = 100 - ZKB1;
JDQ = ~JDQ;
/**************************************************************
函数功能:定时器T1的中断服务子程序,进行键盘扫描,判断键位,产生中断间隔为500us=0.5ms
**************************************************************/
void timer1_interserve(void) interrupt 3 using 3 //定时器T1的中断编号为3,使用第3组寄存器
TR1=0; //关闭定时器T0
P1=0xf0;//所有行线置为低电平“0”,所有列线置为高电平“1”
if((P1&0xf0)!=0xf0)//列线中有一位为低电平“0”,说明有键按下
delay20ms();//延时一段时间、软件消抖
if((P1&0xf0)!=0xf0)//确实有键按下
P1=0 //第一行置为低电平“0”(P1.0输出低电平“0”)
if(P14==0)//如果检测到接P1.4引脚的列线为低电平“0”
keyval=1;//可判断是S1键被按下
if(P15==0)//如果检测到接P1.5引脚的列线为低电平“0”
keyval=2;//可判断是S2键被按下
if(P16==0)//如果检测到接P1.6引脚的列线为低电平“0”
keyval=3;//可判断是S3键被按下
if(P17==0)//如果检测到接P1.7引脚的列线为低电平“0”
keyval=4;//可判断是S4键被按下
P1=0//第二行置为低电平“0”(P1.1输出低电平“0”)
if(P14==0)//如果检测到接P1.4引脚的列线为低电平“0”
keyval=5;//可判断是S5键被按下
if(P15==0)//如果检测到接P1.5引脚的列线为低电平“0”
keyval=6;//可判断是S6键被按下
if(P16==0)//如果检测到接P1.6引脚的列线为低电平“0”
keyval=7;//可判断是S7键被按下
if(P17==0)//如果检测到接P1.7引脚的列线为低电平“0”
keyval=8;//可判断是S8键被按下
P1=0//第三行置为低电平“0”(P1.2输出低电平“0”)
if(P14==0)//如果检测到接P1.4引脚的列线为低电平“0”
keyval=9;//可判断是S9键被按下
if(P15==0)//如果检测到接P1.5引脚的列线为低电平“0”
keyval=10;//可判断是S10键被按下
if(P16==0)//如果检测到接P1.6引脚的列线为低电平“0”
keyval=11;//可判断是S11键被按下
if(P17==0)//如果检测到接P1.7引脚的列线为低电平“0”
keyval=12;//可判断是S12键被按下
P1=0xf7;//第四行置为低电平“0”(P1.3输出低电平“0”)
if(P14==0)//如果检测到接P1.4引脚的列线为低电平“0”
keyval=13;//可判断是S13键被按下
if(P15==0)//如果检测到接P1.5引脚的列线为低电平“0”
keyval=14;//可判断是S14键被按下
if(P16==0)//如果检测到接P1.6引脚的列线为低电平“0”
keyval=15;//可判断是S15键被按下
if(P17==0)//如果检测到接P1.7引脚的列线为低电平“0”
keyval=16;//可判断是S16键被按下
TR1=1; //开启定时器T0
TH1=()/256;//定时器T0的高8位赋初值
TL1=()%256;//定时器T0的高8位赋初值
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:17877次
排名:千里之外
(1)(1)(3)(3)(2)(2)(2)(2)

我要回帖

更多关于 mpu6050模块 的文章

 

随机推荐