简介
ESP32是国产乐鑫公司生产的32位单片机,双核240MHz,带有蓝牙和wifi功能,本例中使用的是ESP32-S模组。TMP117是德州仪器(TI)推出的I2C温度传感器系列,本例中使用的具体型号是TMP117MAIDRVR。本例中使用的开发环境是VSCODE安装ESP-IDF插件。
硬件连接
TMP117的引脚定义
这里需要注意的是芯片根据ADD0引脚连接不同的网络,I2C地址会发生变化,具体的定义如下图
表中的X代表I2C通讯中代表读写的bit,需要注意的是,在ESP的I2C库函数中,传入参数的地址是7位的地址,在函数中会右移一位并在最低位加上代表读写的bit组成8位的读地址或写地址。举例来说,假如ADD0连接Ground,按照表中的地址是1001000X,那么要传入I2C函数中传入的地址应该为01001000也就是0x48。
TI的数据手册上给出的典型应用电路
这里需要注意的是在使用ESP32作为主机的时候,由于ESP32的芯片手册上提醒了ESP32的数字IO口自带上拉电阻,所以应用电路图中的5Kohm上拉电阻要去掉直接连接到ESP32的IO口。
本人搭建的ESP32-S电路
本人搭建的TMP117外围电路
这里为了方便我将ADD0接到了3.3V,按照前面的表格地址变成了0x49,具体按照自己的要求来接。
使用方法
首先配置ESP-IDF的配置文件,将I2C使用的SDA和SCL引脚配置为和电路中一样(按照自己的电路连接配置)。在VSCODE主界面按F1,在弹出的搜索框内选择ESP-IDF SDK配置编辑器。在左边选择Example Configuration,在右边的SCL GPIO Num和SDA GPIO Num中输入自己的硬件连接的IO口,点击右上角的保存。
上电后TMP117默认进入连续转换模式,每经过一次转换时间更新一次温度寄存器的值,读取温度寄存器(地址0x00)即可获取当前温度值。精度为0.0078125摄氏度每LSB,也就是读取到的原始数据作为16位有符号数乘上0.0078125就得到当前摄氏温度值。
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "i2c-simple-example";
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000
#define TMP117_ADDR 0x49 /*!< Slave address of the MPU9250 sensor */
#define TMP117_TMP_RIG_ADDR 0x00 //温度寄存器地址
#define TMP117_RESOLUTION 0.0078125 //转换精度
static esp_err_t M117B_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, TMP117_ADDR, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
}
/**
* @brief i2c master initialization
*/
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
float MY_OutputtoTemp(int16_t out)
{
return ((float) out * TMP117_RESOLUTION);
}
void app_main(void)
{
uint8_t data[2];
int16_t iTemp;
float ftemp;
ESP_ERROR_CHECK(i2c_master_init());
ESP_LOGI(TAG, "I2C initialized successfully");
vTaskDelay(15 / portTICK_PERIOD_MS);
while(1)
{
ESP_ERROR_CHECK(M117B_register_read(TMP117_TMP_RIG_ADDR , data, 2));
vTaskDelay(15 / portTICK_PERIOD_MS);
iTemp=(int16_t)((data[0] << 8) | data[1]);
ftemp=MY_OutputtoTemp((int16_t)iTemp);
ESP_LOGI(TAG, "M117 Temp: %.3f \n",ftemp);
vTaskDelay(975 / portTICK_PERIOD_MS);
}
}