一、硬件介绍
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模块引脚介绍:
1 | SCL | I2C时钟线 | 如需上拉,使用R1 |
2 | SDA | I2C数据线 | 如需上拉,使用R2 |
3 | GND | 地 | - |
4 | VDD | 电源供应 | - |
5 | 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。
根据下表,可知每位代表的含义,以及是否可修改相关属性;
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地址如“图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的函数 }
输出当前室内温度数据:
当手紧握模块时,温度迅速上升: