This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294NCPDT:使用 ADC 进行温度采样

Guru**** 2530270 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1337688/tm4c1294ncpdt-temperature-sampling-with-the-adc

器件型号:TM4C1294NCPDT
您好!

对来自温度传感器的电压进行采样时出现问题、ADC 为 ADC 的每个"步进"获取不同的数据。

我将一个 NTC 热敏电阻安装到分压器中、该分压器由3.3V 电压供电、并有一个3.9千欧的固定电阻、 
固定电阻器是接地电阻器。 此分压器的输出进入跟随器配置中的运算放大器
为了减轻负载的影响、运算放大器的输出进入多路复用器、多路复用器的输出进入
微控制器的 ADC 引脚。
我对程序进行调试、以便始终观察传感器的温度和电阻是怎样的。 为了进行测试、我将
热敏电阻的电阻值固定时、PCB 上测量的电压是根据电阻值预期的电压、
但 code composer 中的温度与该电阻值不同、甚至比理论值高出10摄氏度。 你能给我什么建议吗?

void MUX_GPIO() //CONFIGURA LOS CANALES DE ADC PARA CADA COMBINACIÓN DE LOS MULTIPLEXORES
{

    //CANAL 0 DEL ADC
     GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, 0x00);//ENABLE1 del primer multiplexor NEGADA EN INTEGRADO
/*
     //entrada S3
      GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_5, 0xFF);//IN2
      GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_4, 0x00);//IN1

      ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR,0);
      ADCSequenceStepConfigure(ADC0_BASE, 0,0, 0);//(paso 1)
      ADCSequenceStepConfigure(ADC0_BASE, 0,1, 0);//(paso 2)
      ADCSequenceStepConfigure(ADC0_BASE, 0,2, 0);//(paso 3)
      ADCSequenceStepConfigure(ADC0_BASE, 0,3, 0);//(paso 4)
      ADCSequenceStepConfigure(ADC0_BASE, 0,4, 0);//(paso 5)
      ADCSequenceStepConfigure(ADC0_BASE, 0,5, 0);//(paso 6)
      ADCSequenceStepConfigure(ADC0_BASE, 0,6, 0);//(paso 7)
      ADCSequenceStepConfigure(ADC0_BASE, 0,7, 0|ADC_CTL_IE|ADC_CTL_END);//(paso 8)

      ADCSequenceEnable(ADC0_BASE,0);
      ADCIntClear(ADC0_BASE,0); //limpia las banderas de interrupción del ADC
      ADCProcessorTrigger(ADC0_BASE,0); //Causa un trigger para una secuencia de muestreo
      while(!ADCIntStatus(ADC0_BASE,0,false)) //indica el estado de las interrupciones
           {

           }
     ADCSequenceDataGet(ADC0_BASE,0,buffer_ADC);//obtiene los datos capturados por el adc

     mu_T=(buffer_ADC[0]+buffer_ADC[1]+buffer_ADC[2]+buffer_ADC[3]+buffer_ADC[4]+buffer_ADC[5]+buffer_ADC[6]+buffer_ADC[7])/8;
     vol_T=mu_T*3.3/4096; //aqui hubo breakpoint
     RT=((3900*(3.3-vol_T))/vol_T);
     T=(1/(0.000634544+(0.000321866*log(RT))+(-0.000000306*pow(log(RT),3))))-273.15;//aqui hubo breakpoint

     arreglo[2]=T;*/

   //entrada S4
   GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_5, 0xFF);//IN2
   GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_4, 0xFF);//IN1

   ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR,0);
   ADCSequenceStepConfigure(ADC0_BASE, 0,0, 0);//(paso 1)
   ADCSequenceStepConfigure(ADC0_BASE, 0,1, 0);//(paso 2)
   ADCSequenceStepConfigure(ADC0_BASE, 0,2, 0);//(paso 3)
   ADCSequenceStepConfigure(ADC0_BASE, 0,3, 0);//(paso 4)
   ADCSequenceStepConfigure(ADC0_BASE, 0,4, 0);//(paso 5)
   ADCSequenceStepConfigure(ADC0_BASE, 0,5, 0);//(paso 6)
   ADCSequenceStepConfigure(ADC0_BASE, 0,6, 0);//(paso 7)
   ADCSequenceStepConfigure(ADC0_BASE, 0,7, 0|ADC_CTL_IE|ADC_CTL_END);//(paso 8)

   ADCSequenceEnable(ADC0_BASE,0);
   ADCIntClear(ADC0_BASE,0); //limpia las banderas de interrupción del ADC
   ADCProcessorTrigger(ADC0_BASE,0); //Causa un trigger para una secuencia de muestreo
   while(!ADCIntStatus(ADC0_BASE,0,false)) //indica el estado de las interrupciones
        {

        }
   ADCSequenceDataGet(ADC0_BASE,0,buffer_ADC);//obtiene los datos capturados por el adc

   mu_T=(buffer_ADC[0]+buffer_ADC[1]+buffer_ADC[2]+buffer_ADC[3]+buffer_ADC[4]+buffer_ADC[5]+buffer_ADC[6]+buffer_ADC[7])/8;
   vol_T=mu_T*3.3/4096; //aqui hubo breakpoint
   RT=((3900*(3.3-vol_T))/vol_T);
   T=(1/(0.000634544+(0.000321866*log(RT))+(-0.000000306*pow(log(RT),3))))-273.15;//aqui hubo breakpoint

   arreglo[3]=T;




//--------------------------------------------------------------------------------------------------------------------------------

}


这是我的代码 

梅拉
 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     我没有看到您为 AIN_0配置 PE3。 您需要在下面一行。  

    GPIOPinTypeADC (GPIO_Port_BASE、GPIO_PIN_3);  

     请参阅 TivaWare SDK 中的示例 、网址为 C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\adc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好

    
    我已经配置了 ADC 引脚、这是我的相应代码。 但我已经意识到、在该计算中、 
    I 执行、生成的所有十进制值都已使用、在执行此操作时、温度值会发生变化、
    例如,在变量 vol_T=3.29919434中,该电压值的温度为1342 °C ,当
    "理论上"、对于3.29伏、428°C 的温度值应该近似。
    您能给我一些建议、以便我的"实际"温度更接近"理论"温度吗? 
     


    void INIT_ADC() //inicializa el ADC
     {
         SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //habilita el periferico para ADC0
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //habilita el periferico E
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //habilita el periferico B
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //habilita el periferico D
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); //habilita el periferico K
         while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));
    
         GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3); //PINES PARA ENTRADA ADC0
         GPIOPinTypeADC(GPIO_PORTB_BASE,GPIO_PIN_3); //PINES PARA ENTRADA ADC0
         GPIOPinTypeADC(GPIO_PORTD_BASE,GPIO_PIN_3); //PINES PARA ENTRADA ADC0
         GPIOPinTypeADC(GPIO_PORTK_BASE,GPIO_PIN_3); //PINES PARA ENTRADA ADC0
     }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     您的代码中使用的是数组 buffer_adc。 buffer_adc[1]的值为一个奇怪的值,即536871428。 您知道原因吗?

     您如何声明您的变量如 vol_T 和其他变量?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    不,我不能说为什么[1]有一个奇怪的价值,我认为这是只发生了一次的事情。
    
    可通过以下方式声明变量: 
    uint32_t buffer_ADC[24]; // arreglo para guardar datos entrantes del ADC
    
    float arreglo[12]; //arreglo para guardar los datos de los termistores
    float vol_T=0.0; //guarda el dato de voltaje
    float RT=0.0;//guarda el dato de resistencia del termistor
    float mu_T; //guarda el promedio de muestreo del adc
    float T=0.0;//guarda el dato de temperatura
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     我建议您找出问题所在。 首先、只需对数据进行采样并读出数据、而无需执行任何浮点操作。 是否得到了 ADC FIFO 中存储的正确值? 这将告诉您问题是否与浮点运算有关。 如果 ADC 在采样正确的值时正确、您可以 进一步研究浮点数计算。 由于使用浮点运算、因此需要确保具有足够的堆栈。 尝试增加堆栈和堆内存。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    
    我隔离了 ADC 采样、采样值​​不对应于那些预期的值、 
    对于相同的 ADC 通道和固定的电阻值、ADC 样本会发生变化、
    但当我施加3.3V 电压(即电源电压)时, ADC 值​​仍然是静态的。

    此致

    梅拉
    
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     您具有以下代码。 您正在为 ADC 配置 PE3、PB3、PD3和 PK3。 这是你想要的吗?

    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);//Pines para entrada ADC0
    GPIOPinTypeADC (GPIO_PORTB_BASE、GPIO_PIN_3);//Pines para entrada ADC0
    GPIOPinTypeADC (GPIO_PORTD_BASE、GPIO_PIN_3);//Pines para entrada ADC0
    GPIOPinTypeADC (GPIO_PORTK_BASE、GPIO_PIN_3);//Pines para entrada ADC0

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    
    是的、我占用了多个 ADC 通道。 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我现在感到困惑。 一方面、您想要在 PE3、PB3、PD3和 PK3上对渠道进行采样、但在您之前的发布中、您有以下代码。 是否确定要对 AIN12和 AIN19进行采样? 我们的代码表明您正在尝试对 AIN0进行八次采样。 你有0作为样本组0中8个步进中每一个步进的第四个参数。  

    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR,0);
    ADCSequenceStepConfigure(ADC0_BASE, 0,0, 0);//(paso 1)
    ADCSequenceStepConfigure(ADC0_BASE, 0,1, 0);//(paso 2)
    ADCSequenceStepConfigure(ADC0_BASE, 0,2, 0);//(paso 3)
    ADCSequenceStepConfigure(ADC0_BASE, 0,3, 0);//(paso 4)
    ADCSequenceStepConfigure(ADC0_BASE, 0,4, 0);//(paso 5)
    ADCSequenceStepConfigure(ADC0_BASE, 0,5, 0);//(paso 6)
    ADCSequenceStepConfigure(ADC0_BASE, 0,6, 0);//(paso 7)
    ADCSequenceStepConfigure(ADC0_BASE, 0,7, 0|ADC_CTL_IE|ADC_CTL_END);//(paso 8)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    代码中的大部分内容都会添加注释。 为什么不 将您的代码集中在一个传感器上的一个通道上。 删除所有注释掉的代码。 此外、我在您的最新代码中也不会看到像 PE3或您想要使用的任何引脚那样使用哪个引脚进行采样。 您在最新代码中的哪个位置有 GPIOPinTypeADC ()?  为了便于读取、请勿使用以下方式编写代码。

    ADCSequenceStepConfigure (ADC0_BASE、0、0、0);//(Paso 1)

    而应按以下内容进行编写。 它可以帮助其他正在阅读您的代码的人、也可以帮助您自己。

    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0);//(Paso 1)

    我将建议您仅对 一个通道采样一次、而不是8次。 看看它能起作用。 在 LaunchPad 上运行相同的程序。 我不知道外部有多路复用器、您的硬件是否以及如何在采样中发挥作用。 您是如何控制多路复用器的。 同样、从简单的东西开始、并根据您的应用要求逐渐扩展。 在 LaunchPad 上执行一个通道采样、然后添加另一个通道。 如果一切正常、请继续添加更多通道、然后在您自己的定制板上测试固件。  

    我也不在办公室,直到下星期三。 我的答复可能会有延误。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Mayray - Charles:

    如果您运行 PWM (3个 INA)、对 ADC 数据进行采样可能需要进行显著的过采样、以便从运算放大器获得稳定的温度读数。 ADC 通道输入还必须具有适当的阻抗匹配。 去耦电容器实际上会在计数中引入 PWM 接地噪声。 有趣的是、下拉电阻器(2K)或更大的电阻器有助于稳定采样计数、为 ADC 内部采样电容器提供放电路径。  BTW 请记住、Charles 提到在代码中配置了多个步骤、ADC 步骤是循环的、必须 POP 每个数组以卸载所需的步进数据、然后在下一次采样之前清除或漏出序列发生器。  

    此致、