走过路过,不要错过
GY-52三轴陀螺仪的测试代码(基于51单片机):
- //***************************************
- // GY-52 MPU3050 IIC测试程序
- // 使用单片机STC89C51
- // 晶振:11.0592M
- // 显示:LCD1602
- //****************************************
- #include <REG51.H>
- #include <math.h> //Keil library
- #include <stdio.h> //Keil library
- #include <INTRINS.H>
- #define uchar unsigned char
- #define uint unsigned int
- #define DataPort P0 //LCD1602数据端口
- sbit SCL=P1^0; //IIC时钟引脚定义
- sbit SDA=P1^1; //IIC数据引脚定义
- sbit LCM_RS=P2^0; //LCD1602命令端口
- sbit LCM_RW=P2^1; //LCD1602命令端口
- sbit LCM_EN=P2^2; //LCD1602命令端口
- //定义MPU3050内部地址********************
- #define WHO 0x00
- #define SMPL 0x15
- #define DLPF 0x16
- #define INT_C 0x17
- #define INT_S 0x1A
- #define TMP_H 0x1B
- #define TMP_L 0x1C
- #define GX_H 0x1D
- #define GX_L 0x1E
- #define GY_H 0x1F
- #define GY_L 0x20
- #define GZ_H 0x21
- #define GZ_L 0x22
- #define PWR_M 0x3E
- //****************************
- #define SlaveAddress 0xD0 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- uchar dis[4]; //显示数组
- BYTE BUF[8]; //接收数据缓存区
- int dis_data; //变量
- int Temperature,Temp_h,Temp_l;
- void delay(unsigned int k);
- void InitLcd(); //初始化lcd1602
- void InitMPU3050(); //初始化MPU3050
- void WriteDataLCM(uchar dataW);
- void WriteCommandLCM(uchar CMD,uchar Attribc);
- void DisplayOneChar(uchar X,uchar Y,uchar DData);
- void DisplayListChar(uchar X,uchar Y,uchar *DData,L);
- void Single_WriteMPU3050(uchar REG_Address,uchar REG_data); //单个写入数据
- uchar Single_ReadMPU3050(uchar REG_Address); //单个读取内部寄存器数据
- //****************************************模拟IIC使用函数
- void Delay5us();
- void MPU3050_Start();
- void MPU3050_Stop();
- void MPU3050_SendACK(bit ack);
- bit MPU3050_RecvACK();
- void MPU3050_SendByte(BYTE dat);
- BYTE MPU3050_RecvByte();
- void MPU3050_ReadPage();
- void MPU3050_WritePage();
- //****************************************
- void display_x();
- void display_y();
- void display_z();
- //****************************************
- void lcd_printf(uchar *s,int temp_data)
- {
- if(temp_data<0){
- temp_data=-temp_data;
- *s='-';
- }
- else *s=' ';
- *++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 delay(unsigned int k)
- {
- unsigned int i,j;
- for(i=0;i<k;i++)
- {
- for(j=0;j<121;j++)
- {;}}
- }
- /*******************************/
- void WaitForEnable(void)
- {
- DataPort=0xff;
- LCM_RS=0;LCM_RW=1;_nop_();
- LCM_EN=1;_nop_();_nop_();
- while(DataPort&0x80);
- LCM_EN=0;
- }
- /*******************************/
- void WriteCommandLCM(uchar CMD,uchar Attribc)
- {
- if(Attribc)WaitForEnable();
- LCM_RS=0;LCM_RW=0;_nop_();
- DataPort=CMD;_nop_();
- LCM_EN=1;_nop_();_nop_();LCM_EN=0;
- }
- /*******************************/
- void WriteDataLCM(uchar dataW)
- {
- WaitForEnable();
- LCM_RS=1;LCM_RW=0;_nop_();
- DataPort=dataW;_nop_();
- LCM_EN=1;_nop_();_nop_();LCM_EN=0;
- }
- /***********************************/
- void InitLcd()
- {
- WriteCommandLCM(0x38,1);
- WriteCommandLCM(0x08,1);
- WriteCommandLCM(0x01,1);
- WriteCommandLCM(0x06,1);
- WriteCommandLCM(0x0c,1);
- DisplayOneChar(0,0,'x');
- DisplayOneChar(1,0,':');
- DisplayOneChar(0,1,'y');
- DisplayOneChar(1,1,':');
- DisplayOneChar(9,0,'z');
- DisplayOneChar(10,0,':');
- DisplayOneChar(9,1,'T');
- DisplayOneChar(10,1,':');
- }
- /***********************************/
- void DisplayOneChar(uchar X,uchar Y,uchar DData)
- {
- Y&=1;
- X&=15;
- if(Y)X|=0x40;
- X|=0x80;
- WriteCommandLCM(X,0);
- WriteDataLCM(DData);
- }
- /***********************************/
- void DisplayListChar(uchar X,uchar Y,uchar *DData,L)
- {
- uchar ListLength=0;
- Y&=0x1;
- X&=0xF;
- while(L--)
- {
- DisplayOneChar(X,Y,DData[ListLength]);
- ListLength++;
- X++;
- }
- }
- /**************************************
- 延时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_();
- }
- /**************************************
- 起始信号
- **************************************/
- void MPU3050_Start()
- {
- SDA = 1; //拉高数据线
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- SDA = 0; //产生下降沿
- Delay5us(); //延时
- SCL = 0; //拉低时钟线
- }
- /**************************************
- 停止信号
- **************************************/
- void MPU3050_Stop()
- {
- SDA = 0; //拉低数据线
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- SDA = 1; //产生上升沿
- Delay5us(); //延时
- }
- /**************************************
- 发送应答信号
- 入口参数:ack (0:ACK 1:NAK)
- **************************************/
- void MPU3050_SendACK(bit ack)
- {
- SDA = ack; //写应答信号
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- SCL = 0; //拉低时钟线
- Delay5us(); //延时
- }
- /**************************************
- 接收应答信号
- **************************************/
- bit MPU3050_RecvACK()
- {
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- CY = SDA; //读应答信号
- SCL = 0; //拉低时钟线
- Delay5us(); //延时
- return CY;
- }
- /**************************************
- 向IIC总线发送一个字节数据
- **************************************/
- void MPU3050_SendByte(BYTE dat)
- {
- BYTE i;
- for (i=0; i<8; i++) //8位计数器
- {
- dat <<= 1; //移出数据的最高位
- SDA = CY; //送数据口
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- SCL = 0; //拉低时钟线
- Delay5us(); //延时
- }
- MPU3050_RecvACK();
- }
- /**************************************
- 从IIC总线接收一个字节数据
- **************************************/
- BYTE MPU3050_RecvByte()
- {
- BYTE i;
- BYTE dat = 0;
- SDA = 1; //使能内部上拉,准备读取数据,
- for (i=0; i<8; i++) //8位计数器
- {
- dat <<= 1;
- SCL = 1; //拉高时钟线
- Delay5us(); //延时
- dat |= SDA; //读数据
- SCL = 0; //拉低时钟线
- Delay5us(); //延时
- }
- return dat;
- }
- //单字节写入*******************************************
- void Single_WriteMPU3050(uchar REG_Address,uchar REG_data)
- {
- MPU3050_Start(); //起始信号
- MPU3050_SendByte(SlaveAddress); //发送设备地址+写信号
- MPU3050_SendByte(REG_Address); //内部寄存器地址,
- MPU3050_SendByte(REG_data); //内部寄存器数据,
- MPU3050_Stop(); //发送停止信号
- }
- //单字节读取*****************************************
- uchar Single_ReadMPU3050(uchar REG_Address)
- { uchar REG_data;
- MPU3050_Start(); //起始信号
- MPU3050_SendByte(SlaveAddress); //发送设备地址+写信号
- MPU3050_SendByte(REG_Address); //发送存储单元地址,从0开始
- MPU3050_Start(); //起始信号
- MPU3050_SendByte(SlaveAddress+1); //发送设备地址+读信号
- REG_data=MPU3050_RecvByte(); //读出寄存器数据
- MPU3050_SendACK(1);
- MPU3050_Stop(); //停止信号
- return REG_data;
- }
- //初始化MPU3050,根据需要请参考pdf进行修改************************
- void InitMPU3050()
- {
- Single_WriteMPU3050(PWR_M, 0x80); //
- Single_WriteMPU3050(SMPL, 0x07); //
- Single_WriteMPU3050(DLPF, 0x1E); //±2000°
- Single_WriteMPU3050(INT_C, 0x00 ); //
- Single_WriteMPU3050(PWR_M, 0x00); //
- }
复制代码
|