部件号: AM3358
(这与之前的查询有关,我想我已链接到它,但更新系统没有明确说明我是这样做的。) 这次我有不同的问题。
对于背景、此传感器由 BeagleBone Black 在 Linux 下使用 pru0 使用 C 代码读取。 我们的问题仍然是、当启用 ADC 阶跃时、信号会出现 1030mV 漂移。 我将在下面发布我们的代码、但首先这里是简单的传感器电路。 
基本上、当光触发 CR1 时、TO_AINx 上的电压输出)... 接近于零。 当光线受阻时、TO_AINx 上的电压输出会上升至 1.6V。 该电路是我们系统的基础、在我们的应用中表现良好。 更改它目前不是一个选项。
问题在于、当我们通过单位增益电压跟随器在示波器上监测 TO_AINx 时、当光线到达 CR1 时、信号接近于零(例如 5mV)、直到我们开始使用 BeagleBone 通过 AM3558 的 ADC 读取信号。 然后、信号漂移在 1030mV 之间。
该信号当前进入 ADC 上的 AIN0。 我们还使用 AIN5 作为读取另一个传感器的第二步。 我们只启用了两个步骤。 它们处于单次触发模式。 同样、我将在下面发布设置代码。
关于这一点、我有一些建议、希望在请进行更改之前获得 TI 的意见。
1) 有人建议 AIN5-AIN7 由于其电荷耦合方式、实现这一目的的可能性较小。 我们可以尝试使用 AIN6、而无需在板上进行过多的黑客攻击。 (但该信号将通过上述单位增益电压跟随器电路,合并这两项更改。)
a) 此建议是否有效?
B) 如果有效、我是否必须切断与 AIN0 的连接以消除电流影响、即使我禁用 AIN0 也是如此?
2) 建议将所有未使用的 AIN 输入接地。 这对解决这个问题是否有价值?
3) 是否有任何可减少漂移问题的通道配置选项? 目前、我们在环路中以尽可能快的速度读取输入。
4) AIN5 中的信号似乎不存在该漂移问题。 但是、在这种情况下、信号通过自定义电流环路到模拟转换器输出级上的运算放大器。 在我看来、这使我相信具有漂移的部分可能有漏电流。
以下是涉及的两个 PRU 代码例程。
static void ADCConfigure(void)
{
unsigned int i, count, data;
// // Actual sensor name as been replaced with "SENSOR WITH DRIFT" to mask a bit of our proprietary process.
/* Enable ADC module clock */
HWREG(SOC_CM_WKUP_REGS + CM_WKUP_ADC_TSC_CLKCTRL) = 0x02;
/* Disable ADC module for configuration */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) &= ~0x01;
/* fs = 24MHz / ((CLKDIV+1)*2*Channels*(OpenDly+Average*(14+SampleDly)))
* = 53.57kHz
* CLKDIV = 0
* Channels = 1
* Average = 16
* OpenDly = 0
* SampleDly = 0
*/
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_ADC_CLKDIV) = 0;
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_ADCRANGE) = 0xFFF << 16;
/* Disable all steps for now */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPENABLE) &= 0xFF;
/* Unlock step configuration */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x04;
//Step 0 config: SW mode, one shot mode, fifo 0, channel 0, AIN0 on the Beaglebone Black, 4 samples averaged
//SENSOR WITH DRIFT
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(0)) = 0x00000008;
//Step 1 config: SW mode, one shot mode, fifo 0, channel 1, AIN1 on the Beaglebone Black, 4 samples averaged
//FLOW METER
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(1)) = 0x00080000; //no averaging
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(1)) = 0x00080004; //averages 2 samples
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(1)) = 0x00080008; //averages 4 samples
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(1)) = 0x0008000C; //averages 8 samples
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(1)) = 0x00080010; //averages 16 samples
//Step 2 config: SW mode, one shot mode, fifo 0, channel 4, AIN4 on the Beaglebone Black, 4 samples averaged
//UNUSED
//HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(2)) = 0x00200008; //averages 4 samples
//Step 2 config: SW mode, one shot mode, fifo 0, channel 5, AIN5 on the Beaglebone Black, 4 samples averaged
//UNUSED
//HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(2)) = 0x00280008; //averages 4 samples
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(0)) = 0xFF000000; //255
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(1)) = 0xFF000000; //255
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(0)) = 0xC8000000; //200
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(1)) = 0xC8000000; //200
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(0)) = 0xAF000000; //175
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(1)) = 0xAF000000; //175
// HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(2)) = 0xFF000000;
/* Enable channel ID tag */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x02;
/* Clear end-of-sequence interrupt */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS) = 0x02;
/* Enable end-of-sequence interrupt */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQENABLE_SET) = 0x02;
/* Lock step configuration */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) &= ~0x04;
/* Empty FIFO 0 */
count = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFOCOUNT(0));
for (i = 0; i < count; i++) {
data = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFODATA(0));
}
/* Enable ADC module */
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x01;
}
static void ReadSensorValues()
// Actual sensor name as been replaced with "Drifting Sensor" to mask a bit of our proprietary process.
//This procedure reads the current values from the Sensor with Drift and the Flow Sensor.
//(The Flow Sensor value returned is actually calculated by average the last 10 Flow Sensor values. - NOT TRUE CURRENTLY)
{
int i;
unsigned int count;
unsigned int StepRead; // the step that was read
unsigned int RawAnalog; //bottom detector data
// const unsigned int Flow_Sensor_Array_Size = 10;
// static unsigned int Flow_Sensor_Array[10];
// static unsigned int Flow_Sensor_Sum;
// static unsigned int Flow_Sensor_Avg;
// static unsigned int fspnr;
// Start step
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPENABLE) = 0xE; // enables steps 1,2 and 3. TSC Charge is not enabled (bit 0)
// Wait for interrupt
while (!(HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS)&0x02));
// Clear interrupt
HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS) = 0x02;
Data = 0xFFFFFFFF;
count = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFOCOUNT(0));
// #PRAGMA MUST_ITERATE
for (i = 0; i < count; i++) // count is the number of readings
// in the ADC FIFO buffer
{
Data = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFODATA(0));
StepRead = (Data >> 16) & 0xF;
RawAnalog = Data & 0xFFF;
switch (StepRead)
{
case 0: //DRIFTING SENSOR
DriftingSensor_Voltage = RawAnalog;
break;
case 1: //FLOW SENSOR
Curr_FlowSensorValue = RawAnalog;
if ((CALIBRATE_PID) && (GelPrimed) && (MaxFSVReached == 0))
{
ReadsToMaxFSV++;
if ((Curr_FlowSensorValue > Max_FSV) || (Curr_FlowSensorValue < 114))
//FSV still increasing or FSV is not above .05v yet
{
Max_FSV = Curr_FlowSensorValue;
ReadsSince_FSV_Increase = 0;
}
else
{
ReadsSince_FSV_Increase++;
if (ReadsSince_FSV_Increase > 900) //assume MaxFSVReached (4000 = 500 ms not increasing)
{
MaxFSVReached = 1;
// SavedMax = Max_FSV;
// __R30 |= SignalToSM; // set signal line to Singulator Module high
// SM_Signal_On = 1;
// SM_Read_Count = 0;
}
}
}
// if (Curr_FlowSensorValue > Max_FSV)
// Max_FSV = Curr_FlowSensorValue;
break;
// case 2:
// break;
default: // flash red LED indicating a problem
// for (j=0;j<20;j++)
// {
// FlashPanelLEDs(1,0,0,0,0,1,10);
// }
break;
} //end of Switch statement
} // bottom of for (i = 0; i < count; i++) loop
// finished loop reading all values from ADC FIFO buffer
}