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.

[参考译文] MSP430F6779:MSP430F6779 ADC10不读取满量程

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1209346/msp430f6779-msp430f6779-adc10-not-reading-full-scale

器件型号:MSP430F6779

我正在尝试读取 A3上的一个模拟输入。 当我将模拟输入端的电压提升到2V 左右时、ADC 值似乎在511时达到最大值。 第10位似乎没有被使用。 我需要更改哪个寄存器才能使其读取1023的满标度并使用所有10位?  

/*--------------- */
/* EVSE ADC10设置*/
/*--------------- */
/*为配置准备 ADC10A */
ADC10CTL0 &=~ADC10ENC;
/*清除挂起的中断以确保 DMA 的触发*/
ADC10IFG = 0;

/* ADC 打开、ADC10等待来自 SD24的触发、采样时间2us 8xADCclk、自动下一个转换 */
ADC10CTL0 = ADC10SHT0 | ADC10ON | ADC10MSC;

//*由 SD24触发,SMCLK/6 = 4MHz,脉冲采样模式*/
ADC10CTL1 = ADC10SHP | ADC10SHS_0 | ADC10DIV_0 | ADC10SSEL_3 | ADC10CONSEQ_2;/*单通道、重复转换*/

/* 10位转换结果*/
ADC10CTL2 |= ADC10RES;

/*启用 ADC 转换完成中断*/
ADC10IE |= ADC10IE0;

/* A3 ADC 输入选择;Vref=AVCC */
ADC10MCTL0 |= ADC10INCH_3 | ADC10SREF_0;

/*启用 ADC10中断*/
//ADC10IE = ADC10IE0 | ADC10OVIE | ADC10TOVIE;

/*启动 ADC 并等待软件启动转换触发器*/
ADC10CTL0 |= ADC10ENC + ADC10SC;

谢谢。

Mike

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

    SMCLK 的速度是多少(ADC10SSEL=3)? 数据表(SLAS768E)第5.57节显示了 ADC 时钟要求。 在实践中、MODCLK (ADC10SSEL=0)始终在规格范围内、因为该时钟的设计对象是 ADC。

    更一般地说、如果源具有高阻抗、则需要更高(更长)的 ADC10SHT 设置、以确保采样电容器有时间充电。

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

    超棒的布鲁斯 将  ADC10SSEL=3更改为 ADC10SSEL=0看起来效果很好!! :)  

    以下代码是否适用于获取多个样本并对其求平均值? 或者仅采集一个样本是否更快/更好?  

    ISR (ADC10、ADC10_INTERRUPT)

      开关(__even_in_range (ADC10IV、ADC10IV_ADC10IFG)
      {
       案例 ADC10IV_NONE:
       中断;
        案例 ADC10IV_ADC10OVIFG:
        中断;
        案例 ADC10IV_ADC10TOVIFG:
        中断;
        案例 ADC10IV_ADC10HIIFG:
        中断;
        案例 ADC10IV_ADC10LOIFG:
        中断;
        案例 ADC10IV_ADC10INIFG:
        中断;
        案例 ADC10IV_ADC10IFG:
            ADC10IFG &=~ADC10IFG0;
            if ( adcSampleNumber >= 10 )
            {
                adcSampleNumber = 0;
                adc10Average = adc10Total / 10.0;
                adc10Voltage =(adc10Average / 1024)* 3.30;
                adc10total = 0.0;
                ADC10CTL0 &=~ADC10ENC;//在100之后禁用多个采样
            }
            方案
            {
                adcValues[adcSampleNumber]= ADC10MEM0;
                adc10otal = adc10otal + ADC10MEM0;
                adcSampleNumber = adcSampleNumber + 1;
            }
            中断;
        }
    }

    感谢您的帮助!

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

    1) 1)您应该警惕在 ISR 中使用浮点。 (如果您可以完全避免它、例如使用缩放整数、那会更好。) 我看不到你的变量的声明;如果它只是终止条件(计算平均值),可能不重要,但如果 adcValues[]是浮动的,你可能会得到超限。

    2)如果 CONSEQ=2、设置 ENC=0不会停止当前转换[请参阅用户指南(SLAU208Q)第二部分27.2.7.6]。 这意味着,在计算平均值之后,你可能会多得到一个 IFG0 ,这将在 adcValues[0]中留下一个过时的值。 [编辑:可能在终止时设置 IE0=0,然后在设置 IE0=1时设置 IFG0=0以重新启动序列。]

    3)对连续读数求平均值可以降低信号上的随机噪声。 但这是假设信号在整个平均值计算周期内保持稳定。 如果这与另一个线程的实验相同、我认为您必须仔细进行设计、以便在您的采样窗口中获得一个 ADC 测量值。

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

    我主要使用浮点将 ADC 值转换为实际电压、仅用于初始测试、以便将其与电压输入进行比较。 一旦一切正常、我就会清除这个代码。

    这与我要测量 PWM 信号高侧的另一个线程相同的代码。 我计划确保 ADC 值高于某个阈值、以消除在 PWM 信号的高侧期间未发生的样本。  

    那么、仅采集一个样本会更好吗?  

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

    好的、请注意您的浮点用法不会妨碍您执行的操作。

    根据另一个线程中的估计、我建议您首先关注获取一个样本、而不是求平均值。 您可能仍需要使用数组、以便能够了解 PWM (高电平)周期结束的位置。

    [编辑:对于那些好奇,这是"其他线程":

    https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1208935/msp430f6779-msp430f6779-measuring-voltage-of-pwm-signal

    ]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    以下代码是否适合采集多个样本并对其求平均值? 或者仅取一个样本是否更快/更好?

    这是一种可怕的方法。 您的信号应该已经通过了抗混叠滤波器(如果没有其他任何情况、至少是一个简单的 RC 滤波器)、这意味着使用 MSC 根本不会改变信号。 这所做的就是对 ADC 内部噪声求平均值。 值。 它还对信号的源阻抗提出了严格要求。

    如果要使用数字低通滤波器、请以所需输出采样率的几倍使用均匀的样本。 最佳值是2的幂数、因为这会创建定点结果。

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

    感谢 David 和 Bruce 的建议! 以下是我更新后的 ADC10 ISR 代码。  

    ISR (ADC10、ADC10_INTERRUPT)

      开关(__even_in_range (ADC10IV、ADC10IV_ADC10IFG)
      {
       案例 ADC10IV_NONE:
         中断;
       案例 ADC10IV_ADC10OVIFG:
         中断;
        案例 ADC10IV_ADC10TOVIFG:
          中断;
        案例 ADC10IV_ADC10HIIFG:
          中断;
        案例 ADC10IV_ADC10LOIFG:
          中断;
        案例 ADC10IV_ADC10INIFG:
          中断;
       案例 ADC10IV_ADC10IFG:
          ADC10CTL0 &=~ADC10ENC;
          ADC_RESULT = ADC10MEM0;//存储 ADC10通道0结果
          ADC10CTL1 ^= ADC10ISSH;//切换 ISSH 以在每个周期提供触发(EQU0)
          ADC10CTL0 |= ADC10ENC;
          中断;
       }
    }