(十一)零基础开发小安派-Eyes-S1【外设篇】——I2C

[复制链接]
查看4795 | 回复34 | 2023-10-19 20:24:35 | 显示全部楼层 |阅读模式

零基础开发小安派-Eyes-S1【外设篇】——I2C

IIC(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

一、了解小安派-Eyes-S1的I2C

1.struct bflb_i2c_msg_s

说明:i2c传输时需要填充的信息

struct bflb_i2c_msg_s {
uint16_t addr;
uint16_t flags;
uint8_t *buffer;
uint16_t length;
};
parameter description
addr 设备地址(7bit或10bit)
flags 传输时附带标志
buffer 数据区
length 数据长度

flag可以为下列参数:

#define I2C_M_READ    0x0001
#define I2C_M_TEN     0x0002
#define I2C_M_DMA     0x0004
#define I2C_M_NOSTOP  0x0040
#define I2C_M_NOSTART 0x0080

备注:flagS也可以设为0,表示写入数据。在使用tansfer函数操作时,一般设置两个结构体数组,其中第一位操作的从机地址和寄存器地址,且Flags设置为NOSTOP,而后一个结构体数组为写入的数据,Flags设置为0,也就是write。

2.bflb_i2c_init

说明: 初始化 i2c 并配置频率。

void bflb_i2c_init(struct bflb_device_s *dev, uint32_t frequency);
parameter description
dev 设备句柄
frequency 配置频率(范围 305 HZ ~ 400KHZ)

3.bflb_i2c_deinit

说明: 反初始化 i2c。

void bflb_i2c_deinit(struct bflb_device_s *dev);
parameter description
dev 设备句柄

4.bflb_i2c_link_txdma

说明: i2c 发送 dma 使能开关。

void bflb_i2c_link_txdma(struct bflb_device_s *dev, bool enable);
parameter description
dev 设备句柄
enable 是否使能 dma

5.bflb_i2c_link_rxdma

说明: i2c 接收 dma 使能开关。

void bflb_i2c_link_rxdma(struct bflb_device_s *dev, bool enable);
parameter description
dev 设备句柄
enable 是否使能 dma

6.bflb_i2c_transfer

说明:i2c 消息传输。

int bflb_i2c_transfer(struct bflb_device_s *dev, struct bflb_i2c_msg_s *msgs, int count);
parameter description
dev 设备句柄
msgs 消息指针
count 消息个数

二、示例——驱动Rd-04雷达

首先准备一块Rd-04,将其的板载MCU拆除。

image.png

其次准备查阅Rd-04的寄存器手册,附上链接:rd-04_v1.0.0模组说明书.pdf (ai-thinker.com)

将Rd-04与S1进行连接,后续代码将GPIO_0设置为SDA,GPIO_1设置为SCL。注意:Rd-04有一个I2C的使能引脚,在配置时需要将I2C_EN拉高,我将其连接到3V3。

image.png

Main

#include "bflb_mtimer.h"
#include "bflb_i2c.h"
#include "bflb_gpio.h"
#include "board.h"

#define I2C_SLAVE_ADDR      0x71         //Rd-04的从机地址

static struct bflb_device_s *i2c0;       //i2c0外设句柄

struct bflb_i2c_msg_s msgs[2];           //I2C发送数据结构体数组


void My_i2c0_gpio_init()                 //初始化I2C的gpio引脚,选择IO_0作为SDA,IO_1作为SCL
{
    struct bflb_device_s* gpio;

    gpio = bflb_device_get_by_name("gpio");
    /* I2C0_SDA */
    bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* I2C0_SCL */
    bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
}


//I2C写入数据函数

static uint8_t axk_rd04_i2c_write(char reg_addr, char buff, char buf_size)
{
    /* Write data */
    msgs[0].addr = I2C_SLAVE_ADDR;
    msgs[0].flags = I2C_M_NOSTOP;
    msgs[0].buffer = ®_addr;
    msgs[0].length = buf_size;

    msgs[1].addr = I2C_SLAVE_ADDR;
    msgs[1].flags = 0;
    msgs[1].buffer = &buff;
    msgs[1].length = buf_size;

    bflb_i2c_transfer(i2c0, msgs, 2);

    bflb_mtimer_delay_ms(100);

    return 1;
}

//I2C读取数据函数
static char axk_rd04_i2c_read(char reg_addr,  char buf_size)
{
    static char read_data = 0;

    /* Read data */
    msgs[0].addr = I2C_SLAVE_ADDR;
    msgs[0].flags = I2C_M_NOSTOP;
    msgs[0].buffer = ®_addr;
    msgs[0].length = buf_size;

    msgs[1].addr = I2C_SLAVE_ADDR;
    msgs[1].flags = I2C_M_READ;
    msgs[1].buffer = &read_data;
    msgs[1].length = buf_size;

    bflb_i2c_transfer(i2c0, msgs, 2);

    bflb_mtimer_delay_ms(100);

    return read_data;
}


//Rd-04初始数据配置函数
static int32_t rd_04_radar_init(void)
{
    printf("radar init\n");
    uint8_t value;

    //-------------------------------------------------------------------
    /*寄存器地址  默认值   读/写   寄存器名称 
     * 0x13             0x1          R/W         bb_ctl[31:24]        
     * [7]            I2C read only data update enable for 0x26~0x29        
         * [6:5]         Reserved        
         * [4]                bb proc threshold mode ( 0:auto by configure pin / 1:manual by cpu control register )        信号检测门限选择,外部管脚选择档位方式和CPU寄存控制方式
         * [3]                bb read only data update enable        
         * [2:1]        read only data select ( 00:det_dc_sum(SUM0) / 01:det_ac_sum(SUM1) / 10:det_dc_used / 11:det_noise )        
         * [0]                bb proc enable ( 1:enable ) 信号检测enable,需要在在配置其它参数前先置0,再置1,由于信号检测部分工作时钟是32KHz,切换该位时需要CPU保证时长足够
     */
    //-------------------------------------------------------------------

    for (uint8_t i = 0; i < 5; i++)
    {
        axk_rd04_i2c_write(0x13, 0x9B, 1);
        bflb_mtimer_delay_us(10);
        value = axk_rd04_i2c_read(0x13, 1);
        printf("read value: 0x%02X\n", value);
    }

    //-------------------------------------------------------------------
        //-------------------------------------------------------------------
    // XBR818-ADC1  ->  VCO频率调整(外部电阻调整或MCU_IIC_调整 )      ---
    // XBR818-ADC2  ->  BB门限(外部电阻调整或MCU_IIC_调整 )                        ---
    // XBR818-ADC3  ->  BB延时时间  (外部电阻调整或MCU_IIC_调整 )     ---
    // XBR818-LP    ->  正常功耗(1)与低功耗(0)模式选择                                        ---
    //-------------------------------------------------------------------

    /*寄存器地址  默认值   读/写   寄存器名称
     *      0x24          0x03          R/W         pin_ctl[11:10]           
         *            [7:2]          Reserved
         *            [3]              INT_IRQ GPIO out
         *            [2]              IO_VAL GPIO out
         *            [1]              power mode control select     0:by P1_5     1:by CPU control register
         *            [0]              ADC2 sample enable for VCO tuning           0:enable
     */
    //--------------------------------------------------------------------------

    axk_rd04_i2c_write(0x24, 0x03, 1);
                                                //.7654 = nc
                                                                                //.3  =1, INT_IRQ设置为GPIO输出功能时输出,为高    =0,为低                                 
                                                                                //.2  =1, IO_VAL设置为GPIO输出功能时输出,为高     =0,为低 
                                                                                //.1  功耗设置方式选择  =1, 寄存器设置     =0,P15外接电阻选择                             
                                                                                //.0  =0,使能ADC1用作VCO频率微调           =1,禁止

        //--------------------------------------------------------------------
        //  0x04: 供电方式控制,默认 0x20        -- LP强制拉低,进入低功耗,此处设置无效
        //  14mA连续波工作模式        10100000  --  b.7=1, RF_EN_Sel=1  --    
        //  120uA脉冲间歇工作模式     00100000  --  b.7=0, RF_EN_Sel=0  -- 
        //--------------------------------------------------------------------
    //WriteBytes(0xE2,0X04,0XA0,1);                //0XA0-全供电  ---- 13mA

    axk_rd04_i2c_write(0x04, 0x20, 1);        //0X20-脉冲供电  ---- 155uA

        //--------------------------------------------------------------------
        //-------------- BB模块(目标检测)功能寄存器设置         ---------------
        //--------------------------------------------------------------------
                                                                                //设置ADC采样频率  ( 配置ADC采样率,32KHz OSC时钟分频,最小为2,default设置为1KHz )

        axk_rd04_i2c_write(0x10, 0x20, 1);  //0x20=32,  Fadc=32000Hz / 32=1000Hz   = 1KHz

        //WriteBytes(0xE2,0X10,0X10,1);     //0x10=16,  Fadc=32000Hz / 16=2000Hz   = 2KHz
        //WriteBytes(0xE2,0X10,0X08,1);     //0x08=8,   Fadc=32000Hz / 8  =4000Hz  = 4KHz
        //WriteBytes(0xE2,0X10,0X02,1);     //0x02=2,   Fadc=32000Hz / 2  =16000Hz = 16KHz

        //--------------------------------------------------------------------
        // 0x3:默认0x45-01000101-调整寄存器0x03【6:4】来微调中频的DC点电平 
        //                 pwu                       [7  ]   PWU                                                                                                                    
        //                mix_swdc            [6:4]   mixer dc trim                                                                                                  
        //                rf_en_ext_sel        [3  ]   rf_en_ext_sel=1, rf_en from PIN=0        
        //                vco_sw                       [2:0]   rf out power control   ---- BIT 2:0 修改发射功率 (7-6-5-4-3-2-1-0)              
        //--------------------------------------------------------------------
        //             mix_swdc   [6:4] = 000 -- OP1直流(mV)864mv 最佳范围 0.75-0.85      
        //                        [6:4] = 001 -- OP1直流(mV)675mv                    
        //                        [6:4] = 010 -- OP1直流(mV)761mv                    
        //                        [6:4] = 011 -- OP1直流(mV)571mv                    
        //                        [6:4] = 100 -- OP1直流(mV)813mv                    
        //                        [6:4] = 101 -- OP1直流(mV)630mv                    
        //                        [6:4] = 110 -- OP1直流(mV)716mv                    
        //                        [6:4] = 111 -- OP1直流(mV)522mv                    
        //--------------------------------------------------------------------
        //WriteBytes(0xE2,0X03,0X47,1);            //发射功率(7) -- 108.5uA@6V 靠近感应无反应
        //WriteBytes(0xE2,0X03,0X46,1);            //发射功率(6) -- 114.5uA@6V 靠近感应反应正常(很近)

        axk_rd04_i2c_write(0x03, 0x45, 1);  //发射功率(5) -- 115.2uA@6V 靠近感应反应正常

        //WriteBytes(0xE2,0X03,0X44,1);            //发射功率(4) -- 117.9uA@6V 靠近感应反应正常
        //WriteBytes(0xE2,0X03,0X43,1);            //发射功率(3) -- 119.7uA@6V 靠近感应反应正常
        //WriteBytes(0xE2,0X03,0X42,1);            //发射功率(2) -- 121.1uA@6V 靠近感应反应正常
        //WriteBytes(0xE2,0X03,0X41,1);            //发射功率(1) -- 123.2uA@6V 靠近感应反应正常
        //WriteBytes(0xE2,0X03,0X40,1);            //发射功率(0) -- 124.1uA@6V 靠近感应反应正常  --- 发射功率最大
        //--------------------------------------------------------------------

        //--------------------------------------------------------------------

        axk_rd04_i2c_write(0x1C, 0x21, 1);        //选择(感应延时由寄存器设置)+(定时器使能)   
                                                                                //.76  = nc                        00100001 
                                        //.5   =1, 感应延时由寄存器设置      =0,感应延时由外围电阻设置
                                                                                //.43  定时时间单位选择  =00(秒)     =01(分)      =10(小时)     =11(天) 
                                                                                //.21  光感检测周期      =00(禁止)   =01(4秒)     =10(1分钟)    =11(1小时)                                                             
                                                                                //.0   =1,定时器使能     =0,定时器禁止


    axk_rd04_i2c_write(0x11, 0x10, 1);        //设置初始化时长为7s

        //感应距离和传感器的值成反比
        //默认使用0x0080,正面感应距离8m左右

        axk_rd04_i2c_write(0x18, 0x00, 1);                //[7:0 ] 设置感应门限      6A -- 10m    9a--8m    ea--5m   15A--7m

        axk_rd04_i2c_write(0x19, 0x20, 1);                  //[15:8] 设置感应门限


        axk_rd04_i2c_write(0x1A, 0x55, 1);                //[7:0 ] 设置噪声更新允许门限   

        axk_rd04_i2c_write(0x1B, 0x01, 1);                  //[15:8] 设置噪声更新允许门限

    //设置1s感应延迟时间

        axk_rd04_i2c_write(0x1D, 0x00, 1);                  //[7:0  ] 设置感应延时时间  ( y / 32000 默认0ea600(960000) / 32000 = 30秒  )

        axk_rd04_i2c_write(0x1E, 0x7D, 1);                  //[15:8 ] 设置感应延时时间  ( y / 32000 默认027100(160000) / 32000 = 5秒   )

        axk_rd04_i2c_write(0x1F, 0x00, 1);                  //[23:16] 设置感应延时时间  ( y / 32000 默认007D00(32000)  / 32000 = 1秒   )  16000-0x3e80
                                                                                    //                        ( y / 32000 默认001900(6400)   / 32000 = 0.2秒 )    3200-0xc80

        //封锁时间:灭灯后不感应的时间,原厂建议最短500ms

        axk_rd04_i2c_write(0x20, 0x80, 1);                  //[7:0  ] 设置封锁时间      ( y / 32000 默认00fa00(64000) / 32000 = 2秒  )

        axk_rd04_i2c_write(0x21, 0x3E, 1);                  //[15:8 ] 设置封锁时间      ( y / 32000 默认027100(160000) / 32000 = 5秒 )

        axk_rd04_i2c_write(0x22, 0x00, 1);                  //[23:16] 设置封锁时间      ( y / 32000 默认007D00(32000)  / 32000 = 1秒 )

        //--------------------------------------------------------------------
        //--------------------------------------------------------------------
        //WriteBytes(0xE2,0X23,0X07,1);                //0X23- 07 - ADC_sample     --INT_IRQ ( 1KHz采样频率 -- 与ADC采样频率对应)
        //WriteBytes(0xE2,0X23,0X09,1);                //0X23- 09 - ADC_sample_IRQ --INT_IRQ
        //WriteBytes(0xE2,0X23,0X0A,1);                //0X23- 0A - ADC_ACCU_IRQ   --INT_IRQ

        axk_rd04_i2c_write(0X23, 0x0C, 1);        //0X23- 0C - IO_VALUE_OUT   --感应有效输出

    printf("radar init done\n");

    return 0;
}


int main(void)
{

    board_init();

    //I2C引脚初始化
    My_i2c0_gpio_init();

    i2c0 = bflb_device_get_by_name("i2c0");

    //I2C初始化
    bflb_i2c_init(i2c0, 400000);

    //Rd-04配置
    rd_04_radar_init();

    while(1){
    }
}

实现效果

7edc7a5e56ad34f172a2ba35acad36bb00_00_00-00_00_30.gif

本帖被以下淘专辑推荐:

回复

使用道具 举报

jkernet | 2023-10-19 21:34:52 | 显示全部楼层
学习打卡
回复

使用道具 举报

爱笑 | 2023-10-20 08:32:29 | 显示全部楼层
泽哥加油!
用心做好保姆工作
回复

使用道具 举报

bzhou830 | 2023-10-20 08:41:01 | 显示全部楼层
学习打卡
选择去发光,而不是被照亮
回复

使用道具 举报

End | 2023-10-20 11:19:18 | 显示全部楼层
学习打卡
羡慕
回复

使用道具 举报

18350766600@139 | 2023-10-20 17:02:32 | 显示全部楼层
学习打卡
回复

使用道具 举报

iiv | 2023-10-20 23:24:45 | 显示全部楼层
泽哥终于出马了,我希望明天泽哥继续出马!
回复 支持 反对

使用道具 举报

Jun | 2023-10-21 13:00:02 | 显示全部楼层
学习了
回复

使用道具 举报

AiThinker-李工 | 2023-10-23 10:08:44 | 显示全部楼层
你小子真帅!
回复 支持 反对

使用道具 举报

lsrly | 2023-11-2 11:44:59 | 显示全部楼层
学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则