【BLE】CC2541之硬件IIC(TMP102温度传感器)

本篇博文最后修改时间:2017年01月06日,11:06。


一、简介

本文以SimpleBLEPeripheral为例,介绍如何使用硬件IIC读取温度传感器TMP102。


二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Smart RF开发板(主芯片CC2541)

传感器芯片:TMP102


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
暂无

2、在进行本文步骤前,请先 实现以下博文:
暂无


五、基础知识

1什么是IIC?

答:IIC是Inter-Integrated Circuit(集成电路总线),有时会写成I2C(读作“I方C”,方是平方的意思)。

它是类似于UART、CAN、SPI的总线,两线(SDL、SCL)即可进行通信,常用波特率是400K。


2、IIC与其他总线的区别?

答:



3、硬件IIC和软件IIC有什么区别?

答:

1)硬件IIC

简介:CC2541内部有硬件IIC模块,只要对IIC的寄存器进行配置后,即可由硬件IIC模块实现IIC通信协议。

优势:较少占用mcu。

劣势:有些芯片商做的硬件IIC会有BUG;较难学会使用。

2)软件IIC

简介:普通芯片的任意两个IO口,都能通过模拟IIC的协议来模拟IIC。

优势:无惧硬件IIC的BUG;简单易用;便于移植

劣势:需要大量延时函数,过多地占用mcu,在CC2541中使用容易断开


4、TI的协议栈中是否有硬件IIC的驱动代码?

答:有,使用起来很方便。


5、TMP102是什么?

答:

1)定义:TMP102是兼容SMBus和I2C串行总线的温度传感器。

2)两种模式:normal mode (EM bit = 0) or extended mode (EM bit = 1),分别对应12位精度与13位精度。

3)5个寄存器:Pointer Register(指针寄存器)、Temperature Register(温度寄存器)、Configuration Register(配置寄存器)、T LOW Register(低温阈值寄存器)、T HIGH Register(高温阈值寄存器)。

4)引脚图:


其中ALERT用于温度阈值时报警。

ADD0用于片选。

5)常用连接原理图(本篇使用这种,只是ALERT可不接)


上图的片选脚ADD0接地,因此TMP102的地址如下:



6、TMP102的5个寄存器如何使用?

答:

1)Pointer Register(指针寄存器)


IIC读写控制默认就是指向这个指针寄存器,而这个指针会根据数值不同而指向不同的寄存器。

比如CC2541往TMP102芯片里写0x01时,它会直接对应到配置寄存器Configuration Register,再根据后面的读、写标志位,来判断是对Configuration Register读还是写。


2)Temperature Register(温度寄存器)



12位或13位的温度数据,被保存在上面的两个寄存器里。其中第2字节的低3位无用。


3)Configuration Register(配置寄存器)


配置寄存器也是2个字节,最重要的位就是BYTE1的D7位了。

Byte1的各位数含义:

OS:“0”表示从转换模式进入关断模式;“1”表示从关断模式进行一次温度数据转换。

R1/R0:转换器分辨率位,默认0x11,表示12位分辨率。

F1/F0:温度超出High/Low寄存器限制时而存在。见Table12

POL:Alert Pin的工作方式,与Byte2的AL搭配。见Figure 13

TM:“0”表示比较模式;“1”表示中断模式。

SD:关断模式(Shutdown mode),“0”表示维持数据转换(ADC)状态,“1”表示现有数据转换完成,关断转换状态。


Byte2的各位数含义:

CR1/CR0:数据转换(ADC)速率。见Table 5

AL:与Byte1的POL搭配。figure13。

EM:“0”表示正常工作模式,数据格式12位;“1”表示扩展工作模式,数据格式13位。


附图:




4、T HIGH Register(高温阈值寄存器)T LOW Register(低温阈值寄存器



一共有4个字节,高温阈值两字节、低温阈值两字节。


六、实验步骤

1、编写并添加TMP102驱动

1)写一个TMP102.c(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)

//******************************************************************************          
//name:         TMP102.c        
//introduce:    TMP102驱动源文件     
//author:       甜甜的大香瓜        
//changetime:   2016.04.12      
//email:        897503845@qq.com      
//******************************************************************************
#include "TMP102.h"  
#include "GUA_sensor.h"  
#include "hal_i2c.h"  
  
/*********************宏定义************************/  
//Slave address   
#define TMP102_DEV_ADDR                         0x48    //0 1001000(最高位无用、ADD0接GND)  
  
//TMP102 register addresses  
#define TMP102_REG_ADDR_TEMPERATURE             0x00  
#define TMP102_REG_ADDR_CONFIG                  0x01  
  
/* Register length */  
#define IRTEMP_REG_LEN                          2  
  
  
/*********************内部函数************************/  
static U8 TMP102_Config(U8 *p_Data, U8 nWrite_Read);  
  
//******************************************************************************                
//name:             TMP102_Init    
//introduce:        TMP102初始化  
//parameter:        none   
//return:           TURE:初始化成功,FALSE:初始化不成功            
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
U8 TMP102_Init(void)  
{  
  U8 nRet = TRUE;    
  U8 bConfig_Data_Read[2] = {0};  
  U8 bConfig_Data_Write[2] = {0x70, 0xA0};   
    
  //开启iic模块、记录下从机地址、配置频率为533KHz  
  HalI2CInit(TMP102_DEV_ADDR, i2cClock_267KHZ);   
    
  //读配置寄存器  
  nRet = TMP102_Config(bConfig_Data_Read, TPM102_REGISTER_READ);   
  if(nRet == FALSE)  
  {  
    return(FALSE);  
  }  
    
  //写配置寄存器,开启温度转换功能  
  nRet = TMP102_Config(bConfig_Data_Write, TPM102_REGISTER_WRITE);  
  if(nRet == FALSE)  
  {  
    return(FALSE);  
  }  
    
  //读配置寄存器    
  nRet = TMP102_Config(bConfig_Data_Read, TPM102_REGISTER_READ);  
  if(nRet == FALSE)  
  {  
    return(FALSE);  
  }  
  
  return(TRUE);    
}  
  
//******************************************************************************                
//name:             TMP102_Config    
//introduce:        读写TMP102的配置寄存器的值  
//parameter:        pData:数据, nWrite_Read:   
//return:           none            
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
static U8 TMP102_Config(U8 *pData, U8 nWrite_Read)  
{  
  switch(nWrite_Read)  
  {  
    case TPM102_REGISTER_READ:  
        if(HalSensorReadReg(TMP102_REG_ADDR_CONFIG, pData, IRTEMP_REG_LEN))  
        {  
          return(TRUE);  
        }   
        else  
        {  
          return(FALSE);  
        }        
        break;  
              
    case TPM102_REGISTER_WRITE:  
        if(HalSensorWriteReg(TMP102_REG_ADDR_CONFIG, pData, IRTEMP_REG_LEN))  
        {  
          return(TRUE);  
        }   
        else  
        {  
          return(FALSE);  
        }        
        break;  
  
    default:  
        return(FALSE);  
        break;       
  }  
}  
  
//******************************************************************************                
//name:             TMP102_Temperature_Read    
//introduce:        读写TMP102的温度值  
//parameter:        pData:读缓冲区   
//return:           TURE:读取成功,FALSE:读取失败             
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
U8 TMP102_Temperature_Read(U8 *pData)  
{  
  if(HalSensorReadReg(TMP102_REG_ADDR_TEMPERATURE, pData, IRTEMP_REG_LEN))  
  {  
    return(TRUE);  
  }   
  else  
  {  
    return(FALSE);  
  }   
}  


2)写一个头文件TMP102.h(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)

//******************************************************************************          
//name:         TMP102.h        
//introduce:    TMP102驱动的头文件     
//author:       甜甜的大香瓜        
//changetime:   2016.04.12      
//email:        897503845@qq.com      
//******************************************************************************
#ifndef TMP102_H  
#define TMP102_H  
  
/*********************宏定义************************/
#ifndef U8  
typedef unsigned char U8;  
#endif  
  
#ifndef U16  
typedef unsigned short U16;  
#endif  
  
#ifndef TRUE  
#define TRUE 1  
#endif  
  
#ifndef FALSE  
#define FALSE 0  
#endif  
  
#define TPM102_REGISTER_READ                    0  
#define TPM102_REGISTER_WRITE                   1  
  

/*********************外部函数************************/  
extern U8 TMP102_Init(void);  
extern U8 TMP102_Temperature_Read(U8 *pData);  
  
#endif  

2、编写传感器控制的驱动

1)写一个GUA_sensor.c(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)

//******************************************************************************          
//name:         GUA_sensor.c        
//introduce:    传感器控制的源文件     
//author:       甜甜的大香瓜        
//changetime:   2016.04.12      
//email:        897503845@qq.com      
//******************************************************************************
#include "GUA_sensor.h"
#include "hal_i2c.h"

/*********************内部变量************************/
static uint8 buffer[24];

//******************************************************************************                
//name:             HalSensorInit    
//introduce:        传感器初始化  
//parameter:        dev_addr:设备地址   
//return:           none           
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
void HalSensorInit(uint8 dev_addr )
{
  HalI2CInit(dev_addr, i2cClock_533KHZ);
}

//******************************************************************************                
//name:             HalSensorReadReg    
//introduce:        传感器读函数  
//parameter:        寄存器addr:地址, pBuf:读缓冲区,  nBytes数据长度  
//return:           TURE:读成功,FALSE:读不成功        
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
bool HalSensorReadReg(uint8 addr, uint8 *pBuf, uint8 nBytes)
{
  uint8 i = 0;

  /* Send address we're reading from */
  if (HalI2CWrite(1,&addr) == 1)
  {
    /* Now read data */
    i = HalI2CRead(nBytes,pBuf);
  }

  return i == nBytes;
}

//******************************************************************************                
//name:             HalSensorWriteReg    
//introduce:        传感器写函数  
//parameter:        寄存器addr:地址, pBuf:写缓冲区,  nBytes数据长度  
//return:           TURE:写成功,FALSE:写不成功        
//author:           甜甜的大香瓜         
//email:            897503845@qq.com       
//changetime:       2016.04.12             
//****************************************************************************** 
bool HalSensorWriteReg(uint8 addr, uint8 *pBuf, uint8 nBytes)
{
  uint8 i;
  uint8 *p = buffer;

  /* Copy address and data to local buffer for burst write */
  *p++ = addr;
  for (i = 0; i < nBytes; i++)
  {
    *p++ = *pBuf++;
  }
  nBytes++;

  /* Send address and data */
  i = HalI2CWrite(nBytes, buffer);
  //if ( i!= nBytes)
  //  HAL_TOGGLE_LED2();

  return (i == nBytes);
}

2)写一个GUA_sensor.h(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)

//******************************************************************************          
//name:         GUA_sensor.h        
//introduce:    传感器控制的头文件     
//author:       甜甜的大香瓜        
//changetime:   2016.04.12      
//email:        897503845@qq.com      
//******************************************************************************
#ifndef GUA_SENSOR_H
#define GUA_SENSOR_H

#ifdef __cplusplus
extern "C"
{
#endif

/*********************头文件************************/
#include "hal_types.h"

/*********************外部函数************************/
void   HalSensorInit(uint8 dev_addr );
bool   HalSensorReadReg(uint8 addr, uint8 *pBuf, uint8 nBytes);
bool   HalSensorWriteReg(uint8 addr, uint8 *pBuf, uint8 nBytes);

#ifdef __cplusplus
}
#endif

#endif


3、工程中添加相关文件

1)将“……\BLE-CC254x-1.4.0\Components\hal\target\CC2541ST”路径下的“hal_i2c.c、hal_i2c.h”2个文件,复制到“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA\IIC”路径下。


2)工程中添加“TMP102.c、TMP102.h、GUA_sensor.c、GUA_sensor.h”和“hal_i2c.c、hal_i2c.h



3)在IAR设置中添加按键驱动源文件路径

$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA\IIC

4、在应用层中读取温度值

1)添加TMP102头文件(SimpleBLEPeripheral.c中)

//GUA
#include "TMP102.h"
//GUA

2)TMP102初始化(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)

  //TMP102初始化
  TMP102_Init();
  TMP102_Temperature_Read(sbTemperature_Data);

3)定义一个存放温度值的数组(SimpleBLEPeripheral.c中)

//GUA 
static U8 sbTemperature_Data[2] = {0};           //温度数据
//GUA

七、注意事项

暂无


八、实验结果

1)读取结果


读取到的值为0x0F60


2)换算实际结果

由于低3位没用,12bit的模式低4位都没用。

因此0x0F60(00001111 01100000)右移4位后为0x0F6(00000000 11110110),用计算器换算为10进制数为246。

根据公式计算为:246*0.0625=15.375°


(手头暂时没有准确的温度计对比,因此后续还需要验证准不准。)





  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值