ADS8681驱动

一、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;
      }
    }
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容