122 lines
2.7 KiB
C
122 lines
2.7 KiB
C
/*************************************************
|
||
Copyright (c) 2025, 成都赛联科技有限责任公司
|
||
All rights reserved.
|
||
@file drv_i2c.C
|
||
@brief drv_i2c驱动程序
|
||
|
||
@details
|
||
@note
|
||
@author dufresne
|
||
@date 2025/09/24
|
||
|
||
@version v1.0 2025/09/24 初始版本
|
||
*************************************************/
|
||
|
||
#include "drv_i2c.h"
|
||
#include "rtthread.h"
|
||
#include <core_cm4.h>
|
||
|
||
/*
|
||
@ brief 延时函数
|
||
@ param
|
||
@ return
|
||
@ note 2025-09-15
|
||
*/
|
||
static void delay_us(int us)
|
||
{
|
||
rt_thread_udelay(us);
|
||
}
|
||
|
||
void i2c_init(void)
|
||
{
|
||
i2c_gpio_config();
|
||
i2c_config();
|
||
}
|
||
/*
|
||
@ brief 初始化tmp75芯片GPIO引脚
|
||
@ param
|
||
@ return
|
||
@ note 2025-09-15
|
||
*/
|
||
void i2c_gpio_config(void)
|
||
{
|
||
// 配置引脚时钟
|
||
rcu_periph_clock_enable(RCU_GPIOB);
|
||
|
||
gpio_af_set(GPIOB, GPIO_AF_4, I2C_SCL_PIN | I2C_SDA_PIN);
|
||
/* 初始化GPIO复用功能模式 */
|
||
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN | I2C_SDA_PIN);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN | I2C_SDA_PIN);
|
||
}
|
||
|
||
void i2c_config(void)
|
||
{
|
||
// 启用 I2C 外设的时钟
|
||
rcu_periph_clock_enable(RCU_I2C0);
|
||
|
||
// 配置 I2C 的时钟参数:
|
||
// I2C_PERIPH:这里使用的I2C1
|
||
// I2C_SPEED:通信速率(单位为 Hz,常用为 100000 或 400000),这里使用100000
|
||
i2c_clock_config(I2C_PERIPH, I2C_SPEED, I2C_DTCY_2);
|
||
|
||
// 配置 I2C 工作模式和地址:
|
||
// I2C_ADDFORMAT_7BITS:使用 7 位地址模式
|
||
// I2C_BUS_ADDRESS:SD2068器件代码0110010 = 0x32
|
||
i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_BUS_ADDRESS);
|
||
|
||
// 启用 I2C 外设
|
||
i2c_enable(I2C_PERIPH);
|
||
|
||
// 使能 ACK 应答功能,确保在接收数据后自动发送 ACK
|
||
i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
|
||
}
|
||
|
||
/*
|
||
@ brief 读取温度值
|
||
@ param
|
||
@ return
|
||
@ note 2025-09-15
|
||
*/
|
||
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);
|
||
}
|