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