nRF52832的TWI(two wire interface,也即是硬件i2c):
一、i2c通信知识储备
1.i2c通信需要两条线,sda和scl。I2C通信角色分为:master和slave
2.当通信总线空闲时,scl、sda都处于高电平状态
3.i2c通信过程中,有两组控制信号:
1)start:
scl为高电平时,sda由高电平变为低电平
2)stop:
scl为高电平时,sda由低电平变为高电平
二、编程分析
sdk版本:nRF5_SDK_15.2.0_9412b96
//1.twi初始化配置
//头文件:nrf_drv_twi.h
//sdk_config.h中开启twi功能
#define ARDUINO_SCL_PIN 7
#define ARDUINO_SDA_PIN 8
#define TWI_IMU_INSTANCE_ID 1 //使用TWI1
#define IMU_ADDR (0x78>>1) //IMU地址
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_IMU_INSTANCE_ID) //twi实例
static volatile bool m_xfer_done = false; //指示twi的操作是否结束
//twi回调函数,主要是用来上报twi操作完成功能
static void twi_handler(nrf_drv_twi_evt_t const *p_event,void *p_context)
{
switch(p_event->type)
{
case NRF_DRV_TWI_EVT_DONE:
if(p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
{
NRF_LOG_INFO("twi tx donw!");
}
else if(p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
{
NRF_LOG_INFO("twi rx donw!");
}
m_xfer_done = true;
break;
case NRF_DRV_TWI_EVT_ADDRESS_NACK:
NRF_LOG_INFO("Error event: NACK received after sending the address.");
break;
case NRF_DRV_TWI_EVT_DATA_NACK:
NRF_LOG_INFO(" Error event: NACK received after sending a data byte.");
break;
default:
break;
}
}
static void twi_config(void)
{
uint32_t err_code;
nrf_drv_twi_config_t const config = {
.scl = ARDUINO_SCL_PIN, //时钟gpio引脚
.sda = ARDUINO_SDA_PIN, //数据gpio引脚
.frequency = NRF_TWI_FREQ_100K, //twi时钟频率
.interrupt_priority = APP_IRQ_PRIORITY_LOWEST, //中断优先级
.clear_bus_init = false //初始化期间清除总线
}
//初始化twi
err_code = nrf_drv_twi_init(&m_twi,&config,twi_handler,NULL);
APP_ERROR_CHECK(err_code);
//使能twi
nrf_drv_twi_enable(&m_twi);
}
//2.读写从设备
1)写
ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,uint8_t address, uint8_t const *p_data,uint8_t length,bool no_stop);
p_instance:指向twi实例的指针
address:从设备地址
p_data:要发送的数据buffer
length:要发送的数据字节长度
no_stop:是否设置没有停止位
2)读
ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance,uint8_t address, uint8_t const *p_data,uint8_t length);
p_instance:指向twi实例的指针
address:从设备地址
p_data:读取的数据存储buffer
length:读取的数据字节长度