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.

[参考译文] MSP430F6776A:ADC 无法从 SD24获取正确读数。

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1513223/msp430f6776a-adc-trouble-getting-correct-readings-from-sd24

器件型号:MSP430F6776A

工具/软件:

是嵌入式的新手 、我正在尝试从连接了压力传感器的 sd24通道读取原始数据(尚未校准、但这并不重要)。
我的代码基于库演示代码、该代码最初输出通道0、1和2的前16位。
我修改了代码以使用 SD24_B_getResults 函数来获得2个16位块。 这个问题是前8个 0似乎是放在数字的开头而不是结尾,把数字放在它的24位范围之外。
我甚至尝试了位移它,手动删除前8位,数字仍然不是正确的。
根据我的理解,从原始数据到 MV 的转换是(结果/2^23)*.6它应该给我一个.115的 MV 这将使原始数据~ 1,607,816.53。 由于不正确的设置、 仅通道0上的输出约为2708761088。
我尝试检查它是否可能是使用 SD24_B_initConverterAdvancedParam 设置进行的设置、但更改似乎也没有任何作用。 请让我知道如何从 sd24频道获得正确读数。

//*****************************************************************************
//  MSP430F67791A Demo - SD24_B, Continuous Conversion on a Group of 3 Channels
//
//  Description: This program uses the SD24_B module to perform continuous
//  conversions on a group of channels (0, 1 and 2). An SD24_B interrupt occurs
//  whenever the conversions have completed. Test by applying voltages to the
//  3 input channels and setting a breakpoint at the line indicated
//  below. Run program until it reaches the breakpoint, then use
//  the debugger's watch window to view the conversion results. Results
//  (upper 16 bits only) are stored in three arrays, one for each channel.
//  ACLK = n/a, MCLK = SMCLK = DCO =  ~ 1.1MHz
//  //* For minimum Vcc required for SD24_B module - see datasheet          *//
//  //* 100nF cap between Vref and AVss is recommended when using 1.5V REF  *//
//
//               MSP430F67791A
//             -----------------
//         /|\|              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |                 |
//   Vin1+ -->|SD0P0            |
//   Vin1- -->|SD0N0            |
//   Vin2+ -->|SD1P0            |
//   Vin2- -->|SD1N0            |
//   Vin3+ -->|SD2P0            |
//   Vin3- -->|SD2N0            |
//            |            VREF |---+
//            |                 |   |
//            |                 |  -+- 100nF
//            |                 |  -+-
//            |                 |   |
//            |            AVss |---+
//            |                 |
//
//   E. Chen
//   Texas Instruments Inc.
//   January 2014
//   Built with CCS Version: 5.5.0 and IAR Embedded Workbench Version: 5.52
//*****************************************************************************
#include <msp430.h>
#include "sd24_b.h"
#include <stdio.h>
/* Number of conversion results to store */
#define Num_of_Results 8

/* Arrays to store SD24_B conversion results */
unsigned int Ch0results[Num_of_Results];
unsigned int Ch1resultsLow[Num_of_Results];
unsigned int Ch1results[Num_of_Results];
unsigned int Ch2results[Num_of_Results];
uint32_t raw24;


volatile uint32_t lastRaw = 0;
volatile uint32_t Ch0Full[Num_of_Results];
volatile uint32_t Ch1FullBeforeConvert[Num_of_Results];
volatile uint32_t Ch1Full[Num_of_Results];
volatile uint32_t Ch2Full[Num_of_Results];
uint8_t Globalconverter = SD24_B_CONVERTER_1;


//#pragma vector=SD24B_VECTOR
__interrupt void SD24B_ISR(void)
{
    lastRaw = SD24_B_getResults(SD24_BASE, Globalconverter);
    SD24_B_clearInterrupt(
        SD24_BASE,
        Globalconverter,
        SD24_B_CONVERTER_INTERRUPT
    );
    __bic_SR_register_on_exit(LPM0_bits);  // wake main loop
}


void AlignmentSetup(void){
    SD24_B_initParam modParam = {
           .clockSourceSelect = SD24_B_CLOCKSOURCE_SMCLK,
           .clockPreDivider   = SD24_B_PRECLOCKDIVIDER_1,
           .clockDivider      = SD24_B_CLOCKDIVIDER_1,
           .referenceSelect   = SD24_B_REF_INTERNAL
       };
       SD24_B_init(SD24_BASE, &modParam);

       // —————————————————————————————
       // 2) Advanced per-converter init
       //    (right-aligned, two’s-complement,
       //     1× PGA, OSR=256, continuous)
       // —————————————————————————————
       SD24_B_initConverterAdvancedParam advParam = {
           .converter       = SD24_B_CONVERTER_0,          // channel 0 (SD0P0/SD0N0)
           .alignment       = SD24_B_ALIGN_RIGHT,          // right-aligned
           .startSelect     = SD24_B_CONVERSION_SELECT_SD24SC,
           .conversionMode  = SD24_B_CONTINUOUS_MODE,
           .dataFormat      = SD24_B_DATA_FORMAT_2COMPLEMENT,
           .sampleDelay     = SD24_B_FOURTH_SAMPLE_INTERRUPT,             // no interrupt delay
           .oversampleRatio = SD24_B_OVERSAMPLE_256,               // 256× OSR
           .gain            = SD24_B_GAIN_1             // unity PGA
       };

       SD24_B_initConverterAdvanced(SD24_BASE, &advParam);

       advParam.converter = SD24_B_CONVERTER_1;           // channel 1
       SD24_B_initConverterAdvanced(SD24_BASE, &advParam);

       advParam.converter = SD24_B_CONVERTER_2;           // channel 2
       SD24_B_initConverterAdvanced(SD24_BASE, &advParam);

       // —————————————————————————————
       // 3) Enable interrupts on channel 2 only
       //    (as in the demo)
       // —————————————————————————————
       SD24_B_enableInterrupt(SD24_BASE,
                              SD24_B_CONVERTER_2,
                              SD24_B_CONVERTER_INTERRUPT);

       // —————————————————————————————
       // 4) Start bucket-brigade / group conversion:
       //    group0 = converters 0–2
       // —————————————————————————————
       // TRGCTL1 holds the group-start bits (grp0 = bit0)
       HWREG16(SD24_BASE + OFS_SD24BCTL1) |= SD24GRP0SC;

       // —————————————————————————————
       // 5) Enter LPM0 w/ interrupts
       // —————————————————————————————
       //__bis_SR_register(LPM0_bits | GIE);
       /* */
}

uint32_t raw;
int32_t signedResult;

int32_t Convert2(int32_t bounds) {
    int32_t raw = (int32_t)(lastRaw >> 8);
    return (raw << 8) >> 8;  // Sign-extend 24-bit into 32-bit by shifting
}

int32_t Convert(uint32_t x)
{
    int32_t t = x & 0xffffff;
    return t - (t >> 23 << 24);
}

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

    SD24BCTL0 = SD24REFS | SD24SSEL_1;      // Select internal REF
                                            // Select SMCLK as SD24_B clock source


    AlignmentSetup(); // does this update alignments? Moving it stop register interrupts.
    SD24BCCTL0 = SD24ALGN | SD24SCS_4;      // Left-aligned, group 0
    SD24BCCTL1 = SD24ALGN | SD24SCS_4;      // Left-aligned, group 0
    SD24BCCTL2 = SD24ALGN | SD24SCS_4;      // Left-aligned, group 0


    SD24BIE = SD24IE2;                      // Enable channel 2 interrupt

    __delay_cycles(0x3600);                 // Delay for 1.5V REF startup

    SD24BCTL1 |= SD24GRP0SC;                // Set bit to start conversion
    __bis_SR_register(LPM0_bits | GIE);     // Enter LPM0 w/ interrupts
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24B_VECTOR //ties interrupt to below function
__interrupt void SD24BISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24B_VECTOR))) SD24BISR (void)
#else
#error Compiler not supported!
#endif
{
    static unsigned int index = 0;

    switch (SD24BIV)
    {
        case SD24BIV_SD24OVIFG:             // SD24MEM Overflow
            break;
        case SD24BIV_SD24TRGIFG:            // SD24 Trigger IFG
            break;
        case SD24BIV_SD24IFG0:              // SD24MEM0 IFG
            break;
        case SD24BIV_SD24IFG1:              // SD24MEM1 IFG
            break;
        case SD24BIV_SD24IFG2:              // SD24MEM2 IFG
        {
             raw = SD24_B_getResults(SD24_BASE, Globalconverter) & 0x00FFFFFF; // Mask to 24 bits
            if (raw & 0x00800000) {
                raw |= 0xFF000000; // Sign-extend if negative
            }
            signedResult = (int32_t)raw;
            lastRaw = SD24_B_getResults(SD24_BASE, Globalconverter);
            Ch0Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_0); //gives me ~2708761088
            Ch1Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_1); //gives me ~2360862464
            //Ch1FullBeforeConvert[index] = Ch1Full[index] ;                     
            //Ch1Full[index] = Convert2(Ch1Full[index]);
            Ch2Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_2); //gives me ~2148898816



            Ch0results[index] = SD24BMEMH0; // Save CH0 results (clears IFG)

            Ch1resultsLow[index] = SD24BMEML1; // Low CH1 results (clears IFG)
            Ch1results[index] = SD24BMEMH1; // Save CH1 results (clears IFG)
            Ch2results[index] = SD24BMEMH2; // Save CH2 results (clears IFG)
            if (++index == Num_of_Results)
            {
                index = 0;                  // SET BREAKPOINT HERE
            }
            break;
        }
    }
}

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

    我没有找到您开始的演示、但看起来很奇怪:

    > AlignmentSetup();//此更新对齐吗? 移动它会停止寄存器中断。
    > SD24BCCTL0 = SD24ALGN | SD24SCS_4;//左对齐、组0
    > SD24BCCTL1 = SD24ALGN | SD24SCS_4;//左对齐、组0
    > SD24BCCTL2 = SD24ALGN | SD24SCS_4;//左对齐、组0

    AlignmentSetup()设置 ALIGN_RIGHT (低24位)、但随后的三个语句设置左对齐(高24位)。 看起来您的 Convert 函数需要右对齐。 如果删除 SD24ALGN 设置、是否会得到更合理的结果?