20191101(33) 针对 RT-Thread 下 ADS1256 移植说明(SPI)

这是基于 RT-Thread 4.0.2 版本移植的 ADS1256 源码程序

注意: 自校准不太适合应用于压差较大环境,测试发现芯片会自动平衡差值无法很好的同时测试 5v和3.3v 两个电压,部分配置请查看数据手册

注意: RT-Thread 中 SPI 和 硬件中断 没法同时工作,因此采用轮询方式进行

以下是源码

//filePath: drv_ads1256.c
#include "drv_ads1256.h"
#include "drv_spi.h"

/*
注意: SPI 和 中断都使用了系统锁所以不能在中断中使用 SPI (除非使用 IO 模拟 SPI 才可以)
鉴于任务需求只要采集16次之后就可以停止工作,则改为轮询方式进行

注意: ADS1256 自带自动校准可能导致检测到的电压被均值,也就是高的被拉低,低的被拉高以便值接近
*/

/*
	ADS1256基本特性:
	1、模拟部分供电5V;
	2、SPI数字接口电平:3.3V
	3、PGA设置范围: 1、2、4、8、16、32、64、
	4、参考电压2.5V (推荐缺省的,外置的)
	5、输入电压范围:PGA = 1 时, 可输入正负5V
	6. 自动校准 (当设置了PGA,BUF使能、数据采样率时,会启动自校准)
	7. 输入的缓冲器可设置启用和关闭(一般选启用)


	外部晶振频率 = 7.68MHz,
		时钟频率 tCLK = 1/7.68M = 0.13uS
		输出数据周期 tDATA =  1 / 30K = 0.033mS  (按30Ksps计算)

	对SPI的时钟速度要求: (ads1256.pdf page 6)
		最快 4个tCLK = 0.52uS
		最慢 10个tDATA = 0.3mS (按 30Ksps 计算)

		SCL高电平和低电平持续时间最小 200ns

	RREG, WREG, RDATA 命令之后,需要延迟 4 * tCLK = 0.52uS;
	RDATAC, RESET, SYNC 命令之后,需要延迟 24 * tCLK = 3.12uS;

	实际测试,在3.3V上电后, 及时不做任何配置,ADS125的DRDY 口线即开始输出脉冲信号(2.6us高,33.4低,频率30KHz)
*/

/*
	调试记录
	(1) 设置寄存器时,SCK过快导致芯片不能每次都收到数据。原因: 发送的相邻的字节之间需要延迟一小段时间.
	(2) 连续复位CPU时,偶尔出现芯片输出采样率异常。
*/

#define SPI_BUS_NAME "spi1"
#define SPI_ADS1256_DEVICE_NAME "spi10"
#define SPI_CS0      		GPIO_PIN_4 //PA4 CS0
#define SPI_CS0_GPIO 		GPIOA 

#define SPI_SYNC0    		GET_PIN(A, 8) //PA8 SYNC0
#define SPI_DRDY0    		GET_PIN(C, 4) //PC4 DRDY0
#define SPI_RST0     		GET_PIN(C, 5)  //PC5 RST0

/* 4194303 = 2.5V , 这是理论值,实际可以根据2.5V基准的实际值进行公式矫正 */
//校准方法: 数字电源 2.5V, 开启自校准, 取当前采集到 2.5V 的值
#define AD_2_5V_MASKVALUE 4194303

static struct rt_spi_device *spi_dev_ads1256;
ADS1256_VAR_T g_tADS1256;

/************** 声明区 declared section ************/

//读寄存器值
static rt_uint8_t rt_hw_ads1256_readReg(rt_uint8_t _RegID);
//写寄存器值
static void rt_hw_ads1256_setReg(rt_uint8_t _RegID, rt_uint8_t _RegValue);
//写单字节命令
static void rt_hw_ads1256_writeCmd(const rt_uint8_t _cmd);
//设置差分通道采集
static void rt_hw_ads1256_setDiffChannel(rt_uint8_t _ch);
//设置单通道采集
static void rt_hw_ads1256_setChannel(rt_uint8_t _ch);
//读取 ADC 数据
static rt_int32_t rt_hw_ads1256_readData(void);
//由外部中断调用的 ADC 采集程序
static void rt_hw_ads1256_getISRValue(void);
//读取 DRDY 引脚电平 低电平有效 1 表示转换完成 0 表示需要等待
static rt_uint8_t rt_hw_ads1256_readDRDY(void);


//复位时缺省值
static const uint8_t s_tabDataRate[ADS1256_DRATE_MAX] =
{
	0xF0,0xE0,0xD0,0xC0,0xB0,0xA1,
	0x92,0x82,0x72,0x63,0x53,0x43,
	0x33,0x20,0x13,0x03
};

/******************* 函数区 Function Section*******/

/* 中断回调函数 */
rt_uint8_t readStatus = 0;
void beep_on(void *args)
{
		readStatus = 1;    
}
/*
@brief: IO 引脚初始化
*/
static void rt_hw_ads1256_gpio(void) {
	rt_pin_mode(SPI_SYNC0, PIN_MODE_OUTPUT);
	rt_pin_mode(SPI_RST0, PIN_MODE_OUTPUT);
	rt_pin_mode(SPI_CS0, PIN_MODE_OUTPUT);
	rt_pin_mode(SPI_DRDY0, PIN_MODE_INPUT);

	rt_pin_write(SPI_SYNC0, PIN_HIGH);
	rt_pin_write(SPI_RST0, PIN_HIGH);
	rt_pin_write(SPI_CS0, PIN_HIGH);

	rt_pin_attach_irq(SPI_DRDY0, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
}

/*
@brief: ADS1256 设备初始化
*/
static int rt_hw_ads1256_init(void) 
{
	rt_err_t res;
	//挂载设备
	__HAL_RCC_GPIOA_CLK_ENABLE();
	res = rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_ADS1256_DEVICE_NAME, SPI_CS0_GPIO, SPI_CS0); //挂载到 SPI 总线
	if (RT_EOK != res) {
		return -RT_ERROR;
	}
	//查找设备
	spi_dev_ads1256 = (struct rt_spi_device *)rt_device_find(SPI_ADS1256_DEVICE_NAME);

	//配置设备
	{
		struct rt_spi_configuration cfg;
		cfg.data_width = 8;
		cfg.mode = RT_SPI_MASTER | RT_SPI_MSB | RT_SPI_MODE_1;//RT_SPI_READY
		cfg.max_hz = 1920 * 1000; //1.92 M
		
		rt_spi_configure(spi_dev_ads1256, &cfg);
	}
	//GPIO 引脚初始化
	rt_hw_ads1256_gpio();

	return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_ads1256_init);

/*
@brief: 获取 DRDY 引脚状态
@return: 1 OK 完成; 0 need wait 等待
*/
static rt_uint8_t rt_hw_ads1256_readDRDY(void) {
	if (rt_pin_read(SPI_DRDY0) == PIN_HIGH) {
		return 0;
	} else {
		return 1;
	}
}
/*
@brief: 读一个寄存器值
@param: _RegID :寄存器 ID
@return: 寄存器值
*/
static rt_uint8_t rt_hw_ads1256_readReg(rt_uint8_t _RegID) {
	rt_uint8_t read = 0;
	rt_uint8_t sendCmd[] = {CMD_RREG | _RegID, 0x00};
	
	//发送数据后接收数据
	rt_spi_send_then_recv(spi_dev_ads1256, sendCmd, 2, &read, 1);

	return read;
}

/*
@brief: 写一个寄存器值
@param: _RegID: 寄存器ID
@param: _RegValue: 设定值
*/
static void rt_hw_ads1256_setReg(rt_uint8_t _RegID, rt_uint8_t _RegValue) {
	rt_uint8_t sendCmd[] = {CMD_WREG | _RegID, 0x00, _RegValue};
	
	rt_spi_send(spi_dev_ads1256, sendCmd, 3);
}

/*
@brief: 写一个单节命令
@param: _cmd: 命令(8bit)
*/
static void rt_hw_ads1256_writeCmd(const rt_uint8_t _cmd) {
	rt_spi_send(spi_dev_ads1256, &_cmd, 1);
}

/*
@brief: 读取 ADC 采集数据
@return: 采集的数据 (24 bit)
*/
static rt_int32_t rt_hw_ads1256_readData(void) {
	rt_uint8_t cmd = CMD_RDATA;
	rt_uint8_t value[3] = {0};
	rt_uint32_t read = 0;
		
	//发送数据后接收数据
	rt_spi_send_then_recv(spi_dev_ads1256, &cmd, 1, value, 3);
	read = value[0] << 16;
	read += value[1] << 8;
	read += value[2];
	/* 负数进行扩展。24位有符号数扩展为32位有符号数 */
	if (read & 0x800000){
		read += 0xFF000000; //0xff 是负数的意思
	}
	
	return (rt_int32_t) read;
}



/*
@brief: 配置 ADC 模式
@param: _gain: 增益
@param: _drate: 采样速率
@param: _ucScanMode: 模式 (0 单端扫描 8路, 1 差分扫描 4 路)
@process:
 1 启动输入缓存;不开启自校准功能;优先高位传输模式 MSB
*/
void rt_hw_ads1256_configADC(ADS1256_GAIN_E _gain, \
													ADS1256_DRATE_E _drate, \
													rt_uint8_t _ucScanMode) {
		
	rt_uint8_t data = 0x00;														
	/* 状态寄存器定义
	Bits 7-4 ID3, ID2, ID1, ID0  Factory Programmed Identification Bits (Read Only)

	Bit 3 ORDER: Data Output Bit Order
		0 = Most Significant Bit First (default)
		1 = Least Significant Bit First
	Input data  is always shifted in most significant byte and bit first. Output data is always shifted out most significant
	byte first. The ORDER bit only controls the bit order of the output data within the byte.

	Bit 2 ACAL : Auto-Calibration
		0 = Auto-Calibration Disabled (default)
		1 = Auto-Calibration Enabled
	When Auto-Calibration is enabled, self-calibration begins at the completion of the WREG command that changes
	the PGA (bits 0-2 of ADCON register), DR (bits 7-0 in the DRATE register) or BUFEN (bit 1 in the STATUS register)
	values.

	Bit 1 BUFEN: Analog Input Buffer Enable
		0 = Buffer Disabled (default)
		1 = Buffer Enabled

	Bit 0 DRDY :  Data Ready (Read Only)
		This bit duplicates the state of the DRDY pin.

	ACAL=1使能自校准功能。当 PGA,BUFEEN, DRATE改变时会启动自校准
*/
//开启自校准前提就是电压相近,不然会出自动平衡4.8v与3.3v同时测试,4.8v被稳到 3.3附近
	data = 0x01;
	rt_hw_ads1256_setReg(REG_STATUS, data);

	data = 0x08;	/* 高四位0表示AINP接 AIN0,  低四位8表示 AINN 固定接 AINCOM */
	rt_hw_ads1256_setReg(REG_MUX, data);
/*	ADCON: A/D Control Register (Address 02h)
	Bit 7 Reserved, always 0 (Read Only)
	Bits 6-5 CLK1, CLK0 : D0/CLKOUT Clock Out Rate Setting
		00 = Clock Out OFF
		01 = Clock Out Frequency = fCLKIN (default)
		10 = Clock Out Frequency = fCLKIN/2
		11 = Clock Out Frequency = fCLKIN/4
		When not using CLKOUT, it is recommended that it be turned off. These bits can only be reset using the RESET pin.

	Bits 4-2 SDCS1, SCDS0: Sensor Detect Current Sources
		00 = Sensor Detect OFF (default)
		01 = Sensor Detect Current = 0.5 μ A
		10 = Sensor Detect Current = 2 μ A
		11 = Sensor Detect Current = 10μ A
		The Sensor Detect Current Sources can be activated to verify  the integrity of an external sensor supplying a signal to the
		ADS1255/6. A shorted sensor produces a very small signal while an open-circuit sensor produces a very large signal.

	Bits 2-0 PGA2, PGA1, PGA0: Programmable Gain Amplifier Setting
		000 = 1 (default)
		001 = 2
		010 = 4
		011 = 8
		100 = 16
		101 = 32
		110 = 64
		111 = 64
*/
	data = 0x00 | _gain;
	rt_hw_ads1256_setReg(REG_ADCON, data);
	/* 因为切换通道和读数据耗时 123uS, 因此扫描中断模式工作时,最大速率 = DRATE_1000SPS */
	data = s_tabDataRate[_drate];	/* 选择数据输出速率 */
	rt_hw_ads1256_setReg(REG_DRATE, data);
	
	{ //配置结构体
		g_tADS1256.Gain = _gain;
		g_tADS1256.DataRate = _drate;
		g_tADS1256.ScanMode = _ucScanMode;
	}
	//清空缓存区
	{
		for (char i = 0; i < 8; ++i) {
				g_tADS1256.AdcNow[i] = 0;
		}
	}
}

/*
@brief: 获取芯片 ID
@return: 只有 ID = 0x30 才能认为硬件连接及工作正常
RT_EOK :   the result is ok;
-RT_ERROR: the result is error;
*/
rt_err_t rt_hw_ads1256_readChipID(void) {
	rt_uint8_t id = 0; //正常情况应该返回 0x3 代表读取成功
	
	id = rt_hw_ads1256_readReg(REG_STATUS); 
	if (0x30 == id) {
		return RT_EOK;
	}
	
	return -RT_ERROR;
}	

/*
@brief: 从缓冲区读取 ADC 采样结果
@param: _ch: 通道号(0-7)
@return: 采样结果
*/
rt_int32_t rt_hw_ads1256_getAdcVaule(rt_uint8_t _ch) {
	rt_int32_t iTemp = 0;
	if (_ch > 7) {
		return 0;
	}
	
	iTemp = g_tADS1256.AdcNow[_ch];
	
	return iTemp;
}

/*
@brief: ADS1256 设置通道号 (AIN- 固定接地(ACOM))
@param: _ch: 通道号(0-7)
*/
static void rt_hw_ads1256_setChannel(rt_uint8_t _ch) {
		/*
	Bits 7-4 PSEL3, PSEL2, PSEL1, PSEL0: Positive Input Channel (AINP) Select
		0000 = AIN0 (default)
		0001 = AIN1
		0010 = AIN2 (ADS1256 only)
		0011 = AIN3 (ADS1256 only)
		0100 = AIN4 (ADS1256 only)
		0101 = AIN5 (ADS1256 only)
		0110 = AIN6 (ADS1256 only)
		0111 = AIN7 (ADS1256 only)
		1xxx = AINCOM (when PSEL3 = 1, PSEL2, PSEL1, PSEL0 are “don’t care”)

		NOTE: When using an ADS1255 make sure to only select the available inputs.

	Bits 3-0 NSEL3, NSEL2, NSEL1, NSEL0: Negative Input Channel (AINN)Select
		0000 = AIN0
		0001 = AIN1 (default)
		0010 = AIN2 (ADS1256 only)
		0011 = AIN3 (ADS1256 only)
		0100 = AIN4 (ADS1256 only)
		0101 = AIN5 (ADS1256 only)
		0110 = AIN6 (ADS1256 only)
		0111 = AIN7 (ADS1256 only)
		1xxx = AINCOM (when NSEL3 = 1, NSEL2, NSEL1, NSEL0 are “don’t care”)
	*/

	if (_ch > 7) {
		return;
	}
	/* Bit3 = 1, AINN 固定接 AINCOM */
	rt_hw_ads1256_setReg(REG_MUX, (_ch << 4) | (1 << 3));
}

/*
@brief: 配置差分多路复用
@param: _ch: 通道号(0-3)
*/
static void rt_hw_ads1256_setDiffChannel(rt_uint8_t _ch) {
		/*
	Bits 7-4 PSEL3, PSEL2, PSEL1, PSEL0: Positive Input Channel (AINP) Select
		0000 = AIN0 (default)
		0001 = AIN1
		0010 = AIN2 (ADS1256 only)
		0011 = AIN3 (ADS1256 only)
		0100 = AIN4 (ADS1256 only)
		0101 = AIN5 (ADS1256 only)
		0110 = AIN6 (ADS1256 only)
		0111 = AIN7 (ADS1256 only)
		1xxx = AINCOM (when PSEL3 = 1, PSEL2, PSEL1, PSEL0 are “don’t care”)

		NOTE: When using an ADS1255 make sure to only select the available inputs.

	Bits 3-0 NSEL3, NSEL2, NSEL1, NSEL0: Negative Input Channel (AINN)Select
		0000 = AIN0
		0001 = AIN1 (default)
		0010 = AIN2 (ADS1256 only)
		0011 = AIN3 (ADS1256 only)
		0100 = AIN4 (ADS1256 only)
		0101 = AIN5 (ADS1256 only)
		0110 = AIN6 (ADS1256 only)
		0111 = AIN7 (ADS1256 only)
		1xxx = AINCOM (when NSEL3 = 1, NSEL2, NSEL1, NSEL0 are “don’t care”)
	*/
	switch (_ch) {
		case 0:/* 差分输入 AIN0, AIN1 */
			rt_hw_ads1256_setReg(REG_MUX, (0 << 4) | 1); break;
		case 1:/* 差分输入 AIN2, AIN3 */
			rt_hw_ads1256_setReg(REG_MUX, (2 << 4) | 3); break;
		case 2:/* 差分输入 AIN4, AIN5 */
			rt_hw_ads1256_setReg(REG_MUX, (4 << 4) | 5); break;
		case 3:/* 差分输入 AIN6, AIN7 */
			rt_hw_ads1256_setReg(REG_MUX, (6 << 4) | 7); break;
	}
}

/*
@brief: 8路单端采集执行程序
*/
static void rt_hw_ads1256_single8Gather(void) {
	/* 读取采集结构,保存在全局变量 */
	rt_hw_ads1256_setChannel(g_tADS1256.Channel);	/* 切换模拟通道 */
	rt_hw_ads1256_writeCmd(CMD_SYNC);
	rt_hw_ads1256_writeCmd(CMD_WAKEUP);

	if (g_tADS1256.Channel == 0) {
		/* 注意保存的是上一个通道的数据 */
		g_tADS1256.AdcNow[7] = rt_hw_ads1256_readData();	
	} else {
		/* 注意保存的是上一个通道的数据 */
		g_tADS1256.AdcNow[g_tADS1256.Channel-1] = rt_hw_ads1256_readData();	
	}

	if (++g_tADS1256.Channel >= 8) {
		g_tADS1256.Channel = 0;
	}
}

/*
@brief: 4路差分采集执行程序
*/
static void rt_hw_ads1256_diff4Gather(void) {
		/* 读取采集结构,保存在全局变量 */
	rt_hw_ads1256_setDiffChannel(g_tADS1256.Channel);	/* 切换模拟通道 */
	rt_hw_ads1256_writeCmd(CMD_SYNC);
	rt_hw_ads1256_writeCmd(CMD_WAKEUP);
	
	if (g_tADS1256.Channel == 0) {
		/* 注意保存的是上一个通道的数据 */
		g_tADS1256.AdcNow[3] = rt_hw_ads1256_readData();		
	} else {
		/* 注意保存的是上一个通道的数据 */
		g_tADS1256.AdcNow[g_tADS1256.Channel-1] = rt_hw_ads1256_readData();	
	}

	if (++g_tADS1256.Channel >= 4) {
		g_tADS1256.Channel = 0;
	}
}

/*
@brief: 由中断函数启动 AD 采集程序
*/
static void rt_hw_ads1256_getISRValue(void) {
	if (0 == g_tADS1256.ScanMode) {//单端 8 路采集
		rt_hw_ads1256_single8Gather();
	} else {
		rt_hw_ads1256_diff4Gather();
	}
}

/*
@brief: ADC 转换
*/
void rt_hw_ads1256_transitionValue(rt_int32_t volt[], rt_int32_t adc[]) {
	for (rt_uint8_t i = 0; i < 8; i++)
	{
		/* 从全局缓冲区读取采样结果。 采样结果是在中断服务程序中读取的。*/
		adc[i] = rt_hw_ads1256_getAdcVaule(i);

		/* 4194303 = 2.5V , 这是理论值,实际可以根据2.5V基准的实际值进行公式矫正 */
		volt[i] = ((rt_int64_t)adc[i] * 2500000) / AD_2_5V_MASKVALUE;	/* 计算实际电压值(近似估算的),如需准确,请进行校准 */
	}
}

/******************测试用例***************************/
/*
@brief: 用来测试 AD1256 测试是否成功
@process: PGA增益 = 1, 数据输出速率 = 15sps, 扫描 8 路
*/
static void test_ads1256_setTest(void) {
	rt_uint8_t value = 0; 
	//设置参数
	rt_hw_ads1256_configADC(ADS1256_GAIN_1, ADS1256_30000SPS, 0);

	// 单独测试
	rt_thread_mdelay(500);	
	// 左值等于右值
	rt_kprintf( " If the left value equals the right value, \
								the setting is successful \n");
	
	value = rt_hw_ads1256_readReg(REG_STATUS); 
	rt_kprintf(" read ADS1256 ID: %x == 36? \n", value);
	
	value = rt_hw_ads1256_readReg(REG_MUX); 
	rt_kprintf(" read ADS1256 ID: %x == 8? \n", value);

	value = rt_hw_ads1256_readReg(REG_ADCON); 
	rt_kprintf(" read ADS1256 ID: %x == %x? \n", value, ADS1256_GAIN_1);

	value = rt_hw_ads1256_readReg(REG_DRATE); 
	rt_kprintf(" read ADS1256 ID: %x == f0? \n", value);
}
MSH_CMD_EXPORT(test_ads1256_setTest, spi ads1256 sample);

/*
@brief: 获取芯片 ID
@return: 只有 ID = 0x30 才能认为硬件连接及工作正常
*/
static void test_ads1256_readChipID(void) {
	rt_uint8_t id = 0; //正常情况应该返回 0x3 代表读取成功
	
	id = rt_hw_ads1256_readReg(REG_STATUS); 

	rt_kprintf(" read ADS1256 ID: %x \n", id);
	if (0x30 == id) {
		rt_kprintf(" ADS1256 device work OK! \n");
	} else {
		rt_kprintf(" ADS1256 device start fail! \n");
	}
}	
MSH_CMD_EXPORT(test_ads1256_readChipID, spi ads1256 sample);

/* 
@brief: 采集 AD 值测试程序
*/
static void test_ads1256_getValue(void) {
	rt_int32_t adc[8];
	rt_int32_t volt[8];
	rt_int32_t iTemp;

	for (rt_uint8_t i = 0; i < 8; i++) {
		rt_pin_irq_enable(SPI_DRDY0, PIN_IRQ_ENABLE);
		while(!readStatus);
		rt_pin_irq_enable(SPI_DRDY0, PIN_IRQ_DISABLE);
		readStatus = 0;
		rt_hw_ads1256_getISRValue();
	}

	rt_hw_ads1256_transitionValue(volt, adc);
	for (rt_uint8_t i = 0; i < 8; i++) {
		iTemp = volt[i];	/* 余数,uV  */
		if (iTemp < 0) {
			iTemp--;
			rt_kprintf("%d=%6d,(-%d.%03d %03d V) \r\n", i, adc[i], iTemp /1000000, (iTemp%1000000)/1000, iTemp%1000);
		} else {
			rt_kprintf("%d=%6d,( %d.%03d %03d V) \r\n", i, adc[i], iTemp/1000000, (iTemp%1000000)/1000, iTemp%1000);
		}
	}
}
MSH_CMD_EXPORT(test_ads1256_getValue, spi ads1256 sample);

//filePath: drv_ads1256.h
#ifndef __DRV_ADS1256_H
#define __DRV_ADS1256_H

#include "board.h"
/* 寄存器定义: Table 23. Register Map --- ADS1256数据手册第30页 */
enum
{
	/* 寄存器地址, 后面是复位后缺省值 */
	REG_STATUS = 0,	// x1H
	REG_MUX    = 1, // 01H
	REG_ADCON  = 2, // 20H
	REG_DRATE  = 3, // F0H
	REG_IO     = 4, // E0H
	REG_OFC0   = 5, // xxH
	REG_OFC1   = 6, // xxH
	REG_OFC2   = 7, // xxH
	REG_FSC0   = 8, // xxH
	REG_FSC1   = 9, // xxH
	REG_FSC2   = 10, // xxH
};

/* 命令定义: TTable 24. Command Definitions --- ADS1256数据手册第34页 */
enum
{
	CMD_WAKEUP  = 0x00,	// Completes SYNC and Exits Standby Mode 0000  0000 (00h)
	CMD_RDATA   = 0x01, // Read Data 0000  0001 (01h)
	CMD_RDATAC  = 0x03, // Read Data Continuously 0000   0011 (03h)
	CMD_SDATAC  = 0x0F, // Stop Read Data Continuously 0000   1111 (0Fh)
	CMD_RREG    = 0x10, // Read from REG rrr 0001 rrrr (1xh)
	CMD_WREG    = 0x50, // Write to REG rrr 0101 rrrr (5xh)
	CMD_SELFCAL = 0xF0, // Offset and Gain Self-Calibration 1111    0000 (F0h)
	CMD_SELFOCAL= 0xF1, // Offset Self-Calibration 1111    0001 (F1h)
	CMD_SELFGCAL= 0xF2, // Gain Self-Calibration 1111    0010 (F2h)
	CMD_SYSOCAL = 0xF3, // System Offset Calibration 1111   0011 (F3h)
	CMD_SYSGCAL = 0xF4, // System Gain Calibration 1111    0100 (F4h)
	CMD_SYNC    = 0xFC, // Synchronize the A/D Conversion 1111   1100 (FCh)
	CMD_STANDBY = 0xFD, // Begin Standby Mode 1111   1101 (FDh)
	CMD_RESET   = 0xFE, // Reset to Power-Up Values 1111   1110 (FEh)
};

/* 增益选项 */
typedef enum
{
	ADS1256_GAIN_1			= (0),	/* 增益1(缺省) */
	ADS1256_GAIN_2			= (1),	/* 增益2 */
	ADS1256_GAIN_4			= (2),	/* 增益4 */
	ADS1256_GAIN_8			= (3),	/* 增益8 */
	ADS1256_GAIN_16			= (4),	/* 增益16 */
	ADS1256_GAIN_32			= (5),	/* 增益32 */
	ADS1256_GAIN_64			= (6),	/* 增益64 */
}ADS1256_GAIN_E;

/* 采样速率选项 */
/* 数据转换率选择
	11110000 = 30,000SPS (default)
	11100000 = 15,000SPS
	11010000 = 7,500SPS
	11000000 = 3,750SPS
	10110000 = 2,000SPS
	10100001 = 1,000SPS
	10010010 = 500SPS
	10000010 = 100SPS
	01110010 = 60SPS
	01100011 = 50SPS
	01010011 = 30SPS
	01000011 = 25SPS
	00110011 = 15SPS
	00100011 = 10SPS
	00010011 = 5SPS
	00000011 = 2.5SPS
*/
typedef enum
{
	ADS1256_30000SPS = 0,
	ADS1256_15000SPS,
	ADS1256_7500SPS,
	ADS1256_3750SPS,
	ADS1256_2000SPS,
	ADS1256_1000SPS,
	ADS1256_500SPS,
	ADS1256_100SPS,
	ADS1256_60SPS,
	ADS1256_50SPS,
	ADS1256_30SPS,
	ADS1256_25SPS,
	ADS1256_15SPS,
	ADS1256_10SPS,
	ADS1256_5SPS,
	ADS1256_2d5SPS,

	ADS1256_DRATE_MAX
}ADS1256_DRATE_E;

#define ADS1256_DRAE_COUNT = 15;

typedef struct
{
	ADS1256_GAIN_E Gain;		/* 增益 */
	ADS1256_DRATE_E DataRate;	/* 数据输出速率 */
	int32_t AdcNow[8];		/* 8路ADC采集结果(实时)有符号数 */
	uint8_t Channel;			/* 当前通道 */
	uint8_t ScanMode;			/* 扫描模式,0表示单端8路, 1表示差分4路 */
}ADS1256_VAR_T;
//配置 ADS1256 
void rt_hw_ads1256_configADC(ADS1256_GAIN_E _gain, \
														ADS1256_DRATE_E _drate, \
														rt_uint8_t _ucScanMode);

#endif


发布了120 篇原创文章 · 获赞 27 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_24890953/article/details/102844819