msp430 控制mpu6050电赛分享
- 格式:docx
- 大小:18.50 KB
- 文档页数:12
#include <msp430x14x.h>#include <math.h>#define uchar unsigned char#define ushort unsigned short#define uint unsigned int//*********************************************************#define CPU_F ((double)8000000)#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define P55 5#define P56 6#define P57 7#define RS_CLR P5OUT &= ~(1 << P55) //RS置低#define RS_SET P5OUT |= (1 << P55) //RS置高#define RW_CLR P5OUT &= ~(1 << P56) //RW置低#define RW_SET P5OUT |= (1 << P56) //RW置高#define EN_CLR P5OUT &= ~(1 << P57) //E置低#define EN_SET P5OUT |= (1 << P57) //E置高#define DataPort P4OUT //P4口为数据口//************************************************************************* // 系统时钟初始化//************************************************************************* void Clock_Init(){uchar i;BCSCTL1&=~XT2OFF; //打开XT振荡器BCSCTL2 |= SELM_2 + SELS; //MCLK为8MHZ,SMCLK为8MHZdo{IFG1&=~OFIFG; //清除震荡标志for(i=0;i<100;i++)_NOP(); //延时等待}while((IFG1&OFIFG)!=0); //如果标志为1,则继续循环等待IFG1&=~OFIFG;}//************************************************************************* // MSP430内部看门狗初始化//************************************************************************* void WDT_Init(){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗}//************************************************************************* // 初始化IO口子程序//************************************************************************* void Port_init(){P4SEL = 0x00;P4DIR = 0xFF;P5SEL = 0x00;P5DIR|= BIT5 + BIT6 + BIT7; //控制口设置为输出模式}//*********************************************************************** // 显示屏命令写入函数//***********************************************************************void LCD_write_com(unsigned char com){RS_CLR;RW_CLR;EN_SET;DataPort = com; //命令写入端口delay_us(50);EN_CLR;}//*********************************************************************** // 显示屏数据写入函数//***********************************************************************void LCD_write_data(unsigned char data){RS_SET;RW_CLR;EN_SET;DataPort = data; //数据写入端口delay_us(50);EN_CLR;}//*********************************************************************** // 显示屏清空显示//***********************************************************************void LCD_clear(void){LCD_write_com(0x01); //清屏幕显示delay_ms(5);}//*********************************************************************** // 显示屏字符串写入函数//***********************************************************************void LCD_write_str(unsigned char x,unsigned char y,uchar *s){if (y == 0){LCD_write_com(0x80 + x); //第一行显示}else{LCD_write_com(0xC0 + x); //第二行显示}while (*s){LCD_write_data( *s);s ++;}}//*********************************************************************** // 显示屏单字符写入函数//***********************************************************************void LCD_write_char(unsigned char x,unsigned char y,unsigned char data){if (y == 0){LCD_write_com(0x80 + x); //第一行显示}else{LCD_write_com(0xC0 + x); //第二行显示}LCD_write_data( data);}//***********************************************************************// 显示屏初始化函数//***********************************************************************void LCD_init(void){LCD_write_com(0x38); //显示模式设置delay_ms(5);LCD_write_com(0x08); //显示关闭delay_ms(5);LCD_write_com(0x01); //显示清屏delay_ms(5);LCD_write_com(0x06); //显示光标移动设置delay_ms(5);LCD_write_com(0x0C); //显示开及光标设置delay_ms(5);}//***************************************#define SDA BIT1#define SCL BIT2//****************************************// 定义MPU6050内部地址//****************************************#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) #define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)#define ACCEL_XOUT_H 0x3B#define ACCEL_XOUT_L 0x3C#define ACCEL_YOUT_H 0x3D#define ACCEL_YOUT_L 0x3E#define ACCEL_ZOUT_H 0x3F#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43#define GYRO_XOUT_L 0x44#define GYRO_YOUT_H 0x45#define GYRO_YOUT_L 0x46#define GYRO_ZOUT_H 0x47#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取uchar dis[4]; //显示数字(-511至512)的字符数组int dis_data; //变量//MPU6050操作函数void InitMPU6050(); //初始化MPU6050void I2C_Start();void I2C_Stop();void I2C_SendACK(uchar ack);uchar 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 REG_Address); //读取I2C数据void Single_WriteI2C(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/100+0x30;temp_data=temp_data%100; //取余运算*++s =temp_data/10+0x30;temp_data=temp_data%10; //取余运算*++s =temp_data+0x30;}//************************************** //SDA高电平的产生//************************************** void sda_high() //SDA高电平的产生{P1DIR|=SDA;P1OUT|=SDA;_NOP();_NOP();_NOP();return;}//************************************** //SDA低电平的产生//************************************** void sda_low() //SDA低电平的产生{P1DIR|=SDA;P1OUT&=~SDA;_NOP();_NOP();_NOP();return;}//************************************** //SCL高电平产生//************************************** void scl_high() //SCL高电平产生{P1DIR|=SCL;P1OUT|=SCL;_NOP();_NOP();_NOP();return;}//************************************** //SCL低电平的产生//**************************************void scl_low() //SCL低电平的产生{P1DIR|=SCL;P1OUT&=~SCL;_NOP();_NOP();_NOP();return;}//**************************************//I2C起始信号//************************************** void I2C_Start(){sda_high(); //拉高数据线scl_high(); //拉高时钟线delay_us(5); //延时sda_low(); //产生下降沿delay_us(5); //延时scl_low(); //拉低时钟线}//**************************************//I2C停止信号//************************************** void I2C_Stop(){sda_low(); //拉低数据线scl_high(); //拉高时钟线delay_us(5); //延时sda_high(); //产生上升沿delay_us(5); //延时}//**************************************//I2C发送应答信号//入口参数:ack (0:ACK 1:NAK)//************************************** void I2C_SendACK(uchar ack){if(ack) sda_high();else sda_low(); //写应答信号scl_high(); //拉高时钟线delay_us(5); //延时scl_low(); //拉低时钟线delay_us(5); //延时}//**************************************//I2C接收应答信号//************************************** uchar I2C_RecvACK(){uchar cy;scl_high(); //拉高时钟线P1DIR&=~SDA;delay_us(5); //延时if((P1IN&SDA)==SDA){cy=1;}else{cy=0;}// cy = SDA; //读应答信号scl_low(); //拉低时钟线delay_us(5); //延时P1DIR|=SDA;return cy;}//**************************************//向I2C总线发送一个字节数据//************************************** void I2C_SendByte(uchar dat){uchar i;for (i=0; i<8; i++) //8位计数器{if((dat<<i)&0x80){sda_high();}else{sda_low();}// SDA = cy; //送数据口scl_high(); //拉高时钟线delay_us(5); //延时scl_low(); //拉低时钟线delay_us(5); //延时}I2C_RecvACK();}//**************************************//从I2C总线接收一个字节数据//**************************************uchar I2C_RecvByte(){uchar i;uchar dat = 0,cy;sda_high(); //使能内部上拉,准备读取数据, P1DIR&=~SDA;for (i=0; i<8; i++) //8位计数器{dat <<= 1;scl_high(); //拉高时钟线delay_us(5); //延时if((P1IN&SDA)==SDA){cy=1;}else{cy=0;}dat |= cy; //读数据scl_low(); //拉低时钟线delay_us(5); //延时}P1DIR|=SDA;return dat;}//**************************************//向I2C设备写入一个字节数据//**************************************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;I2C_Start(); //起始信号I2C_SendByte(SlaveAddress); //发送设备地址+写信号I2C_SendByte(REG_Address); //发送存储单元地址,从0开始I2C_Start(); //起始信号I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号REG_data=I2C_RecvByte(); //读出寄存器数据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, 0x18);Single_WriteI2C(ACCEL_CONFIG, 0x01);}//**************************************//合成数据//**************************************int GetData(uchar REG_Address){char H,L;H=Single_ReadI2C(REG_Address);L=Single_ReadI2C(REG_Address+1);return (H<<8)+L; //合成数据}//**************************************//在12864上显示10位数据//**************************************void Display10BitData(int value,uchar x,uchar y){value/=64; //转换为10位数据lcd_printf(dis, value); //转换数据显示LCD_write_str(x,y,dis);//启始列,行,显示数组,显示长度}//主程序//*********************************************************void main(){ double y_j,x_j,z_j;WDTCTL=WDTPW+WDTHOLD; //关闭看门狗Clock_Init(); //系统时钟设置Port_init(); //系统初始化,设置IO口属性delay_ms(100); //延时100msLCD_init(); //液晶参数初始化设置LCD_clear();//CPU空转delay_ms(500); //上电延时InitMPU6050(); //初始化MPU6050delay_ms(150);while(1){ // //*********************************************************//LCD_write_str(0,0,"Tian jin University");x_j=(asin((double)(GetData(ACCEL_XOUT_H)/263.0/64.0))*180)/3.1415;y_j=(asin((double)(GetData(ACCEL_YOUT_H)/259.0/64.0))*180)/3.1415;z_j=(asin((double)(GetData(ACCEL_ZOUT_H)/257.0/64.0))*180)/3.1415;Display10BitData(GetData(ACCEL_XOUT_H),0,0); //显示X轴加速度Display10BitData(GetData(ACCEL_YOUT_H),4,0); //显示Y轴加速度Display10BitData(GetData(ACCEL_ZOUT_H),8,0); //显示Z轴加速度if(x_j>=0){ LCD_write_char(0,1,' ');}if(x_j<0){x_j=fabs(x_j); LCD_write_char(0,1,'-');}LCD_write_char(1,1,(int)(x_j)/100+48); //显示X轴角速度LCD_write_char(2,1,((int)(x_j)%100)/10+48); //显示Y轴角速度LCD_write_char(3,1,((int)(x_j)%10)+48); //显示Z轴角速度if(y_j>=0){ LCD_write_char(4,1,' ');}if(y_j<0){y_j=fabs(y_j); LCD_write_char(4,1,'-');}LCD_write_char(5,1,(int)(y_j)/100+48); //显示X轴角速度LCD_write_char(6,1,((int)(y_j)%100)/10+48); //显示Y轴角速度LCD_write_char(7,1,((int)(y_j)%10)+48); //显示Z轴角速度if(z_j>=0){ LCD_write_char(8,1,' ');}if(z_j<0){z_j=fabs(z_j); LCD_write_char(8,1,'-');}LCD_write_char(9,1,(int)(z_j)/100+48); //显示X轴角速度LCD_write_char(10,1,((int)(z_j)%100)/10+48); //显示Y轴角速度LCD_write_char(11,1,((int)(z_j)%10)+48); //显示Z轴角速度/* Display10BitData(GetData(GYRO_XOUT_H),0,1); //显示X轴角速度Display10BitData(GetData(GYRO_YOUT_H),4,1); //显示Y轴角速度Display10BitData(GetData(GYRO_ZOUT_H),8,1); //显示Z轴角速度*/delay_ms(500);}}。