MC56F8257的ADC输出越限原因

MC56F8257的ADC是一个12位的ADC,而2^12=4096,所以按说只能输出0—4096范围内的值。但是在实际的使用过程中会发现,配置为12位的ADC会输出远大于4096的数字。

而ADC的转换结果会存储在ADC_RSLTn寄存器中。该寄存器的结构如下:

ADC_RSLTn

寄存器的0—2位为保留位;3—14位存储转换的结果;最高位15位为符号位,1表示为负,0表示为正。

而ADC的GetValue的函数中会将ADC_RSLTn的数值直接存在pValue中。返回的值包括第15位最高位的符号位。所以2^15=32768,实际输出的范围是0—32768。

byte AD1_GetValue(void* Values)
{
  register word *pValue=(word*)Values;

  if (!OutFlg) {
    return ERR_NOTAVAIL;
  }
  *pValue = getReg(ADC_RSLT0);
  return ERR_OK;
}

与GetValue相比GetValue16中则会将ADC_RSLTn的数值向左移一位,所以返回的值并不包括第15位最高位的符号位。而相应的,2^15=65536,所以实际的输出范围是0—65536。

byte AD1_GetValue16(word *Values)
{
  if (!OutFlg) {
    return ERR_NOTAVAIL;
  }
  *Values = (getReg(ADC_RSLT0) + 0x00U) << 1U;
  return ERR_OK;
}

所以如果真的只想得到ADC_RSLTn中间那12位结果的话,对应函数中的语句应当进行如下改动:

对于GetValue:

*pValues = (getReg(ADC_RSLT0) & 0x7FF8) >> 3;

对于GetValue16:

*Values = (getReg(ADC_RSLT0) & 0x7FF8) >> 4;

如此的得到的结果的范围便是0—4096了。

但是实际上ADC在这之后还应当进行一次标度变换,而无论是否进行位移动,分辨率都不会有变化,对应的实际的物理意义也不会有变化,只是单纯的数字量的倍数关系而已。所以是否进行寄存器的位移动没有实际意义。