/* * @Description 使用IIC1 驱动SGM58031 * @Version: 1.0 * @Autor: lzc * @Date: 2022-09-02 08:59:57 * @LastEditors: lzc * @LastEditTime: 2023-06-14 17:33:14 */ #include "main.h" #include "drv_SGM58031.h" #include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" /** * @function: IIC_Init * @brief IIC 初始化 * @return {*} * @author: lzc */ void IIC_Init(void) { IIC_SCL = 1; IIC_SDA = 1; } // 产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); // sda线输出 IIC_SDA = 1; IIC_SCL = 1; delay_us(4); IIC_SDA = 0; // START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL = 0; // 钳住I2C总线,准备发送或接收数据 } // 产生IIC停止信号 void IIC_Stop(void) { SDA_OUT(); // sda线输出 IIC_SCL = 0; IIC_SDA = 0; // STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL = 1; IIC_SDA = 1; // 发送I2C总线结束信号 delay_us(4); } // 等待应答信号到来 // 返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime = 0; SDA_IN(); // SDA设置为输入 IIC_SDA = 1; delay_us(1); IIC_SCL = 1; delay_us(1); while (READ_SDA) { ucErrTime++; if (ucErrTime > 250) { IIC_Stop(); return 1; } } IIC_SCL = 0; // 时钟输出0 return 0; } // 产生ACK应答 void IIC_Ack(void) { IIC_SCL = 0; SDA_OUT(); IIC_SDA = 0; delay_us(2); IIC_SCL = 1; delay_us(2); IIC_SCL = 0; } // 不产生ACK应答 void IIC_NAck(void) { IIC_SCL = 0; SDA_OUT(); IIC_SDA = 1; delay_us(2); IIC_SCL = 1; delay_us(2); IIC_SCL = 0; } // IIC发送一个字节 // 返回从机有无应答 // 1,有应答 // 0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL = 0; // 拉低时钟开始数据传输 for (t = 0; t < 8; t++) { IIC_SDA = (txd & 0x80) >> 7; txd <<= 1; delay_us(2); // 对TEA5767这三个延时都是必须的 IIC_SCL = 1; delay_us(2); IIC_SCL = 0; delay_us(2); } } // 读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i, receive = 0; SDA_IN(); // SDA设置为输入 for (i = 0; i < 8; i++) { IIC_SCL = 0; delay_us(2); IIC_SCL = 1; receive <<= 1; if (READ_SDA) receive++; delay_us(1); } if (!ack) IIC_NAck(); // 发送nACK else IIC_Ack(); // 发送ACK return receive; } /** * @function: SGM58031_WriteData * @brief 写数据 * @param {uint8_t} addr 寄存器地址 * @param {uint16_t} data 数据 * @param {uint8_t} device_addr 驱动地址 * @return {*} * @author: lzc */ void SGM58031_WriteData(uint8_t addr, uint16_t data, uint8_t device_addr) { IIC_Start(); IIC_Send_Byte(device_addr); // 发器件地址 IIC_Wait_Ack(); IIC_Send_Byte(addr); // 发送寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte((data >> 8) & 0xff); // 发送高位 IIC_Wait_Ack(); IIC_Send_Byte((data)&0xff); // 发送低位 IIC_Wait_Ack(); IIC_Stop(); // 产生一个停止条件 delay_us(2); } /** * @function: SGM58031_ReadData * @brief 读数据 * @param {uint8_t} addr 寄存器地址 * @param {uint8_t} device_addr 驱动地址 * @param {uint16_t} ByteNumToRead 读取字节数 * @return {*} * @author: lzc */ uint16_t SGM58031_ReadData(uint8_t addr, uint8_t device_addr, uint16_t ByteNumToRead) { uint16_t data; IIC_Start(); IIC_Send_Byte(device_addr); IIC_Wait_Ack(); IIC_Send_Byte(addr); // 发送地址 IIC_Wait_Ack(); IIC_Stop(); // 产生一个停止条件 IIC_Start(); IIC_Send_Byte(device_addr + 1); // 发器件地址 IIC_Wait_Ack(); if (ByteNumToRead == 1) // { data = IIC_Read_Byte(0); } else { data = IIC_Read_Byte(1); data = (data << 8) + IIC_Read_Byte(0); } IIC_Stop(); // 产生一个停止条件 return data; } /** * @function: SGM58031_WriteConfig * @brief 写配置 * @param {uint16_t} data * @return {*} * @author: lzc */ char SGM58031_WriteConfig(uint16_t data) { uint16_t ReadData = 0; SGM58031_WriteData(Config_Reg, data, 0x90); ReadData = SGM58031_ReadData(Config_Reg, 0x90, 2); if (ReadData != data) return 0; else return 1; } /** * @function: SGM58031_ReadADCValue * @brief 读取ADC值 * @param {} * @return {*} * @author: lzc */ uint16_t ReadDate_Record = 0; float SGM58031_ReadADCValue(void) { float ADC_Value = 0; uint16_t ReadData = 0; ReadData = SGM58031_ReadData(0x00, 0x90, 2); if (ReadData == 0xffff) ReadData = ReadDate_Record; else ReadDate_Record = ReadData; ADC_Value = (ReadData / 32768.0f) * 6.144f; return ADC_Value; }