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.
在定制 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无关。