275 lines
4.5 KiB
C
275 lines
4.5 KiB
C
///Copyright (c) 2022, 四川汇源光通信有限公司
|
||
///All rights reserved.
|
||
///@file tmp75.C
|
||
///@brief tmp75驱动程序
|
||
///
|
||
///@details
|
||
///@note
|
||
///@author lqc
|
||
///@date 2022/05/23
|
||
///
|
||
///@version v1.0 2022/05/23 初始版本
|
||
|
||
#include "tmp75.h"
|
||
|
||
/*
|
||
@ brief 延时函数
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-23
|
||
*/
|
||
static void delay_us(int us)
|
||
{
|
||
for(int i = 0; i < us; i++ )
|
||
{
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
}
|
||
}
|
||
|
||
/*
|
||
@ brief 初始化tmp75芯片GPIO引脚
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-23 lqc
|
||
*/
|
||
void temp75_gpio_init()
|
||
{
|
||
//配置引脚时钟
|
||
rcu_periph_clock_enable(RCU_GPIOB);
|
||
//设置引脚为输出模式:PB6
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
|
||
|
||
//设置引脚PB7输出模式
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
|
||
TMP75_SCL_HIGH;
|
||
TMP75_SDA_HIGH;
|
||
}
|
||
|
||
/*
|
||
@ brief 设置SDA引脚为输出模式
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-25 lqc
|
||
*/
|
||
static void tmp75_sda_output()
|
||
{
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
}
|
||
|
||
/*
|
||
@ brief 设置SDA引脚为输入模式
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-25 lqc
|
||
*/
|
||
static void tmp75_sda_input()
|
||
{
|
||
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
// gpio_output_options_set(GPIOB, GPIO_PUPD_NONE, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
}
|
||
|
||
/*
|
||
@ brief I2C start信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-25
|
||
*/
|
||
static void i2c_start()
|
||
{
|
||
TMP75_SDA_HIGH;
|
||
TMP75_SCL_HIGH;
|
||
TMP75_SDA_LOW;
|
||
delay_us(40);
|
||
}
|
||
|
||
/*
|
||
@ brief I2C stop信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-25
|
||
*/
|
||
static void i2c_stop()
|
||
{
|
||
TMP75_SDA_LOW;
|
||
TMP75_SCL_HIGH;
|
||
TMP75_SDA_HIGH;
|
||
}
|
||
|
||
/*
|
||
@ brief 写一个字节数据
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-25
|
||
*/
|
||
static void tmp75_write_byte(uint8_t byte)
|
||
{
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
TMP75_SCL_LOW;
|
||
delay_us(4);
|
||
if(byte & 0x80)
|
||
{
|
||
TMP75_SDA_HIGH;
|
||
}else{
|
||
TMP75_SDA_LOW;
|
||
}
|
||
byte <<= 1;
|
||
TMP75_SCL_HIGH;
|
||
delay_us(40);
|
||
}
|
||
TMP75_SCL_LOW;
|
||
}
|
||
|
||
/*
|
||
@ brief 写入数据后,CPU接收TMP75返回的ACK信号
|
||
@ param
|
||
@ return
|
||
@ note
|
||
*/
|
||
static void tmp75_ack()
|
||
{
|
||
int i = 0;
|
||
//将sda设置为输入模式
|
||
tmp75_sda_input();
|
||
TMP75_SCL_HIGH;
|
||
while((TMP75_SDA_GET) && (i < 1000))
|
||
{
|
||
i++;
|
||
}
|
||
TMP75_SCL_LOW;
|
||
//将sda设置为输出模式
|
||
tmp75_sda_output();
|
||
}
|
||
|
||
/*
|
||
@ brief 读取数据
|
||
@ param
|
||
@ return value:读取到的单字节数据
|
||
@ note 2022-05-25
|
||
*/
|
||
static uint8_t tmp75_read_byte()
|
||
{
|
||
uint8_t value = 0;
|
||
tmp75_sda_input();
|
||
TMP75_SCL_LOW;
|
||
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
TMP75_SCL_HIGH;
|
||
value <<= 1;
|
||
delay_us(10);
|
||
if(TMP75_SDA_GET)
|
||
{
|
||
value = value | 0x01;
|
||
}
|
||
TMP75_SCL_LOW;
|
||
delay_us(10);
|
||
}
|
||
tmp75_sda_output();
|
||
return value;
|
||
}
|
||
|
||
/*
|
||
@ brief 读取数据,主机发送ack信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-25
|
||
*/
|
||
static void master_ack()
|
||
{
|
||
TMP75_SDA_LOW;
|
||
delay_us(5);
|
||
TMP75_SCL_HIGH;
|
||
delay_us(5);
|
||
TMP75_SCL_LOW;
|
||
delay_us(5);
|
||
}
|
||
|
||
/*
|
||
@ brief 读取数据完成,主机发送noack信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static void master_noack()
|
||
{
|
||
TMP75_SDA_HIGH;
|
||
delay_us(5);
|
||
TMP75_SCL_HIGH;
|
||
delay_us(5);
|
||
TMP75_SCL_LOW;
|
||
delay_us(5);
|
||
}
|
||
/*
|
||
@ brief 读取温度值
|
||
@ param
|
||
@ return
|
||
@note 2022-05-25
|
||
*/
|
||
float tmp75_read_temp(void)
|
||
{
|
||
uint8_t tempH = 0;
|
||
uint8_t tempL = 0;
|
||
uint16_t tempCode = 0;
|
||
float temp = 0;
|
||
|
||
//起始信号
|
||
i2c_start();
|
||
//写tmp75地址
|
||
tmp75_write_byte(TMP75_ADDRESS);
|
||
//接收tmp75的ack信息
|
||
tmp75_ack();
|
||
//发送需读取数据的地址
|
||
tmp75_write_byte(TEMP_REGISTER_ADDRESS);
|
||
tmp75_ack();
|
||
|
||
i2c_start();
|
||
//写tmp75地址
|
||
tmp75_write_byte(TMP75_ADDRESS + 1); //读地址数据
|
||
tmp75_ack();
|
||
tempH = tmp75_read_byte();
|
||
master_ack();
|
||
tempL = tmp75_read_byte();
|
||
master_noack();
|
||
i2c_stop();
|
||
tempCode = (tempH << 8) | tempL;
|
||
tempCode = tempCode >> 6;
|
||
if(tempCode & 0x200) //负温度
|
||
{
|
||
tempCode &= 0x1ff;
|
||
temp = ((float)tempCode -512) / 4;
|
||
}
|
||
else
|
||
{
|
||
temp = (float)tempCode / 4;
|
||
}
|
||
TMP75_SDA_LOW;
|
||
TMP75_SCL_LOW;
|
||
return (temp);
|
||
}
|
||
|
||
|