[原创] 【LPC54100】iic读取MPU6050相关数据

youki12345   2015-5-24 15:28 楼主
既然要做自平衡车,那么小车姿态的获取就相当重要的,通常6050是首选,下面这段话来自与6050的手册: MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的IC或最高达20MHz的SPI(MPU-6050没有SPI)。MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VVDIO供电为1.8V± 5%(MPU6000仅用VDD)。MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。 可见,对于小型化的嵌入式系统来说,MPU6050是不二的选择。由于它采用的是IIC来进行通讯,因此我们必须在LPC上面实现IIC。 IIC通讯的方式一般有两种:软件模拟和硬件实现。由于硬件IIC的方式前面有朋友已经搞定了,所以我们最终还是选择采用软件模拟IIC的方式来做。开始我们还认为软件模拟的方式会出现速度跟不上的问题,后来发现担心完全是多余的。并且采用软件的方式还具有GPIO灵活的特点。
MYIIC.rar (1.33 KB)
(下载次数: 17, 2015-5-24 15:18 上传)
IIC头文件 #ifndef _MYIIC_H_ #define _MYIIC_H_ #include "board.h" #define IIC_SCL_OUT() {Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 10);} #define IIC_SCL_IN() {Chip_GPIO_SetPinDIRInput(LPC_GPIO, 0, 10);} #define IIC_SCL_1 {Chip_GPIO_SetPinState(LPC_GPIO, 0, 10, 1);} #define IIC_SCL_0 {Chip_GPIO_SetPinState(LPC_GPIO, 0, 10, 0);} #define IIC_SDA_OUT() {Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 11);} #define IIC_SDA_IN() {Chip_GPIO_SetPinDIRInput(LPC_GPIO, 0, 11);} #define IIC_SDA_1 {Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 1);} #define IIC_SDA_0 {Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 0);} #define IIC_SDA_READ (Chip_GPIO_ReadPortBit(LPC_GPIO, 0, 11)) //IIC所有操作函数 void IIC_Init(void); void IIC_Start(void); void IIC_Stop(void); void IIC_SendACK(unsigned char ack); unsigned char IIC_RecvACK(void); void IIC_Send_Byte(unsigned char dat); unsigned char IIC_Read_Byte(void); IIC实现文件 #include "myiic.h" void IIC_Delay() { int i; for(i=0;i<10;i++); } //初始化IIC void IIC_Init(void) { //Chip_GPIO_Init(LPC_GPIO); Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 10, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)); Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 11, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)); IIC_SCL_OUT() IIC_SDA_OUT() } //产生IIC起始信号 void IIC_Start(void) { IIC_SDA_OUT(); //sda线输出 IIC_SDA_1; IIC_SCL_1; IIC_Delay(); IIC_SDA_0;//START:when CLK is high,DATA change form high to low IIC_Delay(); IIC_SCL_0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { IIC_SDA_OUT();//sda线输出 IIC_SDA_0; IIC_SCL_1; IIC_Delay(); IIC_SDA_1; IIC_Delay(); } //************************************** //I2C发送应答信号 //入口参数:ack (0:ACK 1:NAK) //************************************** void IIC_SendACK(unsigned char ack) { if(ack==1) //写应答信号 IIC_SDA_1 else IIC_SDA_0; IIC_SCL_1; //拉高时钟线 IIC_Delay(); //延时 IIC_SCL_0; //拉低时钟线 IIC_Delay(); //延时 } //************************************** //I2C接收应答信号 //************************************** unsigned char IIC_RecvACK(void) { /* IIC_SDA_OUT(); IIC_SCL_0; IIC_Delay(); IIC_SDA_1; IIC_Delay(); IIC_SDA_IN(); IIC_SCL_1; //拉高时钟线 IIC_Delay(); //延时 if(IIC_SDA_READ) { IIC_SCL_0; return 0; } IIC_SCL_0; return 1;*/ IIC_SDA_IN(); IIC_SCL_1; //拉高时钟线 IIC_Delay(); //延时 if(IIC_SDA_READ) { IIC_SCL_0; return 0; } //读应答信号 IIC_SCL_0; //拉低时钟线 IIC_Delay(); //延时 return 1; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(unsigned char dat) { unsigned char i,a; IIC_SDA_OUT(); for (i=0; i<8; i++) { a=(dat>>(7-i))&1; if(a==1) IIC_SDA_1 else IIC_SDA_0; IIC_SCL_1; IIC_Delay(); IIC_SCL_0; IIC_Delay(); } //IIC_RecvACK(); } //读1个字节 unsigned char IIC_Read_Byte(void) { unsigned char i,dat=0; IIC_SDA_IN();//SDA设置为输入 for(i=0;i<8;i++) { dat<<=1; IIC_SCL_1; IIC_Delay(); if(IIC_SDA_READ==1) dat|=1; else dat|=0; IIC_SCL_0; IIC_Delay(); } IIC_SDA_OUT(); return dat; } 本帖最后由 youki12345 于 2015-5-24 15:32 编辑
https://bbs.eeworld.com.cn/thread-471646-1-1.html 欢迎加入我的团队

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复