///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); }