清风烈酒 发表于 2018-1-29 17:00

LTC1867芯片单极模式只能采样0~2V

本帖最后由 清风烈酒 于 2018-1-30 12:58 编辑

在stm32f107基础上使用LTC1867芯片采样,设置单极性后只能采样要0~2V的电压,基准为4V。请大神帮忙!!!!


#define         ADC_CS_H                                        GPIO_SetBits(GPIOA,GPIO_Pin_4);
#define         ADC_CS_L                                        GPIO_ResetBits(GPIOA,GPIO_Pin_4);

#define         ADC_SCK_H                                        GPIO_SetBits(GPIOA,GPIO_Pin_5);
#define         ADC_SCK_L                                        GPIO_ResetBits(GPIOA,GPIO_Pin_5);

//#define         ADC_MISO                      GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)
#define         ADC_MISO                      GPIOA->IDR&(1<<6)


#define         ADC_MOSI_H                              GPIO_SetBits(GPIOA,GPIO_Pin_7);
#define         ADC_MOSI_L                              GPIO_ResetBits(GPIOA,GPIO_Pin_7);

#define         Instructions_LTC1867_CH0                                                0x80
#define         Instructions_LTC1867_CH1                                          0xC0
#define         Instructions_LTC1867_CH2                                                 0x90
#define          Instructions_LTC1867_CH3                                                 0xD0
#define         Instructions_LTC1867_CH4                                                0xA0
#define         Instructions_LTC1867_CH5                                          0xE0
#define         Instructions_LTC1867_CH6                                                 0xB0
#define          Instructions_LTC1867_CH7                                                 0xF0
                                                               
#define         LTC1867_SLEEP_MODE                                                                         0x02
#define         LTC1867_EXIT_SLEEP_MODE                                                 0x00
#define         LTC1867_UNIPOLAR_MODE                                                         0x04
#define         LTC1867_BIPOLAR_MODE                                                               0x00


/******************************************

*功能:SPI初始化

*******************************************/
void SPI_GPIO_Init(void)
{
                GPIO_InitTypeDef GPIO_InitStructure;
               
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);      
      
                //----------------------GPIO----------------------
                // Configure SPI pins: CS
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_Init(GPIOA, &GPIO_InitStructure);
               

                // Configure SPI pins: SCK
                GPIO_InitStructure.GPIO_Pin = 0;
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                GPIO_Init(GPIOA, &GPIO_InitStructure);

                // Configure SPI pins: MISO
                GPIO_InitStructure.GPIO_Pin = 0;
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
                GPIO_Init(GPIOA, &GPIO_InitStructure);

                // Configure _SPI pins: MOSI
                GPIO_InitStructure.GPIO_Pin = 0;
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                GPIO_Init(GPIOA, &GPIO_InitStructure);

                //设置为空闲状态
          ADC_CS_H;
          ADC_SCK_H;

}



/************************************************

*功能: LTC1867ACGN选择1~8通道

*************************************************/
u8 LTC1867ACGN_SetChnl(u8 chnl)
{
                u8 cmd;                              
                switch(chnl)
                {
                              case 1:
                                        cmd = Instructions_LTC1867_CH0|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 2:
                                        cmd = Instructions_LTC1867_CH1|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 3:
                                        cmd = Instructions_LTC1867_CH2|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 4:
                                        cmd = Instructions_LTC1867_CH3|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 5:
                                        cmd = Instructions_LTC1867_CH4|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 6:
                                        cmd = Instructions_LTC1867_CH5|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 7:
                                        cmd = Instructions_LTC1867_CH6|LTC1867_UNIPOLAR_MODE;break;
                              
                              case 8:
                                        cmd = Instructions_LTC1867_CH7|LTC1867_UNIPOLAR_MODE;break;

                              default:
                                        cmd = Instructions_LTC1867_CH0|LTC1867_UNIPOLAR_MODE;break;
                }
                return cmd;
}

/**********************************

*功能: SPI读写数据,给定通道选择参数

***********************************/
u16 SPI_WriteRead(u8 chnl)
{
                u8 i = 0;
                u16 dat = 0;
                u8 cmd = 0;
                cmd = LTC1867ACGN_SetChnl(chnl);
                ADC_CS_L;
                delay_5us(10);                                        //50
                for(i=0;i<7;i++)
                {
                              if(cmd&(0x80))
                              {
                                                ADC_MOSI_H;
                              }else{
                                                ADC_MOSI_L;
                              }
                              cmd <<= 1;
                              ADC_SCK_L;
                              delay_5us(1);                        //5
                              ADC_SCK_H;
                              delay_5us(1);                        //5
                }
                ADC_CS_H;
                delay_5us(2);                                        //10
                ADC_CS_L;
                for(i=0;i<16;i++)
                {
                              ADC_SCK_L;
                              delay_5us(1);                        //2
                              if(ADC_MISO) dat |= 1;
                              dat <<= 1;
                              ADC_SCK_H;
                              delay_5us(1);                        //2
                }
                ADC_CS_H;
               
                return dat;
}

littleshrimp 发表于 2018-1-29 18:07

使用的外部4.069基准吗?

清风烈酒 发表于 2018-1-30 09:33

littleshrimp 发表于 2018-1-29 18:07
使用的外部4.069基准吗?

使用的内部基准,我用万用表测了REFCOMP引脚有4.07V的电压

littleshrimp 发表于 2018-1-30 10:05

清风烈酒 发表于 2018-1-30 09:33
使用的内部基准,我用万用表测了REFCOMP引脚有4.07V的电压

看你的情况像是单端模式没有设置成功,差分模式下会出现你说的这种情况,你再检查一下设置看看

清风烈酒 发表于 2018-1-30 10:21

littleshrimp 发表于 2018-1-30 10:05
看你的情况像是单端模式没有设置成功,差分模式下会出现你说的这种情况,你再检查一下设置看看


上表我用的是下面8行的配置,上面八行是差分输入吧。
我这边实际电压0V对应采集值0V,实际电压2V对应采集值为2V,2.01V开始就变成了0V,实际电压4V对应的采集值是1.996V。

清风烈酒 发表于 2018-1-30 10:25

麻烦大神解析,感激不尽:)

littleshrimp 发表于 2018-1-30 10:54

<div class='shownolgin' data-isdigest='no'>清风烈酒 发表于 2018-1-30 10:21
上表我用的是下面8行的配置,上面八行是差分输入吧。
我这边实际电压0V对应采集值0V,

你看一下0V,2V,4V对应的ADC CODE分别是多少
再参照一下官方的转换函数看下是不是计算的时候出了问题?
/*!
LTC1867: 16-Bit 8-Channel 200ksps ADC
 
@verbatim
 
The LTC1863/LTC1867 are pin-compatible, 8-channel 12-/16-bit A/D converters with
serial I/O, and an internal reference. The ADCs typically draw only 1.3mA from a
single 5V supply. The 8-channel input multiplexer can be configured for either
single-ended or differential inputs and unipolar or bipolar conversions (or
combinations thereof). The automatic nap and sleep modes benefit power sensitive
applications.
 
The LTC1867's DC performance is outstanding with a +/-2LSB INL specification and
no missing codes over temperature. The signal-to-noise ratio (SNR) for the
LTC1867 is typically 89dB, with the internal reference.
 
@endverbatim
 
http://www.linear.com/product/LTC1867
 
http://www.linear.com/product/LTC1867#demoboards
 
REVISION HISTORY
$Revision: 2026 $
$Date: 2013-10-14 13:52:48 -0700 (Mon, 14 Oct 2013) $
 
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
 
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
 
//! @defgroup LTC1867 LTC1867: 16-Bit 8-Channel 200ksps ADC
 
/*! @file
    @ingroup LTC1867
    Library for LTC1867: 16-Bit 8-Channel 200ksps ADC
*/
 
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include "LTC1867.h"
#include <SPI.h>
 
 
// Reads the ADC  and returns 16-bit data
void LTC1867_read(uint8_t cs, uint8_t adc_command, uint16_t *adc_code)
{
  spi_transfer_word(cs, (uint16_t)(adc_command<<8), adc_code);
}
 
// Calculates the LTC1867 input's unipolar voltage given the binary data and lsb weight.
float LTC1867_unipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_unipolar_code)
{
  float adc_voltage;
  adc_voltage=((float)(adc_code+LTC1867_offset_unipolar_code))*LTC1867_lsb;   //! 1) Calculate voltage from ADC code, lsb, offset.
  return(adc_voltage);
}
 
// Calculates the LTC1867 input's bipolar voltage given the two's compliment data and lsb weight
float LTC1867_bipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_bipolar_code)
{
  float adc_voltage, sign = 1.0;
  if (adc_code>>15)
  {
    adc_code = (adc_code ^ 0xFFFF)+1;                                           //! 1) Convert ADC code from two's complement to binary
    sign = -1;
  }
  adc_voltage=((float)(adc_code+LTC1867_offset_bipolar_code))*LTC1867_lsb*sign; //! 2) Calculate voltage from ADC code, lsb, offset.
  return(adc_voltage);
}
 
// Calibrate the lsb
void LTC1867_cal_voltage(uint16_t zero_unipolar_code, uint16_t zero_bipolar_code, uint16_t fs_code, float zero_voltage, float fs_voltage, float *LTC1867_lsb, int32_t *LTC1867_offset_unipolar_code, int32_t *LTC1867_offset_bipolar_code)
{
  float temp_offset;
  *LTC1867_lsb = (fs_voltage-zero_voltage)/((float)(fs_code - zero_unipolar_code));                     //! 1) Calculate the LSB
   
  temp_offset = (zero_voltage/ *LTC1867_lsb) - zero_unipolar_code;                                      //! 2) Calculate Unipolar offset
  temp_offset = (temp_offset > (floor(temp_offset) + 0.5)) ? ceil(temp_offset) : floor(temp_offset);    //! 3) Round
  *LTC1867_offset_unipolar_code = (int32_t)temp_offset;                                                 //! 4) Cast as int32_t
   
  temp_offset = (zero_voltage / *LTC1867_lsb) - zero_bipolar_code ;                                     //! 5) Calculate Bipolar offset
  temp_offset = (temp_offset > (floor(temp_offset) + 0.5)) ? ceil(temp_offset) : floor(temp_offset);    //! 6) Round
  *LTC1867_offset_bipolar_code = (int32_t)temp_offset;                                                  //! 7) cast as int32_t
}</div><script>showreplylogin();</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

清风烈酒 发表于 2018-1-30 12:20

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2018-1-30 10:54
你看一下0V,2V,4V对应的ADC CODE分别是多少
再参照一下官方的转换函数看下是不是计算的时候出了问题?
...

用基准源给定2V,AD读到的值是0xFE06,给定4V也是0xFE06左右。
官方提供的源码有点看不懂啊</div><script>showreplylogin();</script>

littleshrimp 发表于 2018-1-30 17:34

<div class='shownolgin' data-isdigest='no'>清风烈酒 发表于 2018-1-30 12:20
用基准源给定2V,AD读到的值是0xFE06,给定4V也是0xFE06左右。
官方提供的源码有点看不懂啊

再看看输出数据有没有篡位</div><script>showreplylogin();</script>

清风烈酒 发表于 2018-1-31 10:45

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2018-1-30 17:34
再看看输出数据有没有篡位

也没有啊,请问下如果使用内部基准,基准电压是4V吗?REFCOMP有4V输出,VREF为2.4v。我用外用表量了进来的电压和给定的电压差不多,但是2~4V就有问题了。用U32保存数据也没有溢出的情况请帮我看下这个原理图有没有问题。
</div><script>showreplylogin();</script>
页: [1]
查看完整版本: LTC1867芯片单极模式只能采样0~2V