看了用户手册ADCCTL1 寄存器 ADCCONSEQX 位是对采集顺序进行配置的,我想知道咱们这款芯片是不支持指定通道采集吗? 还是只支持序列多通道采集,如果支持序列多通道,我想用内部温度采集通道12和通道8指定最高通道12 岂不是0 -12 所有的都采集到,根本不是我想要的,求大神指导下,以下是我的代码
#include <msp430.h>
unsigned int ADC_Result[13]; // 12-bit ADC conversion result array
unsigned char i;
#define CALADC_15V_30C *((unsigned int *)0x1A1A) // Temperature Sensor Calibration-30 C // See device datasheet for TLV table memory mapping
#define CALADC_15V_85C *((unsigned int *)0x1A1C) // Temperature Sensor Calibration-High Temperature (85 for Industrial, 105 for Extended)
void Software_Trim(); // Software Trim to get the best DCOFTRIM value
#define MCLK_FREQ_MHZ 8 // MCLK = 8MHz
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
//configure clock
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM=3, DCO Range = 8MHz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
Software_Trim(); // Software Trim to get the best DCOFTRIM value
CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
// Configure ADC A8 pin
P5SEL0 |= BIT0;
P5SEL1 |= BIT0;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
ADCCTL0 |= ADCSHT_8 | ADCON; // ADCON, S&H=256 ADC clks
ADCCTL1 |= ADCSHP | ADCCONSEQ_1 | ADCSSEL_0; // ADCCLK = MODOSC; sampling timer
ADCCTL2 &= ~ADCRES; // clear ADCRES in ADCCTL
ADCCTL2 |= ADCRES_2; // 12-bit conversion results
ADCIE |= ADCIE0; // Enable ADC conv complete interrupt
// ADCMCTL0 = ADCINCH_12 | ADCINCH_8 | ADCSREF_1;
// ADCMCTL0 |= ADCINCH_12 | ADCSREF_1; // A8 ADC input select; Vref=2.5V
// Configure reference module
PMMCTL0_H = PMMPW_H; // Unlock the PMM registers
PMMCTL2 |= INTREFEN | REFVSEL_2 | TSENSOREN ; // Enable internal 2.5V reference
// PMMCTL2 |= INTREFEN | REFVSEL_2 ; // Enable internal 2.5V reference
__delay_cycles(400); // Delay for reference settling
_EINT();
while(1)
{
while(ADCCTL2 & ADCBUSY); // Wait if ADC core is active
ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start
__delay_cycles(5000);
}
}
// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
volatile float temp;
volatile float IntDegF;
volatile float IntDegC;
switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
{
case ADCIV_NONE:
break;
case ADCIV_ADCOVIFG:
break;
case ADCIV_ADCTOVIFG:
break;
case ADCIV_ADCHIIFG:
break;
case ADCIV_ADCLOIFG:
break;
case ADCIV_ADCINIFG:
break;
case ADCIV_ADCIFG:
ADC_Result[i] = ADCMEM0;
if(i == 0)
{
i =12;
temp =ADC_Result[11];
// Temperature in Celsius
// The temperature (Temp, C)=
IntDegC = (temp-CALADC_15V_30C)*(85-30)/(CALADC_15V_85C-CALADC_15V_30C)+30;
// Temperature in Fahrenheit
// Tf = (9/5)*Tc | 32
IntDegF = 9*IntDegC/5+32;
//__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
else
{
i–;
}
break;
default:
break;
}
}
void Software_Trim()
{
unsigned int oldDcoTap = 0xffff;
unsigned int newDcoTap = 0xffff;
unsigned int newDcoDelta = 0xffff;
unsigned int bestDcoDelta = 0xffff;
unsigned int csCtl0Copy = 0;
unsigned int csCtl1Copy = 0;
unsigned int csCtl0Read = 0;
unsigned int csCtl1Read = 0;
unsigned int dcoFreqTrim = 3;
unsigned char endLoop = 0;
do
{
CSCTL0 = 0x100; // DCO Tap = 256
do
{
CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
}while (CSCTL7 & DCOFFG); // Test DCO fault flag
__delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
// Suggest to wait 24 cycles of divided FLL reference clock
while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));
csCtl0Read = CSCTL0; // Read CSCTL0
csCtl1Read = CSCTL1; // Read CSCTL1
oldDcoTap = newDcoTap; // Record DCOTAP value of last time
newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value
if(newDcoTap < 256) // DCOTAP < 256
{
newDcoDelta = 256 – newDcoTap; // Delta value between DCPTAP and 256
if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim–;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}
else // DCOTAP >= 256
{
newDcoDelta = newDcoTap – 256; // Delta value between DCPTAP and 256
if(oldDcoTap < 256) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim++;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}
if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
{
csCtl0Copy = csCtl0Read;
csCtl1Copy = csCtl1Read;
bestDcoDelta = newDcoDelta;
}
}while(endLoop == 0); // Poll until endLoop == 1
CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
}
Susan Yang:
ADC12的话有4种转换模式
The ADC12 works a sequence as if the MCTL registers were a script. It first converts based on MCTL0, then MCTL1, then MCTL2 until it hits the EOS bit.
序列通道的转换由通道x开始,而序列中的最后通道y使用EOS标志。
user5707170:
回复 Susan Yang:
The ADC12 works a sequence as if the MCTL registers were a script. It first converts based on MCTL0, then MCTL1, then MCTL2 until it hits the EOS bit.
序列通道的转换由通道x开始,而序列中的最后通道y使用EOS标志。
这几句没有太明白什么意思,转换是由X开始,也就是我指定的通道了,EOS标志是什么,能不能给个参考的例子,参考下您说的MCTL 寄存器是不是ADCCTL0ADCCTL1ADCCTL2 这三个寄存器, 我想知道能不能指定其中2个或多个通道,我自己得到转换结果,非常感谢您的回复
Susan Yang:
回复 user5707170:
MSP430FR2353比较特殊,没有EOS位,您可以参考下面的说明来停止转换
若是您只是想要A8和A12的数据的话,建议您使用两个单通道转换来实现
FR2 ADC(与其他器件中的ADC12和ADC14不同)只有一个MCTL / MEM,只有一个INCH,没有DMA。它总是从INCH的高位倒数到0. 若是您还是想使用序列通道的话,您也可以尝试对通道进行全部采样并丢弃您不感兴趣的结果。
Susan Yang:
回复 user5707170:
我之前是说的一般芯片的ADC12,今天又看了下FR2 的ADC,还是有差异的