我们正在尝试了解如何从 BeagleBone Black 的 PRU 配置和访问 AIN 值。 我们已按照如下所示配置系统以读取 AIN0-2、但当我们从 FIFO 读取 AIN 值时、根据我们在输入端测量的电压、这些值与我们预期的值不匹配。
ADC_GET()根据计时器(当前为100ms)进行定期调用。 例如、我们看到的 AIN1值如下:
伏 FIFO
0.571V = 1057
0.900V = 1895
1.297V = 2705
数字值正在发生变化、但不像我们从公式中所期望的那样:
D = Vin *(2^n - 1)/Vref
Vin = 0.571 *(2^12-1)/ 1.8
VIN = 1299.025
我们实际上得到的是1057
我们正在尝试了解原因?
另一个观察结果:中心0.9V 与上面和下面的值之间的差值为0.002V 或28个计数。
0.9 - 0.571 = 0.329V = 838 ADC 计数
1.227 - 0.9 = 0.327V = 810 ADC 计数
----------------------------------
0.002V 的差值= 28次计数
在 out 设备树.dtsi 文件中、我们有:
tscadc{(&T)
ADC{
TI、ADC 通道=<0 1 2>;
};
};
void ADC_Init_Steps (void)
{
ADC_TSC (0x40)|=(1 << 2);// CTRL:步进配置寄存器是可写的
ADC_TSC (0x64)&=(0x1F);// STEPCONFIG1:清除模式和采样平均值
ADC_TSC (0x64)|= // STEPCONFIG1:
(
(3 << 2) // 8个样本平均调试 du
|(0 < 19) //通道 ID 0 SEL_INP
|(0 < 15) //通道 ID 0 SEL_INM
|(0 < 0) //启用软件、单次触发
);
ADC_TSC (0x68)= 0x98; // STEPDELAY1:开路延迟= 0x98
ADC_TSC (0x6C)&=(0x1F);// STEPCONFIG2:清除模式和采样平均值
ADC_TSC (0x6C)|= // STEPCONFIG2:
(
(3 << 2) // 8个样本平均调试 du
|(1 << 19) //通道 ID 1 SEL_INP
|(1 << 15) //通道 ID 1 SEL_INM
|(0 < 0) //启用软件、单次触发
);
ADC_TSC (0x70)= 0x98; // STEPDELAY2:开路延迟= 0x98
ADC_TSC (0x74)&=(0x1F);// STEPCONFIG3:清除模式和采样平均值
ADC_TSC (0x74)|= // STEPCONFIG3:
(
(3 << 2) // 8个样本平均调试 du
|(2 << 19) //通道 ID 2 SEL_INP
|(2 << 15) //通道 ID 2 SEL_INM
|(0 < 0) //启用软件、单次触发
);
ADC_TSC (0x78)= 0x98; // STEPDELAY3:开路延迟= 0x98
ADC_TSC (0x54)= 0;// STEPENABLE:禁用所有步骤
ADC_TSC (0x40)&=~(1 << 2);// CTRL:步进配置寄存器受到保护
}
void ADC_DRAT_Fifos (void)
{
//清除 FIFO
uint16_t fifo_count;
FIFO_COUNT = ADC_TSC (0xE4); // FIFO0COUNT
while (fifo_count->0)
{
(空) ADC_TSC (0x100);// FIFO0DATA
}
FIFO_COUNT = ADC_TSC (0xF0); // FIFO1COUNT
while (fifo_count->0)
{
(空) ADC_TSC (0x200);// FIFO1DATA
}
}
空 ADC_Enable (bool 启用)
{
uint32_t ctrl_mask =
(
(1 << 1) // FIFO 中包含捕捉数据的步进 ID 号
|(1 << 0) //已启用
);
uint32_t STEP_ENABLE_MASK =
(
(1 << 1) //启用步骤1
|(1 << 2) //启用步骤2
|(1 << 3) //启用步骤3
);
if (启用)
{
ADC_TSC (0x54)= 0;// STEPENABLE:
ADC_RELET_Fifos ();
ADC_TSC (0x54)= STEP_ENABLE; // STEPENABLE:
ADC_TSC (0x40)|= CTRL_MASK;// CTRL:
}
其他
{
ADC_TSC (0x54)= 0; // STEPENABLE:
ADC_TSC (0x40)&=~(CTRL_MASK);// CTRL:
}
}
int32_t ADC_Get (uint32_t ADC_DATA[]、size_t NUMBER_OW_SAples)
{
int timeout = 1000;
//对数据进行旋转等待
while (1)
{
if (超时--<= 0)
{
返回-1;
}
uint32_t fifo_count = ADC_TSC (0xE4); // FIFO0COUNT
if (fifo_count >= number_of _samples")
{
int i;
for (i=0;<fifo_count;i++))
{
ADC_DATA[i]= ADC_TSC (0x100);// FIFO0DATA
}
返回 fifo_count;
}
}
}
void ADC_Init (void)
{
/*启用 TSC_ADC 时钟模块*/
while (!(CM_PER_ADC_TSC 和0x2))
CM_PER_ADC_TSC |= 0x2;
ADC_TSC (0x48)=~(0xFFF << 16);// ADCRANGE max = 0xFFF、min = 0
ADC_Init_Steps();
ADC_Enable (0);
ADC_RELET_Fifos ();
}