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.

[参考译文] MSP430F5638:ADC12寄存器单个内部温度读取问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1029479/msp430f5638-adc12-register-questions-for-single-internal-temperature-read

器件型号:MSP430F5638

在定制 SBC 上使用 CCS v10.4和 msp430f5638。 我已经创建了两 个 ADC12读取函数、它们源自两个 TI 示例。

RUN_430_ADC_T ()、它源自 MSP430F55xx_ADC_10.c、并读取内部温度传感器的单个通道、ISR 案例6。

RUN_430_ADC_DAV ()、 它源自 MSP430F55xx_ADC_09.c、并读取包含内部电压的单个3个通道序列、ISR 案例32。

两个示例以及我的两个派生函数在单独运行时都可以正常运行。 按顺序运行时,第二个调用不会正确运行,而不管首先运行哪个调用。

此帖子用于 run_430_ADC_T ()(单次读取温度)和为这两个函数提供服务的 ISR。 我需要更好地了解设置和使用寄存器来确定问题。

问题

1.//ADC12CTL0  &=~ADC12ON; //初始时关闭 ADC 以清除 ADC

这是关闭和清除 ADC 设置的有效方法吗?还是仅打开/关闭、对寄存器设置没有影响?

 ADC12CTL0 = ADC12SHT0_8 + ADC12REFON + ADC12ON;//内部基准= 1.5V、基准打开、ADC 打开

ADC12SHT0_8是采样保持选择位8、与 ref = 1.5V 无关? 评论错误吗?

3.(8*0x100u)= 0x800为什么这个12位宽而不是16位宽? 是否有隐含的0000b 前缀?

ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_10; // ADC i/p ch A10 =温度感测 I/p

ADC12SREF_1选择 ADC 基准1、即(1*0x10u)= 0x10、VREF+、AVSS、这是正确的吗?

 ADC12IE = 0x001;

为什么这是12位而不是16位? 是否有隐含的0000b 前缀?

6.在针对矢量6单次转换的 ISR 中、您将 ADC12MEM0用于内部温度、但是在针对矢量32的4个通道序列的 TI 示例中、您将 ADC12MEM10用于内部温度

两者上是否有温度传感器? 还是两者都应该是 ADC12MEM10?

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

    /***************************************************************************************************************
     *
     * run_430_ADC_T() for internal Temperature
     * derived from TI MSP430F55xx_adc_10.c example, reads one channel one time
     *
     **************************************************************************************************************/
    // setup and run in single temperature sensor mode
    // runs continuously for now, ultimately only need 1 value, not averaging 10 values
    void run_430_ADC_T(void)
    {
        // local strings to hold LCD data
        unsigned char string1[LCD_ROW_WIDTH];
    
        // add breakpoint to stop here on debug
        __no_operation();
    
        WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    
        /***************************************************************************************************************
        * setup ADC12 for Temperature
        **************************************************************************************************************/
    
        REFCTL0 &= ~REFMSTR;                      // REF shared reference control register
                                                  // Reset REFMSTR to hand over control to ADC12_A reference control registers, REF not used
        //ADC12CTL0 &= ~ADC12ON;                     // turn ADC off initially to clear ADC
    
        //     1111 11
        // msb 5432 1098 7654 3210 lsb
        //     0000 0000 0001 0000 = 0x0010     ADC12ON turn ADC12 on
        //     0000 0000 0010 0000 = 0x0020     ADC12REFON set reference on
        //     0000 1000 0000 0000 = 0x0800     ADC12SHT0_8 Sample Hold 0 Select Bit: 8,  (8*0x100u)
        //     ----------------------------
        //     0000 1000 0011 0000 = 0x0830     Total = ADC12CTL0 bit setting
        ADC12CTL0 = ADC12SHT0_8 + ADC12REFON + ADC12ON;     // Internal ref = 1.5V, Ref on, ADC on
    
        ADC12CTL1 = ADC12SHP;                     // enable sample timer, pulse mode, 0x0200
    
        //     1111 11
        // msb 5432 1098 7654 3210 lsb
        //     0000 0000 0000 1020 = 0x000A     ADC12INCH_10 ch A10 temperature sensor
        //     0000 0000 0001 0000 = 0x0010     ADC12SREF_1 select reference 1 (1*0x10u) = 0x10, VREF+, AVSS
        ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_10;  // ADC i/p ch A10 = temp sense i/p
    
        ADC12IE = 0x001;                          // ADC_IFG upon conv result-ADCMEMO
        // it runs with or without the loop, but don't know accuracy without precise testing - leave the loop in for now
        __delay_cycles(100);                       // delay to allow Ref to settle
        // comment out while single stepping, it bogs down here
        ADC12CTL0 |= ADC12ENC;                     // enable conversion 0x0002
    
        /***************************************************************************************************************
        * read ADC12 Temperature
        **************************************************************************************************************/
    
        while(1)
        {
            ADC12CTL0 &= ~ADC12SC;                  // ensure sampling is stopped
            ADC12CTL0 |= ADC12SC;                   // start sampling and conversion
    
            __bis_SR_register(LPM4_bits + GIE);     // LPM4 with interrupts enabled
            __no_operation();
    
            // Temperature in Celsius
            tempDegC = (float)(((long)(temp) - CALADC12_15V_30C) * (85 - 30)) / (CALADC12_15V_85C - CALADC12_15V_30C) + 30.0f;
    
            // Temperature in Fahrenheit Tf = (9/5)*Tc + 32
            tempDegF = tempDegC * 9.0f / 5.0f + 32.0f;
    
            // create string for LCD
            sprintf(temp_st, "%3.0f", tempDegF);
    
    #if(LCDADC)
            // send data to console
            printf("tempDegC = %3.2f   tempDegF = %3.2f   temp = %d\n", tempDegC, tempDegF, temp);
            //fprintf(stdout, "tempDegF = %3.1f   tempDegC = %3.1f\n", tempDegF, tempDegC);
    
            // build LCD data string
            // these are correct conversion codes, incorrect codes caused several problems
            sprintf(string1, "%3.2f     %3.2f     %d        \n", tempDegC, tempDegF, temp);
    
            // LCD data display
            LCD_put_string_4_cc(ROW10, COL0, "DEGC      DEGF      TEMP          ", black, white);
            LCD_put_string_4_cc(ROW11, COL0, "----------------------------------", black, white);
            LCD_put_string_4_cc(ROW12, COL0, string1, black, white);
    #endif
            __no_operation();                       // if desired, set breakpoint here
        }
    }
    
    
    /***************************************************************************************************************
     *
     * MSP430 ADC12 ISR - for 3 sequential ADC channels (case 32), and 1 single channel (case 6)
     *
     **************************************************************************************************************/
    // this ISR deals with two ADC functions: case 6 for single temperature
    // and case 32 for sequence of channels: voltage and two other sensors
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      // dissect ADC12IV and process single, correct interrupt vector, use last channel for a sequence
      // 2nd arg is the range, which is case value in decimal
      // case uses decimal, interrupt vector uses hex
      // example only went to case 34 for ADC12IFG14, corrected here to case 36
      switch(__even_in_range(ADC12IV,36))
      {
      case  0: break;                           // Vector  0:  No interrupt
      case  2: break;                           // Vector  2:  ADC overflow
      case  4: break;                           // Vector  4:  ADC timing overflow
      case  6:                                  // Vector  6:  ADC12IFG0, temperature
          temp = ADC12MEM0;
          __bic_SR_register_on_exit(LPM4_bits); // Exit active CPU
          break;
      case  8: break;                           // Vector  8:  ADC12IFG1
      case 10: break;                           // Vector 10:  ADC12IFG2
      case 12: break;                           // Vector 12:  ADC12IFG3
      case 14: break;                           // Vector 14:  ADC12IFG4
      case 16: break;                           // Vector 16:  ADC12IFG5
      case 18: break;                           // Vector 18:  ADC12IFG6
      case 20: break;                           // Vector 20:  ADC12IFG7
      case 22: break;                           // Vector 22:  ADC12IFG8
      case 24: break;                           // Vector 24:  ADC12IFG9
      case 26: break;                           // Vector 26:  ADC12IFG10
      case 28: break;                           // Vector 28:  ADC12IFG11
      case 30: break;                           // Vector 30:  ADC12IFG12
      case 32:                                  // Vector 32:  ADC12IFG13 - use interrupt case for last channel in sequence
          //ADC_results[i][0] = ADC12MEM10;       // Move A10 results, IFG is cleared, used in 4 channel sequence example for temperature, only 3 channel sequence used here
          ADC_results[i][0] = ADC12MEM11;       // Move A11 results, IFG is cleared
          ADC_results[i][1] = ADC12MEM12;       // Move A12 results, IFG is cleared
          ADC_results[i][2] = ADC12MEM13;       // Move A13 results, IFG is cleared
          __bic_SR_register_on_exit(LPM4_bits); // Exit active CPU, SET BREAKPOINT HERE
          break;
      case 34: break;                           // Vector 34:  ADC12IFG14
      case 36: break;                           // Vector 36:  ADC12IFG15
      default: break;
      }
    }
    
    
    

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

    手册中有详细说明。

    1) 1) ADC12ON 仅打开和关闭 ADC。 当 ADC 打开时、某些配置位无法置位。

    2) 2)使基准电压为2.5V 的位未设置、因此...

    3) 3)我在您的代码中找不到它。

    4) 4)正确。

    5) 5)我不理解问题。 除非您想知道为什么将该常量写入0x001而不是0x0001。 这并不重要、因为它们完全相同。

    6) 6) ADCMEM10上没有传感器。 这是为 ADCMCTL10控制的转换存储结果的地方。 输入将是那里选择的任何值。

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

    DS/UG 有时会有很差的描述、这些描述深得难以找到。 尽管总的来说、编写的文档非常好。

    3是来自 msp430f5638.h 头文件、与#5是相同的问题。 我不同意0x000与0x0000相同。 在第一种情况下、上半字节未定义。 现在、如果 TI 的内部代码处理这些未定义的上部半字节(在常量中)、那么这是可以的。 这是什么情况发生了、这些细节在哪里详细说明了?

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

    0是整数大小的整数常量。 16位。 0L 是一个长整数常量。 这是非常基本的 C 语言、与 MSP430无关。