既然要做自平衡车,那么小车姿态的获取就相当重要的,通常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 编辑