在最近做CC2530驱动MPU6050传感器的过程总遇到不少细节问题,在参考各种资料外加大神的知道终于能够完整的获取6维的数据而且实现实时更新,现将过程中出现的问题一一总结如下:
1.时序问题
由于MPU6050支持的是I2C通信,想要成功驱动MPU6050,正确的时钟信号是前提,针对MPU6050的通信流程对应编写正确的时序程序:
在CC2530对数据端口的配置过程中,注意每次SDA和SCL的数据方向,本实验中选择的是两个端口P1-0,P1-1,在I2C的时序配置上配合着上面的通信流程图根据需要需对SDA和SCL至高或至低,而且还需要配合相应的时延。网上搜到的好多资料在某些环节都缺少了数据方向的配置,所以导致时序混乱。
2.串口问题
MPU6050传感器感应到的数据通过I2C传给CC2530,CC2530需要将该数据通过串口发送给PC串口调试助手显示,这个过程相对简单无需多讲,唯一需要注意的是在主函数中的数据输出时的数据类型,该输出类型和从传感器相应地址得到的数据类型如果不兼容会在串口输出时出现乱码(本人在调试时因小误差导致输出乱码找了好久才定位到)。
3.示波器的作用
在本次试验中示波器起到了很大的作用,对着示波器可以定位一些时序的问题,对应着示波器可以进行相应的调试。
总结:
以上是本人在调试过程中的问题,因是新手所以可能会有好多问题,望大家指正,参考的文档有如下:
http://www.feibit.com/forum.php?mod=viewthread&tid=10459
本实验的连接图如下:
对应的部分程序分享如下:
void main(void)
{
int temp;
Init_IO();
wait_ms(500);
initUART();
wait_ms(500);
InitMPU6050();
while(1)
{
wait_ms(500);
Txdata[0]=GetData(ACCEL_XOUT_H);
Txdata[1]=GetData(ACCEL_XOUT_H+1);
Txdata[2]=GetData(ACCEL_YOUT_H);
Txdata[3]=GetData(ACCEL_YOUT_H+1);
Txdata[4]=GetData(ACCEL_ZOUT_H);
Txdata[5]=GetData(ACCEL_ZOUT_H+1);
Txdata[6]=GetData(GYRO_XOUT_H);
Txdata[7]=GetData(GYRO_XOUT_H+1);
Txdata[8]=GetData(GYRO_YOUT_H);
Txdata[9]=GetData(GYRO_YOUT_H+1);
Txdata[10]=GetData(GYRO_ZOUT_H);
Txdata[11]=GetData(GYRO_ZOUT_H+1);
Sendstr(Txdata,12);
wait_ms(1000);
}
}
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_data=0;
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=I2C_Read_Byte();
I2C_SendACK(1);
I2C_Stop(); //停止信号
return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_DIV, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x00);
Single_WriteI2C(ACCEL_CONFIG, 0x00);
}
//**************************************
//合成数据
//**************************************
s16 GetData(uchar REG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //合成数据
}
/******************************************************************************
* @fn wait_ms
*
* @brief
* Delay time milliseconds.
*
* Parameters:
*
* @param time
*
* @return void
*
******************************************************************************/
void wait_ms(uint16 time)
{
uint16 a;
unsigned short i;
for(i = 0;i < time;i++)
for(a = 1067;a > 0;a--)
asm("NOP");
}