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.

[参考译文] MSP430G2553:在不同引脚上进行多个 ADC 读取

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1387533/msp430g2553-multiple-adc-reads-on-different-pins

器件型号:MSP430G2553

工具与软件:

大家好!

我目前就职于一个项目、其中有 PIN1.1、PIN2.2和 PIN2.4三路模拟输入。 我想使用我的 ADC 读取所有这些引脚。

目前、我将使用 ADC10执行此操作、并按顺序读取三个输入。 但我不知道如何专门为 ADC 使用引脚1、之后是引脚2。

非常感谢您的帮助。

此致、

Timo

#include <msp430.h>
#include <stdint.h>

#define CURRENT BIT1 // Pin 1.1
#define VOLTAGE BIT4 // Pin 2.4
#define TEMPERATURE BIT2 // Pin 2.2

volatile uint16_t current = 0; // Variable to store ADC result
volatile uint16_t voltage = 0; // Variable to store ADC result
volatile uint16_t temperature = 0; // Variable to store ADC result

void start_ADC_conversion();

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer

    ADC10CTL1 = INCH_4 + ADC10SSEL_1;       // Channel select A4    +   Conversion sequence mode select ==  Sequence-of-channels    + ACLK - clock (no input div)
    ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE;    // REF = VCC & VSS + ADC SampleAndHoldTime 16 x ADC10CLKs  + + //
    ADC10AE0 |= CURRENT;                   //   These bits enable the PIN 1.1 for analog input
    ADC10AE0 |= (VOLTAGE | TEMPERATURE);                   //   These bits enable the PIN 2.2 & 2.4 for analog input
    P1SEL |=  CURRENT;                     //  ADC input select mode P1.1
    P2SEL |= (VOLTAGE | TEMPERATURE);       // ADC input select mode P2.2 & 2.4

    __bis_SR_register(GIE);             // Enable global interrupts

    while (1) {
        start_ADC_conversion();         // Start an ADC conversion
        __delay_cycles(500000);         // Delay for a while (for demonstration purposes)
    }
}

void start_ADC_conversion() {
    ADC10CTL1 = INCH_1;     // select channel A1 for ADC
    ADC10CTL0 |= ADC10SC + ENC; // ADC10SC == 0 >> no sample start conversation + ENC == EnableConversation
    current = ADC10MEM;   // saves the ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;  // disable conversation
    ADC10CTL0 &= ~ADC10IFG; // deletes the ADC-InterruptFlag for the next conversation

    ADC10CTL1 = INCH_4;     // select channel A4 as input
    ADC10CTL0 |= ADC10SC + ENC;
    voltage = ADC10MEM;       // save ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;
    ADC10CTL0 &= ~ADC10IFG; // deletes the ADC-InterruptFlag for the next conversation

    ADC10CTL1 = INCH_2;     // select channel A2 as input
    ADC10CTL0 |= ADC10SC + ENC;
    temperature = ADC10MEM;       // save ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
    ADC10CTL0 &= ~ADC10IFG;            // Clear interrupt flag
    __bic_SR_register_on_exit(CPUOFF);  // Clear CPUOFF bit to exit LPM0
}

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

    尊敬的 Timo:

    根据 器件的数据表第22.2.6.2节、如果您将 ADC10置于"通道序列"模式(ADC10CTL1.CONSEQ 位= 0x01)、请将 ADC10CTL1.INCH 位设置为您要测量的最高通道、在本例中为 INCH_4 (这将成为起始通道)。 然后、当转换开始时、第一次测量值存储在 ADC10MEM 中并且设置中断标志 ADC10IFG、然后下一个通道 INCH_3被转换并且结果存储在 ADC10MEM 中、ADC10IFG 被设置、依此类推至通道 INCH_0。

    最好使用中断并处理 ISR 中的 ADC10MEM 读取、这样就无需轮询 ADC10IFG。  您可以将测量值存储在阵列中、并丢弃与不需要的通道相关的测量值。  此外、您还可以设置 DTC (数据传输控制)功能、以便自动将结果发布到存储器中。

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

    尊敬的 Dennis:

    感谢您的帮助。 我想这对我已经有帮助了。

    您能告诉我如何设置端口2以正确读取 ADC 吗?

    如果我使用 ADC10AE1寄存器、则会收到错误"标识符"ADC10AE1"未定义"。

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

    尊敬的 Timo:

    这是因为该器件的端口2上没有模拟输入通道。  选择这些引脚的原因是否存在?

    有关引脚说明、请参阅数据表中的第4.2节。