本次使用的是SDK开发中的I2C,采用NONOS 2.0
i2c.h文件
#ifndef __I2C_H_
#define __I2C_H_
#include "osapi.h"
#define MPU_I2C_SDA_MUX PERIPHS_IO_MUX_GPIO2_U
#define MPU_I2C_SDA_GPIO 2
#define MPU_I2C_SDA_FUNC FUNC_GPIO2
#define MPU_I2C_SCL_MUX PERIPHS_IO_MUX_MTMS_U
#define MPU_I2C_SCL_FUNC FUNC_GPIO14
#define MPU_I2C_SCL_GPIO 14
#define MPU_I2C_SCL_H gpio_output_set(1<<MPU_I2C_SCL_GPIO, 0, 1<<MPU_I2C_SCL_GPIO, 0)
#define MPU_I2C_SCL_L gpio_output_set(0,1<<MPU_I2C_SCL_GPIO, 1<<MPU_I2C_SCL_GPIO, 0)
#define MPU_I2C_SDA_H gpio_output_set(1<<MPU_I2C_SDA_GPIO, 0, 1<<MPU_I2C_SDA_GPIO, 0)
#define MPU_I2C_SDA_L gpio_output_set(0,1<<MPU_I2C_SDA_GPIO, 1<<MPU_I2C_SDA_GPIO, 0)
#define mpu_i2c_delay_us(t) os_delay_us(t)
#define mpu_i2c_delay_ms(t) os_delay_us(t*1000)
void mpu_i2c_master_setDC(uint8 SDA, uint8 SCL);
uint8 mpu_i2c_master_getDC(void);
uint8 mpu_i2c_master_getSCL(void);
void mpu_i2c_master_start(void);
void mpu_i2c_master_stop(void);
void mpu_i2c_master_setAck(uint8 level);
uint8 mpu_i2c_master_getAck(void);
bool mpu_i2c_master_checkAck(void);
void mpu_i2c_master_send_ack(void);
void mpu_i2c_master_send_nack(void);
uint8 mpu_i2c_master_readByte(uint8 ack);
uint8 mpu_i2c_master_writeByte(uint8 wrdata);
uint8 MPU_Write_Byte(uint8 reg,uint8 data);
uint8 MPU_Read_Byte(uint8 reg);
uint8 MPU_Write_Len(uint8 addr,uint8 reg,uint8 len,uint8 *buf);
uint8 MPU_Read_Len(uint8 addr,uint8 reg,uint8 len,uint8 *buf);
void mpu_i2c_master_init(void);
void bsp_i2c_master_init(void);
#endif /* APP_INCLUDE_DRIVER_AS7000_H_ */
mpu6050.c文件
#include "driver/i2c.h"
#include "osapi.h" // os_XXX、软件定时器
#include "gpio.h"
static uint8 m_nLastSDA;
static uint8 m_nLastSCL;
/******************************************************************************
* FunctionName : mpu_i2c_master_setDC
* Description : Internal used function -
* set i2c SDA and SCL bit value for half clk cycle
* Parameters : uint8 SDA
* uint8 SCL
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_setDC(uint8 SDA, uint8 SCL)
{
SDA &= 0x01;
SCL &= 0x01;
m_nLastSDA = SDA;
m_nLastSCL = SCL;
if ((0 == SDA) && (0 == SCL))
{
MPU_I2C_SDA_L;
MPU_I2C_SCL_L;
}
else if ((0 == SDA) && (1 == SCL))
{
MPU_I2C_SDA_L;
MPU_I2C_SCL_H;
}
else if ((1 == SDA) && (0 == SCL))
{
MPU_I2C_SDA_H;
MPU_I2C_SCL_L;
}
else
{
MPU_I2C_SDA_H;
MPU_I2C_SCL_H;
}
}
uint8 ICACHE_FLASH_ATTR mpu_i2c_master_getDC(void)
{
uint8 sda_out;
sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(MPU_I2C_SDA_GPIO));
return sda_out;
}
uint8 ICACHE_FLASH_ATTR
mpu_i2c_master_getSCL(void)
{
uint8 scl_out;
scl_out = GPIO_INPUT_GET(GPIO_ID_PIN(MPU_I2C_SCL_GPIO));
return scl_out;
}
/******************************************************************************
* FunctionName : i2c_master_start
* Description : set i2c to send state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_start(void)
{
mpu_i2c_master_setDC(1, m_nLastSCL);
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(1, 1);
mpu_i2c_delay_us(2); // sda 1, scl 1
mpu_i2c_master_setDC(0, 1);
mpu_i2c_delay_us(2); // sda 0, scl 1
}
/******************************************************************************
* FunctionName : i2c_master_stop
* Description : set i2c to stop sending state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_stop(void)
{
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(0, m_nLastSCL);
mpu_i2c_delay_us(2); // sda 0
mpu_i2c_master_setDC(0, 1);
mpu_i2c_delay_us(2); // sda 0, scl 1
mpu_i2c_master_setDC(1, 1);
mpu_i2c_delay_us(2); // sda 1, scl 1
}
/******************************************************************************
* FunctionName : mpu_i2c_master_setAck
* Description : set ack to i2c bus as level value
* Parameters : uint8 level - 0 or 1
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_setAck(uint8 level)
{
mpu_i2c_master_setDC(m_nLastSDA, 0);
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(level, 0);
mpu_i2c_delay_us(2); // sda level, scl 0
mpu_i2c_master_setDC(level, 1);
mpu_i2c_delay_us(2); // sda level, scl 1
mpu_i2c_master_setDC(level, 0);
mpu_i2c_delay_us(2); // sda level, scl 0
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(2);
}
/******************************************************************************
* FunctionName : mpu_i2c_master_getAck
* Description : confirm if peer send ack
* Parameters : NONE
* Returns : uint8 - ack value, 0 or 1
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
mpu_i2c_master_getAck(void)
{
uint8 retVal;
mpu_i2c_master_setDC(m_nLastSDA, 0);
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(1, 1);
mpu_i2c_delay_us(2);
retVal = mpu_i2c_master_getDC();
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(2);
return retVal;
}
/******************************************************************************
* FunctionName : mpu_i2c_master_checkAck
* Description : get dev response
* Parameters : NONE
* Returns : true : get ack ; false : get nack
*******************************************************************************/
bool ICACHE_FLASH_ATTR
mpu_i2c_master_checkAck(void)
{
if(mpu_i2c_master_getAck())
{
return FALSE;
}
else
{
return TRUE;
}
}
/******************************************************************************
* FunctionName : mpu_i2c_master_send_ack
* Description : response ack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_send_ack(void)
{
mpu_i2c_master_setAck(0x0);
}
/******************************************************************************
* FunctionName : mpu_i2c_master_send_nack
* Description : response nack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
mpu_i2c_master_send_nack(void)
{
mpu_i2c_master_setAck(0x1);
}
/******************************************************************************
* FunctionName : mpu_i2c_master_readByte
* Description : read Byte from i2c bus
* Parameters : ack - ack = 1 send ack,ack = 0 send nack
* Returns : uint8 - readed value
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
mpu_i2c_master_readByte(uint8 ack)
{
uint8 retVal = 0;
uint8 k, i;
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(m_nLastSDA, 0);
mpu_i2c_delay_us(2); // sda 1, scl 0
for (i = 0; i < 8; i++)
{
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(2); // sda 1, scl 0
mpu_i2c_master_setDC(1, 1);
mpu_i2c_delay_us(2); // sda 1, scl 1
k = mpu_i2c_master_getDC();
mpu_i2c_delay_us(2);
if (i == 7)
{
mpu_i2c_delay_us(2);
}
k <<= (7 - i);
retVal |= k;
}
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(2); // sda 1, scl 0
if(!ack)
mpu_i2c_master_send_nack();
else
mpu_i2c_master_send_ack();
return retVal;
}
/******************************************************************************
* FunctionName : mpu_i2c_master_writeByte
* Description : write wrdata value(one byte) into i2c
* Parameters : uint8 wrdata - write value
* Returns : 0:成功,1:失败
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
mpu_i2c_master_writeByte(uint8 wrdata)
{
uint8 dat;
sint8 i;
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(m_nLastSDA, 0);
mpu_i2c_delay_us(2);
for (i = 7; i >= 0; i--)
{
dat = wrdata >> i;
mpu_i2c_master_setDC(dat, 0);
mpu_i2c_delay_us(2);
mpu_i2c_master_setDC(dat, 1);
mpu_i2c_delay_us(2);
if (i == 0) {
mpu_i2c_delay_us(2);
}
mpu_i2c_master_setDC(dat, 0);
mpu_i2c_delay_us(2);
}
uint8 waitting_ack = 0;
while(!mpu_i2c_master_checkAck()) //等待应答
{
waitting_ack++;
if(waitting_ack > 250)
{
mpu_i2c_master_stop();
return 1;
}
}
return 0;
}
/*
* IIC写一个字节
*reg:寄存器地址
*data:数据
*返回值:0,正常
* 其他,错误代码
*/
uint8 ICACHE_FLASH_ATTR MPU_Write_Byte(uint8 reg,uint8 data)
{
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(MPU6050_SLAVE_ADDR | 0))
{
return 1;
}
if(mpu_i2c_master_writeByte(reg))
{
return 1;
}
if(mpu_i2c_master_writeByte(data))
{
return 1;
}
mpu_i2c_master_stop();
return 0;
}
/*
*IIC读一个字节
*reg:寄存器地址
*返回值:读到的数据
*/
uint8 ICACHE_FLASH_ATTR MPU_Read_Byte(uint8 reg)
{
uint8 ret = 0;
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(MPU6050_SLAVE_ADDR | 0))
{
return 1;
}
if(mpu_i2c_master_writeByte(reg))
{
return 1;
}
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(MPU6050_SLAVE_ADDR | 1))
{
return 1;
}
ret=mpu_i2c_master_readByte(0);//读取数据,发送nACK
mpu_i2c_master_stop(); //产生一个停止条件
return ret;
}
//IIC连续写
//addr:器件地址
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
// 其他,错误代码
uint8 ICACHE_FLASH_ATTR MPU_Write_Len(uint8 addr,uint8 reg,uint8 len,uint8 *buf)
{
uint8 i;
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(addr | 0))
{
return 1;
}
if(mpu_i2c_master_writeByte(reg))
{
return 1;
}
for(i=0;i<len;i++)
{
if(mpu_i2c_master_writeByte(buf[i])) //发送数据
{
return 1;
}
}
mpu_i2c_master_stop();
return 0;
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
// 其他,错误代码
uint8 ICACHE_FLASH_ATTR MPU_Read_Len(uint8 addr,uint8 reg,uint8 len,uint8 *buf)
{
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(addr | 0))
{
return 1;
}
if(mpu_i2c_master_writeByte(reg))
{
return 1;
}
mpu_i2c_master_start();
if(mpu_i2c_master_writeByte(addr | 1))
{
return 1;
}
while(len)
{
if(len==1)*buf=mpu_i2c_master_readByte(0);//读数据,发送nACK
else *buf=mpu_i2c_master_readByte(1); //读数据,发送ACK
len--;
buf++;
}
mpu_i2c_master_stop(); //产生一个停止条件
return 0;
}
void ICACHE_FLASH_ATTR
mpu_i2c_master_init(void)
{
uint8 i;
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(20);
// when SCL = 0, toggle SDA to clear up
mpu_i2c_master_setDC(0, 0);
mpu_i2c_delay_us(20);
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(20);
// set data_cnt to max value
for (i = 0; i < 28; i++)
{
mpu_i2c_master_setDC(1, 0);
mpu_i2c_delay_us(20); // sda 1, scl 0
mpu_i2c_master_setDC(1, 1);
mpu_i2c_delay_us(20); // sda 1, scl 1
}
// reset all
mpu_i2c_master_stop();
return;
}
/******************************************************************************
* FunctionName : bsp_i2c_master_init
* Description : config SDA and SCL gpio to open-drain output mode,
* mux and gpio num defined in i2c_master.h
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
bsp_i2c_master_init(void)
{
/* 共用SDA,由于6050会受外接多个i2c设备影响,所以单独使用一根SCL,i2c的通讯速率为10KHZ左右 */
PIN_FUNC_SELECT(MPU_I2C_SDA_MUX, MPU_I2C_SDA_FUNC);
PIN_FUNC_SELECT(MPU_I2C_SCL_MUX, MPU_I2C_SCL_FUNC);
/* 配置开漏输出 */
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(MPU_I2C_SDA_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(MPU_I2C_SDA_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE));
GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << MPU_I2C_SDA_GPIO));
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(MPU_I2C_SCL_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(MPU_I2C_SCL_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE));
GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << MPU_I2C_SCL_GPIO));
MPU_I2C_SDA_H;
MPU_I2C_SCL_H;
mpu_i2c_master_init();
}
使用I2C驱动MPU6050,读取原始数据,分别是加速度、角速度,基于ESP8266 SDK开发 NONOS 2.0
传送门:https://download.csdn.net/download/weixin_41583631/12364615