Job_SignsPads/STM32/Code/STM32F405/Application/drv_SGM58031.c
2025-04-22 10:29:37 +08:00

232 lines
4.9 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.

/*
* @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时发送ACKack=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;
}