1.概述
本文主要介绍了基于GD32F407和Rtthread编写的SGM58031驱动程序,使用两路模拟I2C通信扩展4个SGM58031芯片实现16路AD采样。
2.ENV程序编写
在board文件里找到Kconfig文件并打开,menu "Onboard Peripheral Drivers"内添加如下代码:
menuconfig BSP_USING_SGM58031
bool "Enable SGM58031"
default n
select BSP_USING_I2C
if BSP_USING_SGM58031
config BSP_USING_SGM58031_0
bool "Using SGM58031_0"
default y
if BSP_USING_SGM58031_0
config SGM58031_BUS_NAME0
string "sgm58031_0 bus name"
default "si2c0"
config SGM58031_DEVICE_NAME0
string "sgm58031_0 device name"
default "s58031_0"
endif
config BSP_USING_SGM58031_1
bool "Using SGM58031_1"
default y
if BSP_USING_SGM58031_1
config SGM58031_BUS_NAME1
string "sgm58031_1 bus name"
default "si2c0"
config SGM58031_DEVICE_NAME1
string "sgm58031_1 device name"
default "s58031_1"
endif
config BSP_USING_SGM58031_2
bool "Using SGM58031_2"
default y
if BSP_USING_SGM58031_2
config SGM58031_BUS_NAME2
string "sgm58031_2 bus name"
default "si2c1"
config SGM58031_DEVICE_NAME2
string "sgm58031_2 device name"
default "s58031_2"
endif
config BSP_USING_SGM58031_3
bool "Using SGM58031_3"
default n
if BSP_USING_SGM58031_3
config SGM58031_BUS_NAME3
string "sgm58031_3 bus name"
default "si2c1"
config SGM58031_DEVICE_NAME3
string "sgm58031_3 device name"
default "s58031_3"
endif
endif
3.ENV配置
1打开ENV
2使能SGM58031
3选择要配置的SGM58031,填写通信接口和设备名称
4配置完成后rtconfig.h中就自动定义了, 如下所示。
#define BSP_USING_SGM58031
#define BSP_USING_SGM58031_0
#define SGM58031_BUS_NAME0 "si2c0"
#define SGM58031_DEVICE_NAME0 "s58031_0"
#define BSP_USING_SGM58031_1
#define SGM58031_BUS_NAME1 "si2c0"
#define SGM58031_DEVICE_NAME1 "s58031_1"
#define BSP_USING_SGM58031_2
#define SGM58031_BUS_NAME2 "si2c1"
#define SGM58031_DEVICE_NAME2 "s58031_2"
#define BSP_USING_SGM58031_3
#define SGM58031_BUS_NAME3 "si2c1"
#define SGM58031_DEVICE_NAME3 "s58031_3"
4.SGM58031驱动的头文件drv_sgm58031.h
#ifndef __DRV_SGM58031_H__
#define __DRV_SGM58031_H__
#include <rtdevice.h>
#define SGM58031_ADDR_GND 0x48 //ADDR接地,芯片1地址
#define SGM58031_ADDR_VDD 0x49 //ADDR接VDD,芯片2地址
#define SGM58031_ADDR_SDA 0x4A //ADDR接SDA
#define SGM58031_ADDR_SCL 0x4B //ADDR接SCL
#define SGM58031_Config_ADDR 0x01 //配置寄存器地址
#define SGM58031_Conversion_ADDR 0x00 //转换数据寄存器地址
#define SGM58031_Single_A0_ADDR 0x44E3 //单端连续转换模式A0通道1倍增益900Hz C3XX=单次 42XX=连续转换 XXE3=900Hz XX83=100Hz
#define SGM58031_Single_A1_ADDR 0x54E3 //单端连续转换模式A1通道1倍增益900Hz D3XX=单次 52XX=连续转换
#define SGM58031_Single_A2_ADDR 0x64E3 //单端连续转换模式A2通道1倍增益900Hz E3XX=单次 62XX=连续转换
#define SGM58031_Single_A3_ADDR 0x74E3 //单端连续转换模式A3通道1倍增益900Hz F3XX=单次 72XX=连续转换
/** sgm58031设备结构体 */
struct sgm58031_device
{
struct rt_device parent;
struct rt_i2c_bus_device *bus;
};
/** sgm58031设备用户操作配置结构图 */
struct sgm58031_config
{
rt_uint16_t addr; //设备地址 SGM58031_ADDR
rt_uint16_t flags; //I2C操作标志
const char *bus_name;
const char *dev_name;
};
#ifdef BSP_USING_SGM58031_0
#define SGM58031_0_DEVICE_CONFIG \
{ \
.addr = SGM58031_ADDR_GND, \
.flags = 0, \
.bus_name = SGM58031_BUS_NAME0, \
.dev_name = SGM58031_DEVICE_NAME0, \
}
#endif
#ifdef BSP_USING_SGM58031_1
#define SGM58031_1_DEVICE_CONFIG \
{ \
.addr = SGM58031_ADDR_VDD, \
.flags = 0, \
.bus_name = SGM58031_BUS_NAME1, \
.dev_name = SGM58031_DEVICE_NAME1, \
}
#endif
#ifdef BSP_USING_SGM58031_2
#define SGM58031_2_DEVICE_CONFIG \
{ \
.addr = SGM58031_ADDR_GND, \
.flags = 0, \
.bus_name = SGM58031_BUS_NAME2, \
.dev_name = SGM58031_DEVICE_NAME2, \
}
#endif
#ifdef BSP_USING_SGM58031_3
#define SGM58031_3_DEVICE_CONFIG \
{ \
.addr = SGM58031_ADDR_VDD, \
.flags = 0, \
.bus_name = SGM58031_BUS_NAME3, \
.dev_name = SGM58031_DEVICE_NAME3, \
}
#endif
extern rt_err_t sgm58031_register(rt_int8_t number,const char *device_name, const char *i2c_bus, void *user_data);
#endif
5.SGM58031驱动代码drv_sgm58031.c
代码可以从文章绑定的资源下载。
6.使用方法
编写两个函数用于配置通道和取值。
#ifdef BSP_USING_SGM58031
static void SGM58031_Set_Channel(rt_device_t dev,unsigned char channel)//配置采集通道开启转换
{
rt_uint16_t config;
if(channel==0)//
{
config= SGM58031_Single_A0_ADDR;
}
else if(channel==1)//
{
config= SGM58031_Single_A1_ADDR;
}
else if(channel==2)//
{
config= SGM58031_Single_A2_ADDR;
}
else if(channel==3)//
{
config= SGM58031_Single_A3_ADDR;
}
rt_device_write(dev,SGM58031_Config_ADDR,&config,2);//切换通道
}
rt_uint16_t SGM58031_Read (rt_device_t dev)// 读取采集值
{
rt_uint8_t buffer[2]={0};
rt_uint16_t data=0;
rt_device_read(dev,SGM58031_Conversion_ADDR,&buffer,2);//读数据
data = (buffer[0]<<8)+buffer[1];
return data;
}
#endif
初始化函数
static int init_ADC(void)
{
rt_thread_t s_th1 = RT_NULL;
#ifdef BSP_USING_SGM58031_0
/*打开sgm58031_0*/
sgm58031_0 = rt_device_find(SGM58031_DEVICE_NAME0);
if (sgm58031_0 == RT_NULL)
{
rt_kprintf("can't find %s device!\n", SGM58031_DEVICE_NAME0);
return RT_ERROR ;
}
else
{
rt_device_open(sgm58031_0, RT_DEVICE_FLAG_RDWR);
}
#endif
/*打开sgm58031_1*/
#ifdef BSP_USING_SGM58031_1
sgm58031_1 = rt_device_find(SGM58031_DEVICE_NAME1);
if (sgm58031_1 == RT_NULL)
{
rt_kprintf("can't find %s device!\n", SGM58031_DEVICE_NAME1);
return RT_ERROR ;
}
else
{
rt_device_open(sgm58031_1, RT_DEVICE_FLAG_RDWR);
}
#endif
/*打开sgm58031_2*/
#ifdef BSP_USING_SGM58031_2
sgm58031_2 = rt_device_find(SGM58031_DEVICE_NAME2);
if (sgm58031_2 == RT_NULL)
{
rt_kprintf("can't find %s device!\n", SGM58031_DEVICE_NAME2);
return RT_ERROR ;
}
else
{
rt_device_open(sgm58031_2, RT_DEVICE_FLAG_RDWR);
}
#endif
/*打开sgm58031_3*/
#ifdef BSP_USING_SGM58031_3
sgm58031_3 = rt_device_find(SGM58031_DEVICE_NAME3);
if (sgm58031_3 == RT_NULL)
{
rt_kprintf("can't find %s device!\n", SGM58031_DEVICE_NAME3);
return RT_ERROR ;
}
else
{
rt_device_open(sgm58031_3, RT_DEVICE_FLAG_RDWR);
}
#endif
}INIT_APP_EXPORT(init_ADC);
7.问题
目前测试没有发现问题。可能还存在不完善的地方,如果遇到什么问题可以给我留言。