232 lines
4.9 KiB
C
232 lines
4.9 KiB
C
/*
|
||
* @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;
|
||
} |