newPtz/drivers/drv_i2c.c

122 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************
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_ADDRESSSD2068器件代码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);
}