前段時間由于項目需要,需要使用cc2530通過IIC讀取MPU6050的資料。發現網上并沒有代碼,很多文章都不是大家需要的,是以我想把我的cc2530驅動MPU6050的代碼粘出來與大家共同學習。我的項目是驅動MPU6050通過zigbee無線傳輸至協調器。下圖是我使用的硬體,看看是否一緻,不同的話可能幫不到您。
GY521點選檢查傳感器是否一緻
名稱 | MPU-6050子產品(3軸陀螺儀+3軸加速度) |
---|---|
使用晶片 | MPU-6050 |
供電電源 | 3-5V |
通信方式 | 标準IIC通信協定 |
晶片内置 | 16位AD轉化器、16位AD資料輸出 |
陀螺儀範圍 | ±250 500 1000 2000 º/s |
加速度範圍 | ±2±4±8±16g |
引腳間距 | 2.24mm |
CC2530是8051核心,但是絕不是那麼簡單的事情,cc2530晶片和51單片機一個很大的差別就是:
我們在代碼裡必須設定IO口的輸入輸出方向
也就是要設定每個端口的PXDIR是1還是0
是以說我們需要在寫IIC時序時,不斷地切換io口的輸入輸出方向
(也許你知道自己的代碼不能用的原因了吧)
以下是通過zigbee協定棧讀取MPU6050的全部驅動程式
/*描述:顯示加速度計和陀螺儀的6位原始資料
****************************************/
#include "ioCC2530.h"
#include "MPU6050.h"
#include "OnBoard.h"
#include "hal_types.h"
#define uint unsigned int
#define uchar unsigned char
int accX,accY,accZ,graX,graY,graZ;
//****************************************
//函數聲明
//****************************************
void WriteSDA_0(void);
void WriteSDA_1(void);
void WriteSCL_0(void);
void WriteSCL_1(void);
void ReadSDA(void);
void Init_IO(void);
void MPU6050_Start(void);
void MPU6050_Stop(void);
void MPU6050_SendACK(uchar ack);
uchar MPU6050_RecvACK(void);
void MPU6050_SendByte(uchar data);
uchar MPU6050_RecvByte(void);
void Single_Write_MPU6050(uchar REG_Address,uchar REG_data);
uchar Single_Read_MPU6050(uchar REG_Address);
void InitMPU6050(void);
void ALLInit(void);
void Multiple_read_MPU6050(void);
void delay_us(unsigned int u);
void ALLInit(void)
{
Init_IO();
InitMPU6050();
}
/****************us延時函數 32M晶振 單周期MCU********************/
void delay_us(unsigned int u)
{
u=4*u;
MicroWait(u);
}
/*****************************MPU6050*******************************/
void WriteSDA_0(void)
{
P0DIR|=0x40;
SDA=0;
}
void WriteSDA_1()
{
P0DIR|=0x40;
SDA=1;
}
void WriteSCL_0()
{
P0DIR|=0x80;
SCL=0;
}
void WriteSCL_1()
{
P0DIR|=0x80;
SCL=1;
}
void ReadSDA(void)//sda輸入,=0
{
P0DIR&=0xBF;
}
void Init_IO(void)
{
P0DIR|=0xc0;
P0SEL&=0x3f;
}
/**************************************
起始信号
**************************************/
void MPU6050_Start()
{
WriteSDA_1();
WriteSCL_1();
delay_us(5);
WriteSDA_0();
delay_us(5);
WriteSCL_0();
delay_us(5);
}
/**************************************
停止信号
**************************************/
void MPU6050_Stop()
{
WriteSDA_0();
WriteSCL_1();
delay_us(5);
WriteSDA_1();
}
//I2C發送應答信号
//入口參數:ack (0:ACK 1:NAK)
void MPU6050_SendACK(uchar ack)
{
SDA=ack; //寫應答信号
WriteSCL_1(); //拉高時鐘線
delay_us(5);//Delay5us(); //延時
WriteSCL_0(); //拉低時鐘線
delay_us(5);//Delay5us(); //延時
}
/**************************************
發送應答信号
**************************************/
uchar MPU6050_RecvACK()
{
ReadSDA();
WriteSCL_1(); //拉高時鐘線
delay_us(5);//Delay5us(); //延時
CY=SDA; //讀應答信号
WriteSCL_0(); //拉低時鐘線
delay_us(5);//Delay5us(); //延時
P0DIR|=0x00;
return CY;
}
/**************************************
向IIC總線發送一個位元組資料
**************************************/
void MPU6050_SendByte(uchar data)
{
uchar i;
SDA_OUT();
for(i=0;i<8;i++) //8位計數器
{
if(data&0x80)
{WriteSDA_1();}
else
{WriteSDA_0();}
data<<=1;
WriteSCL_1(); //拉高時鐘線
delay_us(5); //延時
WriteSCL_0(); //拉低時鐘線
delay_us(5); //延時
}
MPU6050_RecvACK();
}
/**************************************
從IIC總線接收一個位元組資料
**************************************/
uchar MPU6050_RecvByte()
{
uchar i;
uchar dat = 0;
WriteSDA_1(); //使能内部上拉,準備讀取資料,
for (i=0; i<8; i++) //8位計數器
{
dat <<= 1;
SCL = 1; //拉高時鐘線
delay_us(5); //延時
dat |= SDA; //讀資料
SCL = 0; //拉低時鐘線
delay_us(5); //延時
}
return dat;
}
//******單位元組寫入*******************************************
void Single_Write_MPU6050(uchar REG_Address,uchar REG_data)
{
MPU6050_Start(); //起始信号
MPU6050_SendByte(SlaveAddress); //發送裝置位址+寫信号
MPU6050_SendByte(REG_Address); //内部寄存器位址,
MPU6050_SendByte(REG_data); //内部寄存器資料,
MPU6050_Stop(); //發送停止信号
}
//********單位元組讀取*****************************************
uchar Single_Read_MPU6050(uchar REG_Address)
{
uchar REG_data;
MPU6050_Start(); //起始信号
MPU6050_SendByte(SlaveAddress); //發送裝置位址+寫信号
MPU6050_SendByte(REG_Address); //發送存儲單元位址,從0開始
MPU6050_Start(); //起始信号
MPU6050_SendByte(SlaveAddress+1); //發送裝置位址+讀信号
REG_data=MPU6050_RecvByte(); //讀出寄存器資料
MPU6050_SendACK(1); //接收應答信号
MPU6050_Stop(); //停止信号
return REG_data;
}
以上是cc2530全部底層采集的驅動代碼,(絕對可以使用)由于全部代碼内容太多,便不粘貼出來了,如果需要全部代碼,請在下方評論留下你的郵箱,親測百分之百可以使用,真心希望可以互相幫助到所有需要的朋友,共同進步,歡迎交流指導。
[email protected]