ESP8266 SDK 开发 I2C通信

本次使用的是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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值