1、SGM58031芯片详解
(1)SGM58031是一款低功耗,16位精度,delta-sigma (ΔΣ)模数转换器(ADC)。它从3V到5.5V供电。
(2)SGM58031包含一个片上参考和振荡器。它有一个I2C兼容接口,可以选择四个I2C从地址。
(3)SGM58031有两种工作模式:单次发射模式和连续转换模式。
在单次触发模式下,ADC执行一次转换并给出完整的固定数据,无需丢弃任何数据。一旦ADC完成转换,它就会进入低功率关闭模式。
在连续模式中,ADC在先前的转换完成后自动开始新的转换。给出了每一个转换结果。数据速率等于配置的数据速率。
(4)SGM58031的引脚说明
(5)参考电压
2、SGM58031工程代码编写
iic.c
#include "iic.h"
#define I2C1_SLAVE_ADDRESS7 0x90
void i2c_config(void)
{
/* enable GPIOB clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* enable I2C1 clock */
rcu_periph_clock_enable(RCU_I2C1);
rcu_periph_clock_enable(RCU_AF);
/* connect PB10 to I2C1_SCL */
/* connect PB11 to I2C1_SDA */
gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);
i2c_clock_config(I2C1, 100000, I2C_DTCY_2);
i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7);
i2c_enable(I2C1);
i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}
/* I2C写函数 */
void i2c_write(uint8_t reg_addr, uint16_t send_data)
{
uint8_t high_val=0x00;
uint8_t low_val=0x00;
low_val = send_data&0x00ff;
high_val = (send_data>>8)&0x00ff;
//写开始时序
/* wait until i2c bus is idle */
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
/* send a start condition to I2C bus */
i2c_start_on_bus(I2C1);
/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
/* send slave address to I2C bus */
//写从机地址时序
i2c_master_addressing(I2C1, I2C1_SLAVE_ADDRESS7, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
/* clear ADDSEND bit */
i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
/* wait until the transmit data buffer is empty */
while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
//写寄存器地址时序
i2c_data_transmit(I2C1, reg_addr);
/* wait until the TBE bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
//写 写入数据 时序
/* data transmission */
i2c_data_transmit(I2C1, high_val);//先发送高8位数据
/* wait until the TBE bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
i2c_data_transmit(I2C1, low_val);//再发送低8位数据
/* wait until the TBE bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
//写停止时序
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C1);
/* wait until stop condition generate */
while(I2C_CTL0(I2C1)&0x0200);
}
/* I2C读函数 */
uint16_t i2c_read_byte(uint8_t reg_addr)
{
uint8_t high_val=0x00;
uint8_t low_val=0x00;
uint16_t recv_val = 0x0000;
//写开始时序
/* wait until i2c bus is idle */
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
/* send a start condition to I2C bus */
i2c_start_on_bus(I2C1);
/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
//写 从机地址+写 时序
/* send slave address to I2C bus */
i2c_master_addressing(I2C1, I2C1_SLAVE_ADDRESS7, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
/* clear ADDSEND bit */
i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
/* wait until the transmit data buffer is empty */
while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
//写 读寄存器地址 时序
i2c_data_transmit(I2C1, reg_addr);
/* wait until the BTC bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
//写停止时序
i2c_stop_on_bus(I2C1);
while(I2C_CTL0(I2C1)&0x0200);
//写开始时序
i2c_start_on_bus(I2C1);
/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
//写 从机地址+读 时序
/* send slave address to I2C bus */
i2c_master_addressing(I2C1, I2C1_SLAVE_ADDRESS7, I2C_RECEIVER);
/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
/* clear the ADDSEND bit */
i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
/* wait until the RBNE bit is set and clear it*/
while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE));
//接收数据 时序
high_val = i2c_data_receive(I2C1);
while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE));
i2c_ack_config(I2C1, I2C_ACK_DISABLE);
i2c_ackpos_config(I2C1,I2C_ACKPOS_NEXT);
low_val = i2c_data_receive(I2C1);
/* wait until the BTC bit is set */
//while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));代码卡死,屏蔽后不卡死,可以成功读取数据
//写停止时序
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C1);
/* wait until stop condition generate */
while(I2C_CTL0(I2C1)&0x0200);
recv_val = (high_val<<8)|low_val;
i2c_ack_config(I2C1, I2C_ACK_ENABLE);
return recv_val;
}
iic.h
#ifndef __IIC_H
#define __IIC_H
#include "gd32f30x.h"
#include "string.h"
void i2c_config(void);
void i2c_write(uint8_t reg_addr, uint16_t send_data);
uint16_t i2c_read_byte(uint8_t reg_addr);
#endif
main.c
// 使能 RDY输出功能
i2c_write(0x03,0x8000); // Write 0x8000 to Hi_Thresh
i2c_write(0x02,0x0000); // Write 0x0000 to Lo_Thresh
// 配置ADC输入, 启动连续转换模式
i2c_write(0x01,0xC4e0);//Write config, OS=1, AIN0 to GND, G=2(+/-2.048V input range),
//continuous mode conversion, DR=800, others default
//COMP_QUE = 00
Vbat = i2c_read_byte(0x00);//读取电压值
//转换 Vbat/65535*参考电压(比如4.096V)