TI中文支持网
TI专业的中文技术问题搜集分享网站

DSP28377D的AD采样时结果寄存器值波动很大

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

Green Deng:试一下用官方例程采样呢?比如用:C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_examples_Cpu1\adc_soc_software

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

user6107972:

回复 Green Deng:

我试了,结果还是一样的

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

mangui zhang:

回复 user6107972:

建议在AD口上外接一个1.5V的电池看看采集的数据结果变化情况

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

rookiecalf:VREFH配置的电容是否大于1uF

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

user6107972:

回复 rookiecalf:

是大于1uF的

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑

void ConfigureADC(void)
{EALLOW;//write configurationsAdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);//Set pulse positions to lateAdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;//power up the ADCsAdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;//delay for 1ms to allow ADC time to power upDELAY_US(1000);EDIS;
}


void SetupADC(void)
{Uint16 acqps;//determine minimum acquisition window (in SYSCLKS) based on resolutionIF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns}else { //resolution is 16-bitacqps = 63; //320ns}

//Select the channels to convert and end of conversion flag//ADCAEALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin A1AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin A1AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC1 will convert pin A1AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC1 will convert pin A1AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断//ADCBAdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin B1AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC1 will convert pin B1AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC1 will convert pin B1AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cyclesAdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断
}


void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
{Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trimsUint16 adcOffsetTrim; //temporary ADC offset trim//re-populate INL trimCalAdcINL(adc);if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP)){//offset trim function is programmed into OTP, so call it//calculate the index into OTP table of offset trims and call//function to return the correct offset trimadcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode;adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);}else {//offset trim function is not populated, so set offset trim to 0adcOffsetTrim = 0;}//Apply the resolution and signalmode to the specified ADC.//Also apply the offset trim and, if needed, linearity trim correction.switch(adc){case ADC_ADCA:AdcaRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCB:AdcbRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCC:AdccRegs.ADCCTL2.bit.RESOLUTION = resolution;AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdccRegs.ADCINLTRIM1 &= 0xFFFF0000;AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;case ADC_ADCD:AdcdRegs.ADCCTL2.bit.RESOLUTION = resolution;AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;if(ADC_RESOLUTION_12BIT == resolution){//12-bit linearity trim workaroundAdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;}break;}
}

/* 
* Loads INL trim values from OTP into the trim registers of the specified ADC.
* Use only as part of AdcSetMode function, since linearity trim correction
* is needed for some modes.
*/
void CalAdcINL(Uint16 adc)
{switch(adc){case ADC_ADCA:if(0xFFFF != *((Uint16*)CalAdcaINL)){//trim function is programmed into OTP, so call it(*CalAdcaINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCB:if(0xFFFF != *((Uint16*)CalAdcbINL)){//trim function is programmed into OTP, so call it(*CalAdcbINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCC:if(0xFFFF != *((Uint16*)CalAdccINL)){//trim function is programmed into OTP, so call it(*CalAdccINL)();}else {//do nothing, no INL trim function populated}break;case ADC_ADCD:if(0xFFFF != *((Uint16*)CalAdcdINL)){//trim function is programmed into OTP, so call it(*CalAdcdINL)();}else {//do nothing, no INL trim function populated}break;}
}

user6107972:

回复 mangui zhang:

试过,波动仍然很大

赞(0)
未经允许不得转载:TI中文支持网 » DSP28377D的AD采样时结果寄存器值波动很大
分享到: 更多 (0)