第四章 DW_apb_i2c使用2--TMP75读取温度

     

目录

1.TMP75介绍

2.引脚使用说明

 3.寄存器使用说明

4.TMP75寄存器读写流程

5.读取温度例程


        因项目需求,用DW_apb_i2c读写TMP75这个温度传感器,本文仅做个人使用记录。

1.TMP75介绍

        TMP75器件属于数字温度传感器,片上12位模数转换器 (ADC) 具备低至 0.0625°C 的分辨率,TMP75功能总结如下:

(1)可以用i2c进行通信,主要是配置TMP75的工作模式以及获取温度信息;

(2)最多支持8个可配置的设备地址;

(3)支持SMBus Alert功能;

(4)支持广播功能(General Call)

        以上常用功能是我个人的总结,更多详细介绍,清查阅TI官方文档,附上链接:TMP75 data sheet, product information and support | TI.com

2.引脚使用说明

        截图来自官方文档,PIN脚使用不做太多赘述。这里需要注意A0、A1、A2这3个地址控制PIN脚,需要用户在硬件设计上选择拉高或拉低,一共有8种组合,故可以生成8个设备地址,具体见下表:

 硬件电路原理图:

        

当前电路的A0、A1、A2都拉高,所以使用i2c或者smbus通信时,设备地址就是1001111,即0x4f。

 3.寄存器使用说明

        TMP75内部一共有5个寄存器,寄存器结构图如下:

(1)指针寄存器(Pointer Register)

        首先介绍指针寄存器。因为在使用TMP75时,首先就要配置指针寄存器,其配置值表示接下来是读写另外4个寄存器中的哪一个。指针寄存器是一个8bit的寄存器,其低2bit用来指明接下来是读写哪一个寄存器。换句话说,其低2bit表示接下来哪一个寄存器要响应master的读写请求。

        如上图所示,假如指针寄存器的低2bit是01时,即给指针寄存器配置0x01,说明接下来是Configuration register要响应master的读写请求,即表示后面是读写Configuration register,其他值依次类推。

(2)温度传感器(Temperature Register)

        TMP上电时,指针寄存器默认值是0x00,即TMP75上电时默认是可以直接读取温度的。从文档可知,使用中需要连续读取2次温度传感器,才能获取温度值,并且温度传感器是一个12bit有效的只读传感器,有效位见下图:

        从上图可知,T0到T11是温度有效数据位。在实际使用时,读回来的byte1和byte2组成16bit数据,其高12bit是有效温度数据,低4bit数据舍弃。温度计算公式(以0.0625分辨率为例): 

Temperature =((byte1<<4) | (byte2>>4))*0.0625

(3)配置寄存器(Configuration Register)

        这是一个8bit可读可写寄存器,用来控制TMP75的工作模式。bit位定义如下图:

         当前只是读取温度的话,使用默认值就好,后面再研究一下其他模式的用法。

(4)THIGH and TLOW register

        又叫 High and Low Limit Registers ,顾名思义,这2个寄存器是控制温度上限和下限,这里与alert功能的使用有关,当温度超过上限或低于下限时会触发Smbus alert警报。这2个寄存器是可读可写寄存器,读写的时候和上述的温度传感器一样,需要读写2次,高12bit为温度有效值。

4.TMP75寄存器读写流程

        上图是写寄存器流程,Frame1,即第1个byte,是设备地址加写标志位,设备地址怎么设置前面已经说过了;第2个byte是给指针寄存器配置的值,表明接下来是写哪个寄存器;第3个和第4个byte就是给指定寄存器写的值。

        上图是读寄存器流程,Frame1,即第1个byte,是设备地址加上写标志位;第2个byte还是给指针寄存器配置的值;第3个byte是设备地址加上读标志位,第4个和第5个byte就是读回来的值。

5.读取温度例程

截图上部分代码:

#define I2C1_ADDR                (i2c_reg_s *)I2C1_BASE    
/*
*    i2c1 作为 master,采用轮询方式读写 TMP75
*/
void i2c1_master_test_case_for_TMP75(void)
{
    i2c_reg_s *i2c_reg = NULL;
    static i2c_handle_s i2c1_handle = {0};
    unsigned char data[5] = {0};
    unsigned int receive_fifo_empty = 0;
    unsigned short temperature_data = 0;
    unsigned int ic_state = 0;

    i2c1_handle.instance          = I2C1_ADDR;
    i2c1_handle.irq_num           = IRQ_NUM_I2C1;
    i2c1_handle.i2c_mode          = I2C_MODE_MASTER;
    i2c1_handle.i2c_speed_mode    = I2C_BUS_SPEED_STANDARD;
    i2c1_handle.i2c_addr_mode     = I2C_ADDRESS_7BIT;
    i2c1_handle.i2c_general_cell  = GENERAL_CELL_DISABLE;
    i2c1_handle.i2c_restart       = RESTART_DISABLE;
    i2c1_handle.i2c_dma_mode      = DMA_DISABLE;
    i2c1_handle.i2c_notify_type   = I2C_NOTIFY_TYPE_POLL;

    i2c_init(&i2c1_handle);

    dbg_uart_print("i2c1_master_test_case_for_TMP75 init end!!\r\n");

    i2c_reg = i2c1_handle.instance;
    i2c_set_transmit_fifo_threshold(i2c_reg, 2);
    i2c_set_receive_fifo_threshold(i2c_reg, 2);
    i2c_clear_all_irq(i2c_reg);

    i2c_set_slave_address(i2c_reg,0x4f);                            // TMP75地址:100 1111
    mdelay(1);
    i2c_transmit_byte(i2c_reg, 0x00, WRITE_OPERATION, NO_STOP);     //Pointer Register配置0x00,表示后面是操作Temperature register
    mdelay(1);
    i2c_transmit_byte(i2c_reg, 0x00, READ_OPERATION, NO_STOP);      //read 0x00 to get the first byte
    mdelay(1);
    i2c_transmit_byte(i2c_reg, 0x00, READ_OPERATION, SEND_STOP);    //read 0x00 again to get the second byte
    mdelay(5);

    ic_state = i2c_get_ic_status(i2c_reg);                        // get i2c irq status
    if ((ic_state & I2C_STATUS_RFNE) == I2C_STATUS_RFNE) {        // receive fifo not empty
        data[0] = i2c_receive_byte(i2c_reg);                      // get receive data
        dbg_uart_print("data[0]=0x%x\r\n",data[0]);
        ic_state = 0;
    }
    ic_state = i2c_get_ic_status(i2c_reg);                        // get i2c irq status
    if ((ic_state & I2C_STATUS_RFNE) == I2C_STATUS_RFNE) {        // receive fifo not empty
        data[1] = i2c_receive_byte(i2c_reg);                      // get receive data
        dbg_uart_print("data[1]=0x%x\r\n",data[1]);
        ic_state = 0;
    }
    temperature_data = (data[0]<<4 | data[1]>>4);
    dbg_uart_print("temperature_data=0x%x\r\n",temperature_data);
    dbg_uart_print("temperature_data=%f\r\n",(temperature_data*0.0625));
}

        我用的是Synopsys的DW_apb_i2c控制器,上图是DW_apb_i2c的用法,不同产商的i2c使用方法有差异,这里不展开讲,我们的重点是要搞清楚TMP75使用方法。划重点:先配置指针寄存器为0x00,表示后续是读写温度寄存器;然后连续发送两次读请求,用来获取温度寄值;读回来第一个byte放在data[0],第二个byte放在data[1];拼接一下,按公式计算出当前测量出来的温度值。

串口打印结果:

 逻辑分析仪抓取波形:

 

能看到这里,你可真是个狠人,相信已经很累了吧,那就扫个码吧,让你放松一下。

  • 15
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原海青木

你的鼓励将是我创作的最大动力.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值