本帖最后由 AndyL 于 2025-1-10 20:13 编辑
PB_03F_Kit连接AS6221温度传感器模块(IIC)
一、硬件介绍
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 地址设定,支持中断预警模式。
二、硬件连接
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 等功能。
2、连接方式(IIC通讯模式 / 数据解析)
1、AS6221 Eval Kit模块引脚介绍:
Pin |
符号 |
说明 |
备注 |
1 |
SCL |
I2C时钟线 |
如需上拉,使用R1 |
2 |
SDA |
I2C数据线 |
如需上拉,使用R2 |
3 |
GND |
地 |
- |
4 |
VDD |
电源供应 |
- |
5 |
ALERT |
数字输出引脚 |
警报中断输出 |
注:不要将引脚5接到VSS,此引脚只用于ALERT功能
2、I2C地址选择方式:
使用跳线帽设置I2C的地址,且两个位置的跳线帽不能打开。
配置方式如下所示:
3、MCU与模块连接方式:
SDA -> P33
CLK -> P34
ALERT警报功能未使用,不连接。(根据实际情况自行配置)
4、模块输出数据解析
1.TVAL(0x0寄存器地址):当前获取的温度值。
2.CONFIG(0x1寄存器地址):当前配置的相关信息。
3.TLOW(0x2寄存器地址):温度下限警报值。
4.THIGH(0x3寄存器地址):温度上限警报值。
1、温度值TVAL数据解析
为获取模块的温度值,需要读取TVAL(0x0寄存器地址)的值,输出的温度数值为 2字节数据(例:0xb,0x22)
LSB = (1 / 128)°C = 0.0078125 °C
*实际数值 = 读取到的数值 LSB = 2850(0xb22[hex]) * LSB ≈ 22.265°C*
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 中断引脚,相关转换过程如下。
三、代码编写
以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、获取的各个寄存器的原始数据如下图所示:
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的函数
}
输出数据如下(当前环境室温):
当手紧握模块时,温度迅速上升如下:
四、模块更多设置
至此,开发板通过I2C连接模块,并输出温度显示在串口中已实现。
若需要配置ALERT功能等,以及修改模块中的相关CONFIG配置,可根据开发手册,进行相关配置。