AD7327 AD转换芯片使用心得

最近项目调试使用到了AD7327芯片,为了防止后续忘记又得各种查资料,将自己这次调试的心得记录于此,如果错误请指正。谢谢。

开发环境:STM32F407VET6+AD7327     keil mdk 5.23

这款芯片有官方例程,代码开发起来省事儿好多。

 

1.芯片简介

  -12位精度

 - 支持软件选择量程:±10V、±5V、±2.5V,0-10V

  -500ksps传输速率

  -8个模拟量输入通道,既可配置为单个输入,也可配置为双路输入(传感器信号包含V+、V-两根信号线情况下)

  -内置2.5V参考电压

AD7327 AD转换芯片使用心得_第1张图片

AD7327 AD转换芯片使用心得_第2张图片

注意!!!设计硬件时请先参考芯片手册Table 6,注意根据你要使用的量程选择相应的电压。如果采集电压含有正负,则电源也需要接正负电源;如果只需要0-10V,则只需要接电源正和地。

此处可能导致后期程序配置好了寄存器,确定了量程,结果发现输入电压没到最大量程还差好远,结果已经到了fff最大值了,莫名其妙的,设计时需要注意!

AD7327 AD转换芯片使用心得_第3张图片

 

 

2.引脚简介

  AD7327 AD转换芯片使用心得_第4张图片AD7327 AD转换芯片使用心得_第5张图片

  AD7327 AD转换芯片使用心得_第6张图片

     硬件接线按照上图所示即可,注意以下几点:

 -1.  1脚CS  片选。接mcu一个IO口即可;初始化芯片及数据转换读取时需要对该引脚输出高低电平

 -2.  2脚DIN  SPI通讯数据引脚,我使用STM32做主机控制AD7327芯片,因此,DIN脚接mcu的SPI_MOSI

 -3.  18脚.DOUT  SPI通讯数据引脚,DOUT脚接mcu的SPI_MISO

 -4.  20脚SCLK  SPI时钟,接SPI_SCK

 -5. 17脚VDRIVE 接mcu的IO口,初始化后拉高即可。注意该引脚必须和VCC电压相同,最大也不能超过VCC+0.3V。我是用的   stm32f4芯片,因此VCC就是用的3.3V,所以该引脚直接接到stm32的一个IO口即可。

  PS.注意硬件电路上的电容方向,我的板子上有个电容方向画反了,结果上电一个劲儿的发热。建议画板时一定要仔细,参考官方模板电路,焊好后通电没有发现什么问题也要摸一摸芯片和各个元器件看是不是有短路或者接错导致的发热现象出现

 

3.硬件电路

AD7327 AD转换芯片使用心得_第7张图片

    注意vin0-vin7,引脚号并不是按照顺序来的,我之前引脚号弄错了,还花了一番功夫,结果发现原理图上引脚号跟芯片文档对不上,还好电源引脚没有错误,不至于烧掉元器件。

 

4.寄存器简介

  AD7327 AD转换芯片使用心得_第8张图片

AD7327包含4个寄存器,通过SPI发送一个16位的值来读写AD7237.

16位命令中,最高位第15位为写入命令,1有效

                      第14位与第13位用来选择对相应寄存器进行写入操作

 

4.1 控制寄存器

AD7327 AD转换芯片使用心得_第9张图片

  控制寄存器注意以下几点:

  1.coding  即为AD值的类型,0则输出补码,1则输出二进制原码

  2.ref   电压参考。0则开启外部参考,不使用内部参考;1则使用内部参考作为AD输出值的参考

  3.第12-10位,ADD2-ADD0地址选择,如下图所示。我需要8个独立输入通道,因此我配置ADD2-ADD0:111   mode1 = 0,mode0 = 0

AD7327 AD转换芯片使用心得_第10张图片

  4.  Table11中电源模式选择中两个参数所示,00即为正常模式

AD7327 AD转换芯片使用心得_第11张图片

5.sequence选择   我使用8个独立输入通道模式,并且开启sequence模式,即自动按照VIN0-VIN7顺序读取采集值并传输到总线,因此写入seq1=1,seq2=0即可

  若要读取指定通道采集值,则写入seq1=0,seq2=1即可

AD7327 AD转换芯片使用心得_第12张图片

AD7327 AD转换芯片使用心得_第13张图片

 

4.2  序列寄存器

AD7327 AD转换芯片使用心得_第14张图片

  选择相应输入采集通道值,输出到总线。我使用了8个通道,因此全选即可,VIN0-VN7全为1即可。

 

4.3  量程寄存器

  AD7327 AD转换芯片使用心得_第15张图片

  通过设置VinxA与VinxB,来配置相应通道的输入量程,我使用的8个通道均为±10V,因此配置为00即可。

 

5.数据输出

AD7327 AD转换芯片使用心得_第16张图片

  通过向SPI总线写入0x00来读取AD值,返回的16位数据中,第15-13位为当前12位采集值的地址值,第12位为正负标志,若采用补码方式,采集到负电压,则该位为1.

  具体ADD2-ADD0对应哪个通道,可以在上述4.1控制寄存器中table10中找到

 

6.代码

  官方例程中已经配置好各个寄存器地址,在ad7327.h文件中

  6.1 sequence模式

  初始化

#define AD_AUTO 1 //默认使用sequence模式,若想单独读取,改成0即可

uint8_t AD7327Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	
  SPI1_Init();//SPI1初始化
  SPI1_SetSpeed(SPI_BaudRatePrescaler_256);//spi速率选择
		
  //PA4 Vdrive/PC4 CS 引脚初始化
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
		
  AD_Vdrive_1;//Vdrive拉高
  AD_CS_HIGH;//片选拉高,禁止AD读取,带配置完寄存器后拉低
  delayms(20);
			
  //量程选择
  WriteToRangeRegister1 (IN10vCH0, IN10vCH1, IN10vCH2, IN10vCH3);
  delayms(20);
  WriteToRangeRegister2 (IN10vCH4, IN10vCH5, IN10vCH6, IN10vCH7);
  delayms(20);
	
  #if AD_AUTO //使用自动sequence模式,则初始化以下代码,否则无需执行
              //我使用了8个通道,因此VIN0-VIN7全部要初始化
  WriteToSequenceRegister (VIN0|VIN1|VIN2|VIN3|VIN4|VIN5|VIN6|VIN7);
  delayms(20);
  WriteToControlRegister(CH0|CH1|CH2|CH3|CH4|CH5|CH6|CH7, Mode0, Normal,                  
                         StraightBinary, Ref_En, Sequencer);
  delayms(20);
  #endif 
	
  return 0;
}


void SPI1_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    GPIO_PinAFConfig(GPIOA , GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA , GPIO_PinSource6, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA , GPIO_PinSource7, GPIO_AF_SPI1);
	
    //GPIOA 5 6 7
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);
	
    //SPI_I2S_DeInit(SPI1);
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//空闲状态高电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//时钟第一个跳边沿数据被采样
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;	
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;	
    SPI_Init(SPI1, &SPI_InitStructure); 
    SPI_Cmd(SPI1, ENABLE);

}

 使用sequence模式,配置完成后,系统则会按照VIN0-VIN7的顺序采集转换并送出

假如只需要读取某几个通道的数据,则初始化后选择相应通道即可。

SPI读写

uint16_t SPI1_ReadWriteByte(uint16_t TxData)
{
        uint16_t returnData;

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
	AD_CS_LOW;//拉低cs
	SPI_I2S_SendData(SPI1, TxData); //发送命令
		
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}  
        returnData = SPI_I2S_ReceiveData(SPI1);//读取SPI数据
        AD_CS_HIGH;//拉高cs
	    
        return returnData;//返回SPI读取到的值
}

读取AD值函数

uint16_t ReadSequence (void)
{
	uint16_t DataToWrite = 0x00;
	uint16_t ReturnData = 0x00;
		
	DataToWrite = 0x0000;
	
	ReturnData = SPI1_ReadWriteByte (DataToWrite);
	
	return ReturnData;	
}

写入00命令,芯片便会按照之前的设置返回采集值

注意返回值第15-13位为通道值,第12位为正负标志

 

6.2  读取指定通道

static uint16_t ReadCHx(uint16_t VINx, uint16_t CHx)
{
	uint16_t value;
	uint8_t i;
	double sum = 0;
	
	WriteToSequenceRegister (VINx);//读取VINx通道的值
	delayms(10);
	WriteToControlRegister(CHx, Mode0, Normal, StraightBinary, Ref_En, Sequencer);
	delayms(10);
	for(i = 0; i < N; i ++)//采集N次
	{
		ADValue_Original[i] = (ReadSequence() & 0X0FFF);//读取值后12位放入数组
		sum += ADValue_Original[i];//N次值相加求和
	}
	value = (uint16_t) (sum / N);//取平均值
	
	return value;
}

VINx与CHx为相同通道值。就是你想读通道1,就把x写1,读通道2,就把x改成2

你可能感兴趣的:(AD芯片,AD7327)