PB-03F-Kit 开发板I2C使用方法

[复制链接]
查看605 | 回复3 | 7 天前 | 显示全部楼层 |阅读模式

本帖最后由 AndyL 于 2025-1-10 20:13 编辑

PB_03F_Kit连接AS6221温度传感器模块(IIC)

一、硬件介绍

Snipaste_2025-01-02_14-20-31.png

AS6221 是市场上精度最高的数字温度传感器系统 (+/- 0.09°C)。

它具备完整的数字化系统,可以快速准确的获取测试位置的 温度信息,准确的还原温度值并且通过标准 I2C 接口输出。可实现理想的健康温度监测,或应用于各种恒温场景的温度监控。

• 超高的测量精度 ±0.09°C (20°C 至 42°C)****

• 超低功耗 (6µA @ 4 Hz / 0.1μA @ Standby)

• 支持电池供电的使用场景

• 支持预警模式,可以灵活设置阈值,实现精确的温度监控 高集成化设计,设计灵活

• 集成完整的数字模块,支持标准 IIC 通讯模式 • 支持 8 组 IIC 地址,可以多颗器件系统配合使用 小尺寸,使用简单

• 产线完整单体一致性测试,无需标定/校准

• WLCSP 封装,尺寸: 1.5 x 1.0 mm

1、AS6221 内部架构

AS6221 是完整的高精度数字温度传感器系统。它由一个硅基双极温度传感器模拟前端、一个 ADC 和一个数字传感器组成,通过 IIC 通信数字总线与其他设备通讯 器件支持多路 IIC 地址设定,支持中断预警模式

img

二、硬件连接

1、开发板选择(PB_03F_kit)

使用指南详见

PB_03F_kit开发板的IIC硬件介绍如下:

**硬件支持 2 路 I2C**, 可配置 MASTER 或 SLAVE。

硬件 TX FIFO 深度 8 字节,硬件 RX FIFO 深度 8 字节。

PCLK 时钟等于 HCLK,可分频,不建议分频。 当系统休眠时, I2C 信息会丢失,唤醒后需要重新配置。

所有可 fmux 的 io 都可以复用为 I2C。

I2C 使用时需要接上拉电阻,比如 2.2K 或 4.7K。

FULLMUX 模式(FULLMUX 是指将 GPIO 复用为其他模块引脚): 除 TEST_MODE、 P16、 P17、 P1 之外的其他 GPIO 都支持 GPIO FULLMUX 功能,可根据应用 GPIO 配置为 UART,I2C 、 PWM 等功能。

image-20250102155706284.png

2、连接方式(IIC通讯模式 / 数据解析)

1、AS6221 Eval Kit模块引脚介绍:

Pin 符号 说明 备注
1 SCL I2C时钟线 如需上拉,使用R1
2 SDA I2C数据线 如需上拉,使用R2
3 GND -
4 VDD 电源供应 -
5 ALERT 数字输出引脚 警报中断输出

注:不要将引脚5接到VSS,此引脚只用于ALERT功能

image-20250105000218570.png

2、I2C地址选择方式:

使用跳线帽设置I2C的地址,且两个位置的跳线帽不能打开。

配置方式如下所示

image-20250105002216023.png

3、MCU与模块连接方式:

SDA -> P33

CLK -> P34

ALERT警报功能未使用,不连接。(根据实际情况自行配置)

image-20250105002414395.png

4、模块输出数据解析

1.TVAL(0x0寄存器地址):当前获取的温度值。

2.CONFIG(0x1寄存器地址):当前配置的相关信息。

3.TLOW(0x2寄存器地址):温度下限警报值。

4.THIGH(0x3寄存器地址):温度上限警报值。

image-20250107205313525.png

1、温度值TVAL数据解析

为获取模块的温度值,需要读取TVAL(0x0寄存器地址)的值,输出的温度数值为 2字节数据(例:0xb,0x22)

LSB = (1 / 128)°C = 0.0078125 °C

*实际数值 = 读取到的数值 LSB = 2850(0xb22[hex]) * LSB ≈ 22.265°C*

image-20250107221437772.png

2、配置CONFIG数据解析

例:获取的数据为 0x40,0x20;即 0100 0000 0010 0000。

根据下表,可知每位代表的含义,以及是否可修改相关属性。(更多具体的配置,详见数据手册)

Bit Bit name Default Access Bit description
0 Reserved 0 RO Reserved
1 Reserved 0 RO Reserved
2 Reserved 0 RO Reserved
3 Reserved 0 RO Reserved
4 Reserved 0 RO Reserved
5 AL 1 RO Alert Bit (AL)
6 CR[0] 0 RW Conversion RATE (CR)
7 CR[1] 1 RW Conversion RATE (CR)
8 SM 0 RW Sleep Mode (SM)
9 IM 0 RW Interrupt Mode (IM)
10 POL 0 RW Polarity (POL)
11 CF[0] 0 RW Consecutive Faults (CF)
12 CF[1] 0 RW Consecutive Faults (CF)
13 Reserved 0 RO Reserved
14 Reserved 1 RO Reserved
15 SS 0 RW Single Shot

3、TLOW / THIGHT 数据解析

例:TLOW 获取的值为 0x25,0x80;即 75 °C。THIGHT 获取的值为 0x28 0x00;即 80 °C

若要使用TLOW,THIGHT;需配置 ALERT 中断引脚,相关转换过程如下。

image-20250107224109514.png

三、代码编写

以I2C的Demo工程为例,编写相关程序。

(…\PB-03F\phy6222_v313_0512\example\peripheral\i2c)

修改跳线帽位置使从机(模块)I2C地址如“图5”的第一种方式(0x44)。

主要代码如下:

i2c_demo.c代码如下:

#include "OSAL.h"
#include "i2c_demo.h"
#include "log.h"

#include "gpio.h"
#include "clock.h"

#include "pwrmgr.h"
#include "error.h"
#include "key.h"

#include "flash.h"
#include "i2c.h"


#include "pwrmgr.h"
#include "error.h"


#define I2C_MASTER_SDA P33
#define I2C_MASTER_CLK P34

#define slave_i2c_addr 0x44 //从机设备地址
#define Tval_ADDR 0  //温度寄存器的地址
#define Config_ADDR 1 
#define Tlow_ADDR 2 
#define Thight_ADDR 3  

static void* master_pi2c;  
static uint8_t i2c_TaskID;

#define I2C_MASTER_RX_DATA_LEN 2

uint8 I2C_RX_data[I2C_MASTER_RX_DATA_LEN]= {0};   //接收温度数据
uint8 I2C_Config_data[I2C_MASTER_RX_DATA_LEN]= {0};
uint8 I2C_Tlow_data[I2C_MASTER_RX_DATA_LEN]= {0};   
uint8 I2C_Thight_data[I2C_MASTER_RX_DATA_LEN]= {0};  

//从I2C从设备读取数据
static int I2CRead(void* pi2c,  uint8* data,uint8 len,uint8 slave_addr,uint8 Addr)
{
    int ret ;
    ret=hal_i2c_read(pi2c,slave_addr,Addr,data,len);
    
    return ret;
}

//初始化I2C
void I2c_Demo_Init(uint8 task_id)
{
    i2c_TaskID = task_id;
    LOG("i2c demo start...\r\n");
    //初始化SDA CLK相关引脚(Input / 上拉)
    hal_gpio_pin_init(I2C_MASTER_SDA,IE);
    hal_gpio_pin_init(I2C_MASTER_CLK,IE);
    hal_gpio_pull_set(I2C_MASTER_SDA,STRONG_PULL_UP);
    hal_gpio_pull_set(I2C_MASTER_CLK,STRONG_PULL_UP);
    hal_i2c_pin_init(I2C_0, I2C_MASTER_SDA, I2C_MASTER_CLK); //开启硬件I2C_0
    master_pi2c=hal_i2c_init(I2C_0,I2C_CLOCK_400K);

    if(master_pi2c==NULL)
    {
        LOG("I2C master init fail\r\n");
    }
    else
    {
        LOG("I2C master init OK\r\n");
    }
    osal_start_timerEx(i2c_TaskID, KEY_I2C_READ_DATA_EVT, 10);
}

//任务进程
uint16 I2c_ProcessEvent( uint8 task_id, uint16 events )
{
    if(task_id != i2c_TaskID)
    {
        return 0;
    }

    if( events & KEY_I2C_READ_DATA_EVT)
    {
        uint8_t Tval,Config,Tlow,Thight;
        
        //将获取到的数据,保存到相关数组中
        Tval = I2CRead(master_pi2c,I2C_RX_data,I2C_MASTER_RX_DATA_LEN,slave_i2c_addr,Tval_ADDR);
        Config = I2CRead(master_pi2c,I2C_Config_data,I2C_MASTER_RX_DATA_LEN,slave_i2c_addr,Config_ADDR);
        Tlow = I2CRead(master_pi2c,I2C_Tlow_data,I2C_MASTER_RX_DATA_LEN,slave_i2c_addr,Tlow_ADDR);
        Thight = I2CRead(master_pi2c,I2C_Thight_data,I2C_MASTER_RX_DATA_LEN,slave_i2c_addr,Thight_ADDR);
        
        
        if(Tval==PPlus_SUCCESS)
        {
            LOG("I2C_Tval_data=[");

            for(uint8 i=0; i<I2C_MASTER_RX_DATA_LEN; i++)
            {
                LOG("0x%x,",I2C_RX_data[i]);
            }

            LOG("]\r\n");
            
            
            LOG("I2C_Config_data=[");
            
            for(uint8 i=0; i<I2C_MASTER_RX_DATA_LEN; i++)
            {
                LOG("0x%x,",I2C_Config_data[i]);
            }

            LOG("]\r\n");
            
            LOG("I2C_Tlow_data=[");
            
            for(uint8 i=0; i<I2C_MASTER_RX_DATA_LEN; i++)
            {
                LOG("0x%x,",I2C_Tlow_data[i]);
            }

            LOG("]\r\n");
            
            
            LOG("I2C_Thight_data=[");
            
            for(uint8 i=0; i<I2C_MASTER_RX_DATA_LEN; i++)
            {
                LOG("0x%x,",I2C_Thight_data[i]);
            }

            LOG("]\r\n");
            
           //1000ms获取一次数据  
           osal_start_timerEx(i2c_TaskID, KEY_I2C_READ_DATA_EVT, 1000);
        }

        return (events ^ KEY_I2C_READ_DATA_EVT);
    }
    
    LOG("NO Data\r\n");

    return 0;
}

1、获取的各个寄存器的原始数据如下图所示:

image-20250107225034186.png

2、对数据进行处理,并输出

数据处理后的相关代码:
    
    if( events & KEY_I2C_READ_DATA_EVT)
    {
        uint8_t Tval;
        
        //将获取到的数据,保存到相关数组中
        Tval = I2CRead(master_pi2c,I2C_RX_data,I2C_MASTER_RX_DATA_LEN,slave_i2c_addr,Tval_ADDR);
        
        if(Tval==PPlus_SUCCESS)
        {
    
            //转换后的数据
            char Rx[4];
            sprintf(Rx,"%02x%02x",I2C_RX_data[0],I2C_RX_data[1]);
            char *endptr;
            long int Data =  strtol(Rx, &endptr, 16);
            double T =  (double)Data  * 0.0078125;
            
            usart_printf("T = %.3f\r\n",T); //串口输出温度数据
            
           //500ms获取一次数据  
           osal_start_timerEx(i2c_TaskID, KEY_I2C_READ_DATA_EVT, 500);
        }

        return (events ^ KEY_I2C_READ_DATA_EVT);
    }

    return 0;
}


部分代码的实现:
    
#include <stdarg.h>

void usart_printf(char *format,...)
{
    char String[100];        //定义输出字符串
    va_list arg;             //定义一个参数列表变量va_list是一个类型名,arg是变量名
    va_start(arg,format);    //从format位置开始接收参数表放在arg里面

    //sprintf打印位置是String,格式化字符串是format,参数表是arg,对于封装格式sprintf要改成vsprintf
    vsprintf(String,format,arg);
        
    va_end(arg);             //释放参数表
    hal_uart_send_buff(UART0, (uint8_t*)String, strlen(String));    //uart.c的函数

}    
    

输出数据如下(当前环境室温):

image-20250109201858588.png

当手紧握模块时,温度迅速上升如下:

image-20250109202905733.png

四、模块更多设置

至此,开发板通过I2C连接模块,并输出温度显示在串口中已实现。

若需要配置ALERT功能等,以及修改模块中的相关CONFIG配置,可根据开发手册,进行相关配置。

回复

使用道具 举报

爱笑 | 6 天前 | 显示全部楼层
棒~
用心做好保姆工作
回复

使用道具 举报

第一次听说这个温度传感器,精度±0.09°C很强呀
回复 支持 反对

使用道具 举报

回复

使用道具 举报

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

本版积分规则