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.

DSP18377D的ADC采样后结果寄存器值波动大

如图里面所示,无论我是在ID端口输入恒定电压,还是直接在28377的A0端口输入,结果寄存器ADCRESULT0的数一直都在波动,波动值大概有100左右,偶尔还会发生突变,变成接近0或者4095,我用的是12位AD模式,用16位的话波动值更大,用示波器检测电源信号,看到电源只有几毫伏的波动,所以一直不知道是哪出问题了,下面是AD的配置程序,还望各位答疑解惑
void ConfigureADC(void) { EALLOW; //write configurations AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); //Set pulse positions to late AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; //power up the ADCs AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; //delay for 1ms to allow ADC time to power up DELAY_US(1000); EDIS; } void SetupADC(void) { Uint16 acqps; //determine minimum acquisition window (in SYSCLKS) based on resolution IF(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){ acqps = 14; //75ns } else { //resolution is 16-bit acqps = 63; //320ns } //Select the channels to convert and end of conversion flag //ADCA EALLOW; AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0 will convert pin A0 AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1 will convert pin A1 AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC1 will convert pin A1 AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC1 will convert pin A1 AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC1 will convert pin A1 AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC1 will convert pin A1 AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 //ADCB AdcbRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0 will convert pin B0 AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1 will convert pin B1 AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC1 will convert pin B1 AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC1 will convert pin B1 AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 1; //这里设置1为timer0中断,设置0为软件中断 } void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode) { Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trims Uint16 adcOffsetTrim; //temporary ADC offset trim //re-populate INL trim CalAdcINL(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 trim adcOffsetTrimOTPIndex = 4*adc + 2*resolution + 1*signalmode; adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex); } else { //offset trim function is not populated, so set offset trim to 0 adcOffsetTrim = 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 workaround AdcaRegs.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 workaround AdcbRegs.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 workaround AdccRegs.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 workaround AdcdRegs.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; } }