硬件I2C(TWI)协议,串口显示(只显示Z方向加速度数据其他程序结构一样,本人只是需要Z方向,所以没全写上)
mpu.c
/
/***********************************
*程序名称:mpu6550
*设 计:why
*日 期:2012-07-19
*描 述:三轴数据通过串口发送到PC(硬件I2C也就是TWI)
************************************/
#include <iom16v.h>
#include "xiaofeng_delay.h"
void main()
{
uart_init(); /*串口初始化*/
InitMPU6050(); //三轴初始化
delay_nms(1000);
while(1)
{
Display10BitData();
delay_nms(1000);
}
}
twi.c
//
/*******************************
*程序名称:mpu6550
*设 计:why
*日 期:2012-07-19
*描 述:三轴数据通过串口发送到PC(硬件I2C也就是TWI)
********************************/
#include <iom16v.h>
/****************************
I2C 状态定义
MT 主方式传输 MR 主方式接受
***************************/
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK 0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
/*常用TWI操作(主模式写和读)*/
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
#define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
#define TestAck() (TWSR&0xf8) //观察返回状态
#define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
#define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR
//****************************************
// 定义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为读取
//****************************************
//定义类型及变量
//****************************************
unsigned char dis[6]; //显示数字(-511至512)的字符数组
/
/*延时子程序*/
void delay_ms(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<1000;i++);
}
/*串口初始化*/
void uart_init(void)
{
UCSRA=0x02; //异步正常模式
UCSRB=0x18; //允许发送接受中断和使能
UCSRC=0x06; //8位数据
UBRRH=0x00;
UBRRL=0x67; //波特率位9600
}
/*********************************************
I2C总线写一个字节
返回0:写成功
返回1:写失败
**********************************************/
unsigned char I2C_Write(unsigned char RegAddress,unsigned char Wdata)
{
Start(); //I2C启动
Wait();
if(TestAck()!=START)
return 1; //ACK
Write8Bit(SlaveAddress); //写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK)
return 1; //ACK
Write8Bit(RegAddress); //写器件相应寄存器地址
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Write8Bit(Wdata); //写数据到器件相应寄存器
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Stop(); //I2C停止
delay_ms(10); //延时
return 0;
}
/*********************************************
I2C总线读一个字节
返回0:读成功
返回1:读失败
**********************************************/
unsigned char I2C_Read(unsigned RegAddress)
{
unsigned char temp;
Start();//I2C启动
Wait();
if (TestAck()!=START)
return 1; //ACK
Write8Bit(SlaveAddress); //写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK)
return 1; //ACK
Write8Bit(RegAddress); //写器件相应寄存器地址
Wait();
if (TestAck()!=MT_DATA_ACK)
return 1;
Start(); //I2C重新启动
Wait();
if (TestAck()!=RE_START)
return 1;
Write8Bit(SlaveAddress+1); //写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK)
return 1; //ACK
Twi(); //启动主I2C读方式
Wait();
if(TestAck()!=MR_DATA_NOACK)
return 1; //ACK
temp=TWDR; //读取I2C接收数据
Stop(); //I2C停止
return temp;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050(void)
{
I2C_Write(PWR_MGMT_1, 0x00); //解除休眠状态
I2C_Write(SMPLRT_DIV, 0x07);
I2C_Write(CONFIG, 0x06);
I2C_Write(GYRO_CONFIG, 0x18);
I2C_Write(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(unsigned char REG_Address)
{
unsigned char H,L;
H=I2C_Read(REG_Address);
L=I2C_Read(REG_Address+1);
return (H<<8)+L; //合成数据
}
//****************************************
//整数转字符串
//****************************************
void lcd_printf(unsigned char *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;
}
//**************************************
//显示10位数据
//**************************************
void Display10BitData(void)
{
unsigned char i;
lcd_printf(dis,GetData(ACCEL_ZOUT_H)); //转换数据显示
for(i=0;i<6;i++)
{
while(!(UCSRA&(1<<UDRE)));
UDR=dis[i];
}
}
xiaofeng_delay.c
#include"xiaofeng_delay.h"
/**************************************************************
** 函数名称: void delay_1us(void)
** 功能描述: 1us延时函数
** 输 入: 无
** 全局变量: 无
** 调用模块: 无
** 说 明:
** 注 意:
**************************************************************/
void delay_1us(void)
{
asm("nop");
}
/**************************************************************
** 函数名称: void delay_nus(unsigned int n)
** 功能描述: N us延时函数
** 输 入: 无
** 全局变量: 无
** 调用模块: 无
** 说 明:
** 注 意:
**************************************************************/
void delay_nus(uint n)
{
uint i=0;
for(i=0;i<n;i++)
delay_1us();
}
/*******************************************
函数名称: void delay_nms(uint ms)
功 能: 延时指定毫秒(8M晶振)
参 数: ms--延时的毫秒数
返 回 值: 无
/********************************************/
void delay_nms(uint ms)
{
uint i,j;
for( i=0;i<ms;i++)
for(j=0;j<1141;j++);//1141是在8MHz晶振下,仿真得到的数值
}
xiaofeng_delay.h
/
#ifndef _XIAOFENG_DELAY_H_
#define _XIAOFENG_DELAY_H_
/******************数据类型宏定义******************/
#define uchar unsigned char
#define uint unsigned int
/******************延时函数的定义******************/
extern void delay_1us(void);
extern void delay_nus(uint n);
extern void delay_nms(uint z);
/********************config***********************/
extern void uart_init(void);
extern void InitMPU6050(void);
extern int GetData(uchar REG_Address);
extern unsigned char I2C_Read(unsigned RegAddress);
extern unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress);
extern void Display10BitData(void);
extern unsigned char dis[6];
extern void twi_init(void);
/
#endif