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;
}
使用的外部4.069基准吗? littleshrimp 发表于 2018-1-29 18:07
使用的外部4.069基准吗?
使用的内部基准,我用万用表测了REFCOMP引脚有4.07V的电压 清风烈酒 发表于 2018-1-30 09:33
使用的内部基准,我用万用表测了REFCOMP引脚有4.07V的电压
看你的情况像是单端模式没有设置成功,差分模式下会出现你说的这种情况,你再检查一下设置看看 littleshrimp 发表于 2018-1-30 10:05
看你的情况像是单端模式没有设置成功,差分模式下会出现你说的这种情况,你再检查一下设置看看
上表我用的是下面8行的配置,上面八行是差分输入吧。
我这边实际电压0V对应采集值0V,实际电压2V对应采集值为2V,2.01V开始就变成了0V,实际电压4V对应的采集值是1.996V。
麻烦大神解析,感激不尽:) <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> <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> <div class='shownolgin' data-isdigest='no'>清风烈酒 发表于 2018-1-30 12:20
用基准源给定2V,AD读到的值是0xFE06,给定4V也是0xFE06左右。
官方提供的源码有点看不懂啊
再看看输出数据有没有篡位</div><script>showreplylogin();</script> <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]