资讯详情

STM32F030读取TMP275温度传感器,模拟iic。

文章目录

  • 前言
  • 一、tmp275介绍
  • 二、关于tmp275的使用分析
    • 1.TMP275的地址设置
    • 2.tmp275的指针寄存器和分辨率设置
    • 3.通过配置寄存器设置分辨率
  • 三、STM32F030读取tmp275温度例程


前言

未经许可不得转载!


一、tmp275介绍

tmp275是一个12位模数转换器(adc)的±0.5°c精 数字温度传感器密集成。TMP275 能够以最高 0.0625°C (12 位) ,最低 0.5°C (9 位) 的分辨率读 取温度,让用户编写 分辨率更高或转换更短 最大限度地提高时间 效率.设备的额定工作温度范围 为 –40°C 至 125°C。TMP275 器件 特有 系统管理总线 (SMBus) 和两线制 在同一总线的帮助下,接口兼容性可以 SMBus 过热 多达支持报警功能 8 个器件。

二、关于tmp275的使用分析

1.TMP275的地址设置

要与TMP275通信,主必须首先从地址字节到设备地址。读写操作的意图由7个地址位置和指示执行。 图的方向位组成。 在这里插入图片描述 举栗: 我们可以知道这张图A0、A1、A2是接地的,所以我们的7bit地址为:100100。然后根据I2C协议。最后一个地址。bit写:0 读:1 (示例):

     写地址:1001000  = 0x90      读地址:1001001  = 0x91 

2.tmp275指针寄存器和分辨率设置

表3是TMP275中可用 寄存器的指针地址。P1/P0的通电复位值为00。 00-温度寄存器 01-配置寄存器 02-下限设置寄存器 03-寄存器设置在上限

3.通过配置寄存器设置分辨率

SD:TMP275的关闭模式允许用户关闭除串行接口以外的所有设备电路,以节省最大功率,并将电流消耗降低到通常的小功率 于0.1μA。当SD位于1时,启用关闭模式;当前转换完成后,设备关闭。SD等于0,设备保持连续转换。 转换器分辨率(R1/R0): 转换器分辨率位控制内部模数(A/D)转换器的分辨率。这种控制允许用户编程更高的分辨率或更快的转换时间 最大化效率。表6确定了分辨率位与分辨率与转换时间的关系。 根据自己的实际情况使用其他位置。如果只需读取温度数据,就可以配置这两项。

在这里,我们将分辨率设置为12位: (示例):

    I2C_Start();   I2C_Send_Byte(0x90);   while(I2C_Wait_Ack()); //接收到ACK信号   I2C_Send_Byte(0x01);   //跳转到配置寄存器   while(I2C_Wait_Ack());     I2C_Send_Byte(0x60);  //设置为12位分辨率 

三、STM32F030读取tmp275温度例程

(基础的iic不介绍总线,直接上例程) iic.h

#ifndef _IIC_H #define _IIC_H  #define LOW 0 #define HIGH 1  #define I2C_SCL(x) x==1?GPIO_SetBits(GPIOB,GPIO_Pin_6): GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define I2C_SDA(x) x==1?GPIO_SetBits(GPIOB,GPIO_Pin_7): GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define READ_SDA GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)

#define READSLAVEADDR 0x91
#define WRITESLAVEADDR 0x90

#define SDA_IN() { 
          GPIOB->MODER &= 0xffff3fff;}
#define SDA_OUT() { 
          GPIOB->MODER &= 0xffff3fff; GPIOB->MODER |= (uint32_t)(1 << 14);}

void iic_init(void);
void ReadDeviceData(void);
#endif

iic.c:

#include "iic.h"

//起始信号
void I2C_Start(void)
{ 
        
	 SDA_OUT();
	 I2C_SCL(HIGH);
	 I2C_SDA(HIGH);
	 Delay_Us(2);
	 I2C_SDA(LOW);
	 Delay_Us(2);
	 I2C_SCL(LOW);   //开始占用总线,准备发送
	 Delay_Us(2);
}

//当SCL为高的时候,SDA从低变到高
//停止信号
void I2C_Stop(void)
{ 
        
	 SDA_OUT();
	 I2C_SCL(LOW);
	 I2C_SDA(LOW);
	 Delay_Us(2);
	 I2C_SCL(HIGH);
	 I2C_SDA(HIGH);
	 Delay_Us(2);
}

//应答
void I2C_Ack(void)
{ 
        
	 I2C_SCL(LOW);
	 SDA_OUT();
	 I2C_SDA(LOW);
	 Delay_Us(2);
	 I2C_SCL(HIGH);
	 Delay_Us(2);
	 I2C_SCL(LOW);	
}

//非应答信号
void I2C_NAck(void)
{ 
        
	 I2C_SCL(LOW);
     SDA_OUT();
     I2C_SDA(HIGH);
     Delay_Us(2);
     I2C_SCL(HIGH);
     Delay_Us(2);
     I2C_SCL(LOW);	
}

//等待应答信号
uint8_t I2C_Wait_Ack(void)
{ 
        
	 uint8_t ucErrTime=0;
	
	 SDA_IN();
	 I2C_SCL(HIGH);
	 Delay_Us(1);
	 I2C_SDA(HIGH);
	 Delay_Us(1);
	 
	 while(READ_SDA) //如果为零表示接收到应答
	 { 
        
		  ucErrTime++;
		  if(ucErrTime>250)
			{ 
        
				 I2C_Stop();
				 return 1;
			}
	 }
	 I2C_SCL(LOW);
	 return 0;
}

//发送函数
void I2C_Send_Byte(uint8_t data)
{ 
        
	 uint8_t i=0;
	
	 SDA_OUT();
	 I2C_SCL(LOW);
	 for(i=0 ;i<8 ; i++)
	 { 
        
		  if(((data&0x80)>>7)==1) I2C_SDA(HIGH);
		  else I2C_SDA(LOW);
		  data=data<<1;
		  I2C_SCL(HIGH);
		  Delay_Us(4);
		  I2C_SCL(LOW);
		  Delay_Us(4);
	 }
}

//接收函数
uint8_t I2C_Read_Byte(uint8_t ack)
{ 
        
	 uint8_t i,receive=0;
	
	 SDA_IN(); 
	 for(i=0 ;i<8 ; i++)
	 { 
        
		  I2C_SCL(LOW);
		  Delay_Us(4);
		  I2C_SCL(HIGH);
		  Delay_Us(4);
		  receive=receive<<1;
		  if(READ_SDA) receive++;
		  Delay_Us(4);
	 }
	 
	 if(!ack) I2C_NAck();
	 else I2C_Ack();
	
   return receive;	 
}

void iic_init(void)
{ 
        
	GPIO_InitTypeDef        GPIO_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;   //SCL,SDA 
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOB, &GPIO_InitStructure); 	
	
	I2C_SCL(HIGH);
	I2C_SDA(HIGH);
	
	//设置TMP275的配置寄存器
	I2C_Start();
	I2C_Send_Byte(0x90);
	while(I2C_Wait_Ack()); //接收到ACK信号
	I2C_Send_Byte(0x01);   //配置温度寄存器
    while(I2C_Wait_Ack());
	I2C_Send_Byte(0x60);  //设置成12位分辨率
	while(I2C_Wait_Ack());
	//改变编程指针指向
	I2C_Start();
	I2C_Send_Byte(0x90);
	if(I2C_Wait_Ack()) return ;
	I2C_Send_Byte(0x00);   //切换到温度数据寄存器
	if(I2C_Wait_Ack()) return ;
	I2C_Stop();
}

void ReadDeviceData()
{ 
        
	int16_t temp=0;
	I2C_Start();
	I2C_Send_Byte(READSLAVEADDR);
	if(I2C_Wait_Ack()) return ;
	temp = I2C_Read_Byte(1);
	temp = temp<<8;
	temp |= I2C_Read_Byte(0);
	I2C_Stop();
	temp = temp >> 4;
	
	printf("temp=%.1f\r\n",temp*0.0625);
}

“delay.h”

#ifndef _DELAY_H
#define _DELAY_H

void Delay_Init(void);
void Delay_Us(uint16_t time);
void Delay_Ms(uint16_t time);
#endif

“delay.c”

#include "delay.h"

static uint16_t fan_us=0;
static uint16_t fan_ms=0;

void Delay_Init()
{ 
        
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    fan_us=SystemCoreClock/8000000;
	fan_ms=(uint16_t)fan_us * 1000;
}

void Delay_Us(uint16_t time)
{ 
        
	uint32_t temp=0;
	SysTick->VAL=0x00;
    SysTick->LOAD=(uint32_t)time*fan_us;	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
	do
	{ 
        
		 temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(0x01<<16)));
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
	SysTick->VAL=0x00;	
}

void Delay_Ms(uint16_t time)
{ 
        
	uint32_t temp=0;
	SysTick->VAL=0x00;
    SysTick->LOAD=(uint32_t)time*fan_ms;	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
	do
	{ 
        
		 temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(0x01<<16)));
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
	SysTick->VAL=0x00;	
}

标签: 传感器3313a2h

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台