其他分享
首页 > 其他分享> > nrf52 iic使用

nrf52 iic使用

作者:互联网

一、使用环境

SDK17.1 ble_app_template例程

二、工程配置

2.1 添加官方驱动文件

2.2 使能TWI

三、代码移植

驱动代码 peripheral_iic.h

#ifndef _PERIPHERAL_I2C_H_
#define _PERIPHERAL_I2C_H_
​
#include "boards.h"
#include "nrf_delay.h"
#include "nrf_drv_twi.h"
#include "nrf_gpio.h"
​
#include <stdio.h>
#include <string.h>
​
bool I2C_register_read(uint8_t slave_address, uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes);
bool I2C_register_write(uint8_t slave_address, unsigned char *data_buf, uint8_t len);
​
int16_t I2C_Write_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char cmd);
int16_t I2C_Read_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char *ucData);
​
int16_t I2C_MultiWrite_Reg(unsigned char i2c_add, unsigned char reg_add, int16_t num, unsigned char *ucData);
int16_t I2C_MultiRead_Reg(unsigned char i2c_add, unsigned char reg_add, int16_t num, unsigned char *ucData);
​
void I2C_init(void);
void I2C_uninit(void);
​
#endif // END _PERIPHERAL_I2C_H_
​

驱动代码 peripheral_iic.c

#include "peripheral_iic.h"
​
// TWI驱动程序实例ID,ID和外设编号对应,0:TWI0  1:TWI1
#define TWI_INSTANCE_ID_S 0 
​
// TWI传输完成标志
static volatile bool I2C_xfer_done = false;
​
//定义TWI驱动程序实例,名称为m_twi
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID_S);
​
// TWI事件处理函数
static void twi_s_handler(nrf_drv_twi_evt_t const *p_event, void *p_context)
{
    //判断TWI事件类型
    switch (p_event->type)
    {
    //传输完成事件
    case NRF_DRV_TWI_EVT_DONE:
        I2C_xfer_done = true; //置位传输完成标志
        break;
    default:
        break;
    }
}
​
/*************************************************************************
 * 功  能 : 写I2C_Slave寄存器
 * 参  数 : register_address[in]:寄存器地址
 *        : value[in]:写入的数据
 * 返回值 : true:写数据成功,false:写入失败
 *************************************************************************/
bool I2C_register_write(uint8_t slave_address, unsigned char *data_buf, uint8_t len)
{
    uint8_t timeOut = 0;
    ret_code_t err_code;
    // TWI传输完成标志设置为false
    I2C_xfer_done = false;
    //写入数据
    err_code = nrf_drv_twi_tx(&m_twi, slave_address, data_buf, len, false);
    //等待TWI总线传输完成
    timeOut = 0;
    while (I2C_xfer_done == false)
    {
        if (timeOut > 50)
        {
            return false;
        }
        else
        {
            timeOut++;
        }
​
        nrf_delay_us(100);
    }
    if (NRF_SUCCESS != err_code)
    {
        return false;
    }
    return true;
}
​
/*************************************************************************
 * 功  能 : 读I2C_Slave寄存器
 * 参  数 : register_address[in]:寄存器地址
 *        : * destination[out]  :指向保存读取数据的缓存
 *        : number_of_bytes[in] :读取的数据长度
 * 返回值 : true:操作成功,false:操作失败
 *************************************************************************/
bool I2C_register_read(uint8_t slave_address, uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes)
{
    uint8_t timeOut = 0;
    ret_code_t err_code;
    // TWI传输完成标志设置为false
    I2C_xfer_done = false;
    err_code = nrf_drv_twi_tx(&m_twi, slave_address, &register_address, 1, true);
    //等待TWI总线传输完成
    timeOut = 0;
    while (I2C_xfer_done == false)
    {
        if (timeOut > 50)
        {
            return false;
        }
        else
        {
            timeOut++;
        }
​
        nrf_delay_us(100);
    }
    if (NRF_SUCCESS != err_code)
    {
        return false;
    }
    // TWI传输完成标志设置为false
    I2C_xfer_done = false;
    err_code = nrf_drv_twi_rx(&m_twi, slave_address, destination, number_of_bytes);
​
    //等待TWI总线传输完成
    timeOut = 0;
    while (I2C_xfer_done == false)
    {
        if (timeOut > 50)
        {
            return false;
        }
        else
        {
            timeOut++;
        }
​
        nrf_delay_us(100);
    }
    if (NRF_SUCCESS != err_code)
    {
        return false;
    }
    return true;
}
​
int16_t I2C_Write_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char cmd)
{
    uint8_t BufTmp[2];
    BufTmp[0] = reg_add;
    BufTmp[1] = cmd;
​
    return I2C_register_write(i2c_add, BufTmp, 2);
}
​
int16_t I2C_Read_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char *ucData)
{
    return I2C_register_read(i2c_add, reg_add, ucData, 1);
}
​
int16_t I2C_MultiWrite_Reg(unsigned char i2c_add, unsigned char reg_add, int16_t num, unsigned char *ucData)
{
    uint8_t BufTmp[num + 1];
    BufTmp[0] = reg_add;
​
    memcpy(&BufTmp[1], ucData, num);
    return I2C_register_write(i2c_add, BufTmp, num + 1);
}
​
int16_t I2C_MultiRead_Reg(unsigned char i2c_add, unsigned char reg_add, int16_t num, unsigned char *ucData)
{
    return I2C_register_read(i2c_add, reg_add, ucData, num);
}
​
void I2C_init(void)
{   
    ret_code_t err_code;
    //定义并初始化TWI配置结构体
    const nrf_drv_twi_config_t twi_config_s = {
        .scl = ARDUINO_SCL_PIN,                     //定义TWI SCL引脚
        .sda = ARDUINO_SDA_PIN,                     //定义TWI SDA引脚
        .frequency = NRF_DRV_TWI_FREQ_400K,             // TWI速率
        .interrupt_priority = APP_IRQ_PRIORITY_HIGHEST, // TWI优先级
        .clear_bus_init = false                         //初始化期间不发送9个SCL时钟
    };
    //初始化TWI
    err_code = nrf_drv_twi_init(&m_twi, &twi_config_s, twi_s_handler, NULL);
    //检查返回的错误代码
    APP_ERROR_CHECK(err_code);
    //使能TWI
    nrf_drv_twi_enable(&m_twi);
}
​
void I2C_uninit(void)
{
    //失能TWI
    nrf_drv_twi_disable(&m_twi);
    nrf_drv_twi_uninit(&m_twi);
​
    nrf_gpio_cfg_default(ARDUINO_SDA_PIN);
    nrf_gpio_cfg_default(ARDUINO_SCL_PIN);
}
​

添加我们的驱动文件和头文件路径,然后使用例子。

四、驱动测试

4.1 添加头文件
#include "peripheral_iic.h"
4.2 简单读写测试
#define LIS2MDL_ADDR_WRITE                        0x3C//0x3C  0x1EU
#define LIS2MDL_ADDR_READ                         0x3D//0x3D  0x1EU
​
/* 设备寄存器地址 */
#define LIS2MDL_ADDR_CFGA                         0x60
#define LIS2MDL_ADDR_CFGB                         0x61
#define LIS2MDL_ADDR_CFGC                         0x62
#define LIS2MDL_ADDR_INTCRTL                      0x63
#define LIS2MDL_ADDR_INTSOURCE                    0x64
#define LIS2MDL_ADDR_INTTHSL                      0x65
#define LIS2MDL_ADDR_INTTHSH                      0x66
#define LIS2MDL_ADDR_STATUS                       0x67
​
#define LIS2MDL_ADDR_XOUTL                        0x68
#define LIS2MDL_ADDR_XOUTH                        0x69
#define LIS2MDL_ADDR_YOUTHL                       0x6A
#define LIS2MDL_ADDR_YOUTH                        0x6B
#define LIS2MDL_ADDR_ZOUTL                        0x6C
#define LIS2MDL_ADDR_ZOUTH                        0x6D
​
void i2c_test(void)
{
    unsigned char writeData = 0x47;
    unsigned char readData = 0;
    
    I2C_init();
    
    I2C_MultiWrite_Reg(LIS2MDL_ADDR_WRITE, LIS2MDL_ADDR_CFGA, 1, &writeData);
    I2C_MultiRead_Reg(LIS2MDL_ADDR_READ, LIS2MDL_ADDR_XOUTL, 1, &readData);
}
​

标签:twi,nrf52,TWI,unsigned,char,add,iic,使用,I2C
来源: https://www.cnblogs.com/wfagly/p/16123037.html