一、ADS8681介绍
ADS8681 16 位 SAR 模数转换器 (ADC) 是一款基于 16 位逐次逼近(SAR)模数转换器的集成式数据采集系统。 该器件的工作吞吐量达 1MSPS。 该器件具有高精度 SAR ADC、集成模拟前端 (AFE) 输入驱动器电路、过压保护电路(高达 ±20 V)。该器件还包括温度漂移超低的片上 4.096V 基准。 ADS8681 由 5V 单电源供电运行,支持真正的双极输入范围(±12.288V、±6.144V、±10.24V、±5.12V 和 ±2.56V)。此 ADC 还支持单极输入范围(0V 至 12.288V、0V 至 10.24V、0V 至 6.144V 以及 0V 至 5.12V)。AFE 电路的增益误差和偏移误差均可在指定的数值范围内精确调整,从而确保高直流精度。
(1)16位;
(2)转换速度:1Msps
(3)片上基准:4.096V
(4)单双极性输入和范围可选择
二、ADS8681通讯硬件配置
我这边使用标准SPI通讯,RVS和RESET也接到主控制器上。CPOL=0,CPHASE = 0。
所以对应主控的SPI配置也是CPOL=0,CPHASE = 0。
//ADS8681
void spi1_config(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_SPI1);
/*
---SPI1---
PB12 AF-SPI1_NSS
PB13 AF-SPI1_SCK
PB14 AF-SPI1_MISO
PB15 AF-SPI1_MOSI
PD9 AF-SPI1_NSS2
PD8 C_RST
PD10 C_RVS
PB11 V_RST
PB10 V_RVS
*/
/*
NSS2:V采集,NSS:C采集
*/
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, GPIO_PIN_12);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_mode_set(GPIOB, GPIO_MODE_AF,GPIO_PUPD_NONE, GPIO_PIN_14);
gpio_af_set(GPIOB,GPIO_AF_5,GPIO_PIN_14);
gpio_mode_set(GPIOB, GPIO_MODE_AF,GPIO_PUPD_NONE, GPIO_PIN_13);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
gpio_af_set(GPIOB,GPIO_AF_5,GPIO_PIN_13);
gpio_mode_set(GPIOB, GPIO_MODE_AF,GPIO_PUPD_NONE, GPIO_PIN_15);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
gpio_af_set(GPIOB,GPIO_AF_5,GPIO_PIN_15);
gpio_mode_set(GPIOD, GPIO_MODE_INPUT,GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
gpio_bit_set(GPIOD,GPIO_PIN_8);
gpio_mode_set(GPIOB, GPIO_MODE_INPUT,GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, GPIO_PIN_11);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
gpio_bit_set(GPIOB,GPIO_PIN_11);
spi_parameter_struct spi_init_struct;
spi_i2s_deinit(SPI1);
spi_struct_para_init(&spi_init_struct);
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_16; // 30M/16 = 1.875MHz 30M/8 = 3.75M
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI1,&spi_init_struct);
spi_i2s_interrupt_enable(SPI1,SPI_I2S_INT_RBNE);
spi_enable(SPI1);
nvic_irq_enable(SPI1_IRQn,1,1);
}
三、ADS8681驱动文件
3.1、ADS8681.h
#ifndef ADS_8681_H
#define ADS_8681_H
#include "head_conf.h"
#define AD_V_RVS gpio_input_bit_get(GPIOB,GPIO_PIN_10)
#define AD_V_RST gpio_output_bit_get(GPIOB,GPIO_PIN_11)
#define AD_V_RST_H gpio_bit_set(GPIOB,GPIO_PIN_11)
#define AD_V_RST_L gpio_bit_reset(GPIOB,GPIO_PIN_11)
#define AD_V_CS_H gpio_bit_set(GPIOD,GPIO_PIN_9)
#define AD_V_CS_L gpio_bit_reset(GPIOD,GPIO_PIN_9)
/**
* ADS8681 Configuration Registers
*/
#define DEVICE_ID_REG 0X00
#define RST_PWRCTL_REG 0X04
#define SDI_CTL_REG 0X08
#define SDO_CTL_REG 0X0C
#define DATAOUT_CTL_REG 0X10
#define RANGE_SEL_REG 0x14
#define ALARM_REG 0x20
#define ALARM_H_TH_REG 0X24
#define ALARM_L_TH_REG 0X28
/**
* ADS8681 List of Input Commands
*/
#define ADS8681_WRITE 0xD0 // 写寄存器
#define ADS8681_READ 0xC8 // 读寄存器
#define ADS8681_SET_CLK 0xD0080001; // CPOL =0 , CPHASE =1 设置协议中的相位和时钟极性。操作08h寄存器
#define ADS8681_SET_RANGE 0xD0140004; // +-0.625*Vref 设置输入电压范围。操作14h寄存器
#define ADS8681_DATA_READ 0x00000000; // 读取数据
void ADS_8681_Send(Int8U count, Int8U *buf);
void ADS_8681_Read(Int8U count,Int8U *buf);
void ADS8681_Write_Register(Int8U Addr,Int16U data);
Int16U ADS8681_Read_Register(Int8U Addr);
void ADS8681_Init(void);
void ADS8681_Read_ConversionData(void);
#endif
3.2、ADS8681.c
#include "ads8681.h"
Int8U ADS_GET_FLAG = 0;
/**
* ADS8681发送1个字节
*/
void ADS_8681_Send(Int8U count, Int8U *buf)
{
Int8U i;
Int8U value = 0;
AD_V_CS_H;
while(!AD_V_RVS);
AD_V_CS_L;
for(i = count; i > 0; i--)
{
value = *(buf + i - 1);
spi_i2s_data_transmit(SPI1, value);
while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_TBE));
}
AD_V_CS_H;
}
/**
* ADS8681读取
*/
void ADS_8681_Read(Int8U count,Int8U *buf)
{
Int8U i;
Int8U receive = 0;
AD_V_CS_H;
while(!AD_V_RVS);
AD_V_CS_L;
for(i = count; i > 0; i--)
{
while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_RBNE));
receive = spi_i2s_data_receive(SPI1);
*(buf + i - 1)= receive;
}
AD_V_CS_H;
}
/**
* 写寄存器
*/
void ADS8681_Write_Register(Int8U Addr,Int16U data) // 11010_00_<9-bit address>_<16-bit data>
{
Int8U buf[4];
buf[3] = 0xD0;
buf[2] = Addr;
buf[1] = (data>>8)&0xff;
buf[0] = data&0xff;
ADS_8681_Send(4,buf);
}
/**
* 读寄存器
*/
Int16U ADS8681_Read_Register(Int8U Addr) // 11001_xx_<9-bit address>_00000000_00000000
{
Int8U data[2];
Int8U buf[4];
buf[3] = 0xC8;
buf[2] = Addr;
buf[1] = 0x00;
buf[0] = 0x00;
ADS_8681_Send(4,buf);
return data[1]<<8 | data[0];
}
/**
* ADS8681初始化
*/
void ADS8681_Init(void)
{
AD_V_CS_L;
AD_V_RST_L;
delay_1us(2000000);
AD_V_RST_H;
ADS8681_Write_Register(SDI_CTL_REG,0x0000); // CPOL = 0 and CPHASE = 0
ADS8681_Write_Register(RANGE_SEL_REG,0x000B); // 1.25 * Vref
}
/**
* 读取ADS8681采样值
*/
void ADS8681_Read_ConversionData(void)
{
Int8U buf[2];
buf[1] = 0;
buf[0] = 0;
ADS_GET_FLAG = 1;
ADS_8681_Send(2,buf);
}
四、ADS8681调用
spi1_config(); // ADS8681
ADS8681_Init();
...
while(1)
{
if(!ADS_GET_FLAG)
{
ADS8681_Read_ConversionData();
arr_vol_source[array_vol_s_cnt] = (Int32U)AD8681_VAL; // 原始码值
}
}
...
/**
* SPI1中断,ADS8681数据读取
*/
void SPI1_IRQHandler(void)
{
Int8U receive = 0;
if(SET == spi_i2s_interrupt_flag_get(SPI1,SPI_I2S_INT_FLAG_RBNE))
{
receive = spi_i2s_data_receive(SPI1);
if(ADS_GET_FLAG)
{
if(!data_cnt)
{
data_cnt ++;
data1 = receive;
}else
{
data_cnt = 0;
data2 = receive;
AD8681_VAL = (Int32U)(data1 << 8 | data2);
ADS_GET_FLAG = 0;
}
}
}
}