利用51单片机读取MPU9150中AK8975C的原始数据

来源:互联网 发布:怎么看10月经济数据 编辑:程序博客网 时间:2024/06/02 04:32
//利用51单片机,晶振11.0592,串口调试助手上波特率设置为9600,数据位8位,停止位1#include <REG51.H>  #include <math.h>    //Keil library  #include <stdio.h>   //Keil library #include <INTRINS.H>typedef unsigned char  uchar;typedef unsigned short ushort;typedef unsigned int   uint;//****************************************// 定义51单片机端口//****************************************#define DataPort P0     //LCD1602数据端口sbit    SCL=P2^2;           //IIC时钟引脚定义sbit    SDA=P2^3;           //IIC数据引脚定义//****************************************// 定义MPU6050内部地址//****************************************#define SMPLRT_DIV      0x19    //陀螺仪采样率,典型值:0x07(125Hz)#define CONFIG          0x1A    //低通滤波频率,典型值:0x06(5Hz)#define HXL             0X03#define HXH             0X04#define HYL             0X05#define HYH             0X06#define HZL             0X07#define HZH             0X08#define CNTL            0X0A#define INT_PIN_CFG     0X37#define USER_CTRL       0X6A#define MPU9150SLAADD   0XD0#define MAGADD          0X18#define PWR_MGMT_1      0x6B    //电源管理,典型值:0x00(正常启用)#define WHO_AM_I            0x75    //IIC地址寄存器(默认数值0x68,只读)//****************************************//定义类型及变量//****************************************uchar dis[6];                           //显示数字(-511至512)的字符数组int dis_data;                       //变量//****************************************//函数声明//****************************************void  delay(unsigned int k);                                        //延时                        void  lcd_printf(uchar *s,int temp_data);//MPU6050操作函数void  InitMPU6050();                                                    //初始化MPU6050void  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 Slave_Address,uchar REG_Address);                        //读取I2C数据void  Single_WriteI2C(uchar Slave_Address,uchar REG_Address,uchar REG_data);    //向I2C写入数据//****************************************//整数转字符串//****************************************void lcd_printf(uchar *s,int temp_data){    if(temp_data<0)    {        temp_data=-temp_data;        *s='-';    }    else *s=' ';    *++s =temp_data/10000+0x30;    temp_data=temp_data%10000;     //取余运算    *++s =temp_data/1000+0x30;    temp_data=temp_data%1000;     //取余运算    *++s =temp_data/100+0x30;    temp_data=temp_data%100;     //取余运算    *++s =temp_data/10+0x30;    temp_data=temp_data%10;      //取余运算    *++s =temp_data+0x30;   }//****************************************void  SeriPushSend(uchar send_data){    SBUF=send_data;      while(!TI);TI=0;      }//****************************************//延时//****************************************void delay(unsigned int k)  {                           unsigned int i,j;                   for(i=0;i<k;i++)    {                   for(j=0;j<121;j++);    }                       }//**************************************//延时5微秒(STC90C52RC@12M)//不同的工作环境,需要调整此函数//当改用1T的MCU时,请调整此延时函数//**************************************void Delay5us(){    _nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();}//**************************************//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 = ack;                  //写应答信号    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){    uchar i;    for (i=0; i<8; i++)         //8位计数器    {        dat <<= 1;              //移出数据的最高位        SDA = CY;               //送数据口        SCL = 1;                //拉高时钟线        Delay5us();             //延时        SCL = 0;                //拉低时钟线        Delay5us();             //延时    }    I2C_RecvACK();}//**************************************//从I2C总线接收一个字节数据//**************************************uchar I2C_RecvByte(){    uchar i;    uchar dat = 0;    SDA = 1;                    //使能内部上拉,准备读取数据,    for (i=0; i<8; i++)         //8位计数器    {        dat <<= 1;        SCL = 1;                //拉高时钟线        Delay5us();             //延时        dat |= SDA;             //读数据                       SCL = 0;                //拉低时钟线        Delay5us();             //延时    }    return dat;}//**************************************//向I2C设备写入一个字节数据//**************************************void Single_WriteI2C(uchar Slave_Address,uchar REG_Address,uchar REG_data){    I2C_Start();                  //起始信号    I2C_SendByte(Slave_Address);   //发送设备地址+写信号    I2C_SendByte(REG_Address);    //内部寄存器地址,    I2C_SendByte(REG_data);       //内部寄存器数据,    I2C_Stop();                   //发送停止信号}//**************************************//从I2C设备读取一个字节数据//**************************************uchar Single_ReadI2C(uchar Slave_Address,uchar REG_Address){    uchar REG_data;    I2C_Start();                   //起始信号    I2C_SendByte(Slave_Address);    //发送设备地址+写信号    I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始      I2C_Start();                   //起始信号    I2C_SendByte(Slave_Address+1);  //发送设备地址+读信号    REG_data=I2C_RecvByte();       //读出寄存器数据    I2C_SendACK(1);                //接收应答信号    I2C_Stop();                    //停止信号    return REG_data;}//**************************************//初始化MPU6050//**************************************void InitMPU6050(){    Single_WriteI2C(MPU9150SLAADD,PWR_MGMT_1,0x00); //解除休眠状态    Single_WriteI2C(MPU9150SLAADD,SMPLRT_DIV,0x07);    Single_WriteI2C(MPU9150SLAADD,CONFIG, 0x06);    Single_WriteI2C(MPU9150SLAADD,INT_PIN_CFG,0x02);    Single_WriteI2C(MPU9150SLAADD,USER_CTRL,0x00);    Single_WriteI2C(MAGADD,CNTL, 0x00);    delay(100);    Single_WriteI2C(MAGADD,CNTL, 0x01);}//**************************************//合成数据//**************************************int GetData(uchar REG_Address){    uchar H,L;    H=(Single_ReadI2C(MAGADD,REG_Address));    Single_WriteI2C(MAGADD,CNTL, 0x01);//此处非常关键,    //因为日本公司的数据手册上说,在单次测量模式下,每读取一次,    //会自动回归power down mode ,所以这里重新设置为单次测量模式    L=Single_ReadI2C(MAGADD,REG_Address-1);    Single_WriteI2C(MAGADD,CNTL, 0x01);    return (H<<8)+L;   //合成数据}//**************************************//在1602上显示10位数据//**************************************void Display10BitData(int value){  uchar i;//  value/=64;                          //转换为10位数据    lcd_printf(dis, value);         //转换数据显示    for(i=0;i<6;i++)    {    SeriPushSend(dis[i]);    }}void init_uart(){    TMOD=0x21;                  TH1=0xfd;                   TL1=0xfd;           SCON=0x50;    PS=1;      //串口中断设为高优先级别    TR0=1;     //启动定时器              TR1=1;    ET0=1;     //打开定时器0中断               ES=1;       EA=1;}//*********************************************************//主程序//*********************************************************void main(){     delay(500);     //上电延时           init_uart();    InitMPU6050();  //初始化MPU6050    delay(150);    while(1)    {        Display10BitData(GetData(HXH));         Display10BitData(GetData(HYH));        Display10BitData(GetData(HZH));         SeriPushSend(0x0d);         SeriPushSend(0x0a);//换行,回车        delay(100);    }}
0 0
原创粉丝点击