TMP117温度传感器驱动(模拟IO IIC)

#include "tmp117.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
           
#define SD5075_SCL_GPIO_Port    GPIOA
#define SD5075_SCL_Pin          LL_GPIO_PIN_9

#define SD5075_SDA_GPIO_Port    GPIOA
#define SD5075_SDA_Pin          LL_GPIO_PIN_10


#define SCL_L      LL_GPIO_ResetOutputPin(SD5075_SCL_GPIO_Port, SD5075_SCL_Pin)
#define SCL_H      LL_GPIO_SetOutputPin(SD5075_SCL_GPIO_Port, SD5075_SCL_Pin)

#define SDA_L      LL_GPIO_ResetOutputPin(SD5075_SDA_GPIO_Port, SD5075_SDA_Pin)
#define SDA_H      LL_GPIO_SetOutputPin(SD5075_SDA_GPIO_Port, SD5075_SDA_Pin)

//#define SDA_IN     {};
	
//#define SDA_OUT    gpio_mode_set(SD5075_SDA_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, SD5075_SDA_Pin)


/*开漏 无需切换输入输出*/

//#define SDA_IN     {;}
//#define SDA_OUT    {;}


#define SDA_READ   LL_GPIO_IsInputPinSet(SD5075_SDA_GPIO_Port,SD5075_SDA_Pin)

void SDA_IN(void)
{
	LL_GPIO_SetPinMode(SD5075_SDA_GPIO_Port,SD5075_SDA_Pin,LL_GPIO_MODE_INPUT);
}
void SDA_OUT(void)
{   
	LL_GPIO_SetPinMode(SD5075_SDA_GPIO_Port,SD5075_SDA_Pin,LL_GPIO_MODE_OUTPUT);
}

float tempreture[10] = {0};

void tmp117_config(void)
{
	
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* GPIO Ports Clock Enable */
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
  /**/
  GPIO_InitStruct.Pin = SD5075_SCL_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  LL_GPIO_Init(SD5075_SCL_GPIO_Port, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pin = SD5075_SDA_Pin;
  LL_GPIO_Init(SD5075_SDA_GPIO_Port, &GPIO_InitStruct);

	
	
	SCL_H;
	SDA_H;
	
//	gpio_bit_reset(SD5075_ADDR_GPIO_Port,SD5075_ADDR0_Pin|SD5075_ADDR1_Pin|SD5075_ADDR2_Pin);	/*设置地址 0 0 0  48H*/
}

/***********************iic**************************/
void delay_nop(void)
{
 unsigned int i;
 for(i=0;i<60;i++)
	__ASM("nop");
}

//产生IIC起始信号
void IIC_Start(void)
{
		SDA_OUT();//sda线输出
		SDA_H;
		SCL_H;
		delay_nop();
		SDA_L;//START:when CLK is high,DATA change form high to low
		delay_nop();
		SCL_L;//钳住I2C总线,准备发送或接收数据
}

//产生IIC停止信号
void IIC_Stop(void)
{
		SDA_L;
		SDA_OUT();//sda线输出
		SCL_L;
		delay_nop();
		SCL_H;
		delay_nop();
		SDA_H;//发送I2C总线结束信号
		delay_nop();
}
//等待应答信号到来
//返回值:
//  1,接收应答失败
//  0,接收应答成功
uint8_t IIC_Wait_Ack(void)
{
		uint8_t flag;

		SDA_IN(); //SDA设置为输入
		SDA_H;
		delay_nop();
		SCL_H;
		delay_nop();
		if(SDA_READ)
			flag=1;
		else
			flag=0;
		SCL_L;  //时钟输出0
		return flag;
}
//产生ACK应答
void IIC_Ack(void)
{
		SCL_L;
		SDA_OUT();
		SDA_L;
		delay_nop();
		SCL_H;
		delay_nop();
		SCL_L;
}
//不产生ACK应答
void IIC_NAck(void)
{
		SCL_L;
		SDA_OUT();
		SDA_H;
		delay_nop();
		SCL_H;
		delay_nop();
		SCL_L;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(uint8_t txd)
{
		uint8_t t;
		SDA_OUT();
		SCL_L;//拉低时钟开始数据传输
		for(t=0;t<8;t++)
		{
			if((txd&0x80)>>7)
				SDA_H;
			else SDA_L;
				txd<<=1;
			delay_nop();
			SCL_H;
			delay_nop();
			SCL_L;
		}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t IIC_Read_Byte(uint8_t ack)
{
		uint8_t i,receive=0;
		SDA_IN();
		for(i=0;i<8;i++ )
		{
			SCL_L;
			delay_nop();
			SCL_H;
			delay_nop();
			receive<<=1;
			if(SDA_READ)
			receive++;
		}
		if (!ack)
			IIC_NAck();//发送nACK
		else
			IIC_Ack(); //发送ACK
		
		return receive;
}

double tmp117_temp_get(void)
{
	uint8_t tempH,tempL;
	uint16_t temp;
	IIC_Start();
	IIC_Send_Byte(0x90);
	IIC_Wait_Ack();
	IIC_Send_Byte(0x00);
	IIC_Wait_Ack();
	
	IIC_Start();
	IIC_Send_Byte(0x91);
	IIC_Wait_Ack();
	
	tempH = IIC_Read_Byte(1);
	IIC_NAck();
	tempL = IIC_Read_Byte(0);
	
	IIC_Stop();
	temp = (tempH<<8) + tempL;
//	if((temp&0x8000)!=0)// -
//	{
//		tempre =  ((temp>>4) - 4096.0)/16.0;
//	}
//	else
//	{
//		tempre =  (temp>>4)/16.0;
//	}
//	sum = 0;
//	for(i=0;i<9;i++)
//	{
//		tempreture[i] = tempreture[i+1];
//		sum += tempreture[i+1];
//	}	
//	tempreture[9] = tempre;
//	sum += tempre;
	return temp*0.0078125;
}

使用时调用tmp117_temp_get函数即可

tmp117_temp_get()

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于STM32F4系列单片机IO模拟IIC读取TMP102温度的示例代码: ```c #include "stm32f4xx.h" #define SDA_PIN GPIO_Pin_9 #define SDA_GPIO_PORT GPIOB #define SDA_GPIO_CLK RCC_AHB1Periph_GPIOB #define SCL_PIN GPIO_Pin_8 #define SCL_GPIO_PORT GPIOB #define SCL_GPIO_CLK RCC_AHB1Periph_GPIOB #define I2C_SPEED 100000 void IIC_Delay(void) { uint16_t i = 7 * (SystemCoreClock / 10000000); while(i--); } void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(SDA_GPIO_CLK | SCL_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SCL_PIN; GPIO_Init(SCL_GPIO_PORT, &GPIO_InitStructure); GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); } void IIC_Start(void) { GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); GPIO_ResetBits(SDA_GPIO_PORT, SDA_PIN); IIC_Delay(); GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); } void IIC_Stop(void) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); GPIO_ResetBits(SDA_GPIO_PORT, SDA_PIN); IIC_Delay(); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); } uint8_t IIC_WaitAck(void) { uint16_t i = 50000; GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); IIC_Delay(); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); while(GPIO_ReadInputDataBit(SDA_GPIO_PORT, SDA_PIN)) { if(!(i--)) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); return 1; } } GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); return 0; } void IIC_Ack(void) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); GPIO_ResetBits(SDA_GPIO_PORT, SDA_PIN); IIC_Delay(); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); } void IIC_NAck(void) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); IIC_Delay(); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); } void IIC_WriteByte(uint8_t byte) { uint8_t i = 8; while(i--) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); if(byte & 0x80) GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); else GPIO_ResetBits(SDA_GPIO_PORT, SDA_PIN); byte <<= 1; IIC_Delay(); GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); } GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); } uint8_t IIC_ReadByte(uint8_t ack) { uint8_t i = 8, byte = 0; GPIO_SetBits(SDA_GPIO_PORT, SDA_PIN); while(i--) { GPIO_ResetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); byte <<= 1; if(GPIO_ReadInputDataBit(SDA_GPIO_PORT, SDA_PIN)) byte |= 0x01; GPIO_SetBits(SCL_GPIO_PORT, SCL_PIN); IIC_Delay(); } if(ack) IIC_Ack(); else IIC_NAck(); return byte; } void TMP102_Init(void) { IIC_Start(); IIC_WriteByte(0x90); IIC_WaitAck(); IIC_WriteByte(0x01); IIC_WaitAck(); IIC_Stop(); } float TMP102_ReadTemp(void) { uint16_t temp; float t; IIC_Start(); IIC_WriteByte(0x90); IIC_WaitAck(); IIC_WriteByte(0x00); IIC_WaitAck(); IIC_Start(); IIC_WriteByte(0x91); IIC_WaitAck(); temp = (IIC_ReadByte(1) << 8) | IIC_ReadByte(0); IIC_Stop(); t = temp * 0.0625; return t; } int main(void) { float temperature; RCC_DeInit(); SystemInit(); IIC_Init(); TMP102_Init(); while(1) { temperature = TMP102_ReadTemp(); // 处理温度数据 } } ``` 在本例中,使用GPIO模拟IIC总线,通过模拟SCL和SDA信号来实现与TMP102的通信。首先初始化GPIO口,然后定义IIC总线的各种操作函数。在主函数中初始化TMP102,并循环读取温度数据。需要注意的是,TMP102的温度数据为16位有符号数,需要经过转换才能得到实际温度值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值