江科大STM32学习记录
I2C时序基本单元
void myIIC_Start(void)//SCL高电平期间,sda产生一个下升沿
{
Set_SDA(1);
Set_SCL(1);
Set_SDA(0);
Set_SCL(0);
}
void myIIC_Stop(void)//SCL高电平期间,sda产生一个上升沿
{
Set_SCL(1);
Set_SDA(0);
Set_SDA(1);
}
I2C时序基本单元
void myIIC_SendByte(uint8_t Byte)//SCL低电平,主机把数据放到SDA线上,SCL高电平,从机读取SDA上的数据
{
uint8_t i;
for(i=0;i<8;i++){
Set_SDA(Byte & (0x80>>i));
Set_SCL(1);
Set_SCL(0);
}
}
I2C时序基本单元
uint8_t myIIC_ReceByte(void)//SCL低电平,从机把数据放到SDA线上,SCL高电平,主机读取SDA上的数据
{
uint8_t Rece_Byte = 0x00;
uint8_t i;
Set_SDA(1);//释放sda总线
for(i=0;i<8;i++){
Set_SCL(1);
if(Read_SDA() == 1){
Rece_Byte |= (0x80 >> i);
}
Set_SCL(0);
}
return Rece_Byte;
}
void myIIC_SendACK(uint8_t AckBit)
{
Set_SDA(AckBit);
Set_SCL(1);
Set_SCL(0);
}
uint8_t myIIC_ReceACK(void)
{
uint8_t AckBit;
Set_SDA(1);//释放sda总线
Set_SCL(1);
AckBit = Read_SDA();
Set_SCL(0);
return AckBit;
}
void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{
myIIC_Start();
myIIC_SendByte(Slave);
myIIC_ReceACK();
myIIC_SendByte(RegAddress);
myIIC_ReceACK();
myIIC_SendByte(Data);
myIIC_ReceACK();
myIIC_Stop();
}
uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{
uint8_t temp;
myIIC_Start();
myIIC_SendByte(Slave);
myIIC_ReceACK();
myIIC_SendByte(RegAddress);
myIIC_ReceACK();
//上面为指定地址
myIIC_Start();//重复起始
myIIC_SendByte(Slave | 0x01);//低位1表示读操作
myIIC_ReceACK();
temp = myIIC_ReceByte();
myIIC_SendACK(1);//不应答
myIIC_Stop();
return temp;
#include "MPU6050.h"
void MPU6050_Init(void)
{
myIIC_Init();
Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_1,0x01);
Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_2,0x00);
Specify_Address_Write(MPU6050_Address,MPU6050_SMPLRT_DIV,0x09);
Specify_Address_Write(MPU6050_Address,MPU6050_CONFIG,0x06);
Specify_Address_Write(MPU6050_Address,MPU6050_GYRO_CONFIG,0x18);
Specify_Address_Write(MPU6050_Address,MPU6050_ACCEL_CONFIG,0x18);
}
uint8_t MCU6050_GetID(void)
{
return Specify_Address_Read(MPU6050_Address,MPU6050_WHO_AM_I);
}
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
uint8_t data_H;
uint8_t data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_L);
*AccX = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_L);
*AccY = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_L);
*AccZ = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_L);
*GyroX = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_L);
*GyroY = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_L);
*GyroZ = (data_H<<8) | data_L;
}
#ifndef _MPU6050_H
#define _MPU6050_H
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "myIIC.h"
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C
#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48
#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#define MPU6050_Address 0xD0
void MPU6050_Init(void);
uint8_t MCU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);
#endif
//超时退出机制
uint8_t Check_Timeout(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t time = 5000;
while(I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS){
time -- ;
if(time == 0){
return Timeout;
}
}
return SUCCESS;
}
void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);
Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
I2C_SendData(I2C2,RegAddress);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);
I2C_SendData(I2C2,Data);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);
I2C_GenerateSTOP(I2C2,ENABLE);
}
uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{
uint8_t ReceData;
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);
Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
I2C_SendData(I2C2,RegAddress);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Receiver);
Check_Timeout(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
I2C_AcknowledgeConfig(I2C2,DISABLE);
I2C_GenerateSTOP(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);
ReceData = I2C_ReceiveData(I2C2);
I2C_AcknowledgeConfig(I2C2,ENABLE);
return ReceData;
}
硬件I2C读取MPU6050数据
#include "I2C.h"
void I2C_init(void)
{
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//GPIO初始化
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//指定I2C模式。
I2C_InitStructure.I2C_ClockSpeed = 200000;//指定时钟频率
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//作为从机地址为7位
I2C_InitStructure.I2C_OwnAddress1 = 0x00;//作为从机自身地址
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//指定I2C快速模式占空比
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_Init(I2C2,&I2C_InitStructure);
I2C_Cmd(I2C2,ENABLE);
}
//超时退出机制
uint8_t Check_Timeout(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t time = 5000;
while(I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS){
time -- ;
if(time == 0){
return Timeout;
}
}
return SUCCESS;
}
void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);
Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
I2C_SendData(I2C2,RegAddress);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);
I2C_SendData(I2C2,Data);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);
I2C_GenerateSTOP(I2C2,ENABLE);
}
uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{
uint8_t ReceData;
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);
Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
I2C_SendData(I2C2,RegAddress);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);
I2C_GenerateSTART(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);
I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Receiver);
Check_Timeout(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
//接收的最后一个字节之前就要不应答和发送终止信号
I2C_AcknowledgeConfig(I2C2,DISABLE);
I2C_GenerateSTOP(I2C2,ENABLE);
Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);//接收到事件后一个字节就传到DR寄存器了
ReceData = I2C_ReceiveData(I2C2);
I2C_AcknowledgeConfig(I2C2,ENABLE);
return ReceData;
}
void MPU6050_Init(void)
{
I2C_init();
Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_1,0x01);
Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_2,0x00);
Specify_Address_Write(MPU6050_Address,MPU6050_SMPLRT_DIV,0x09);
Specify_Address_Write(MPU6050_Address,MPU6050_CONFIG,0x06);
Specify_Address_Write(MPU6050_Address,MPU6050_GYRO_CONFIG,0x18);
Specify_Address_Write(MPU6050_Address,MPU6050_ACCEL_CONFIG,0x18);
}
uint8_t MCU6050_GetID(void)
{
return Specify_Address_Read(MPU6050_Address,MPU6050_WHO_AM_I);
}
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
uint8_t data_H;
uint8_t data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_L);
*AccX = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_L);
*AccY = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_L);
*AccZ = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_L);
*GyroX = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_L);
*GyroY = (data_H<<8) | data_L;
data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_H);
data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_L);
*GyroZ = (data_H<<8) | data_L;
}