Post Go back to editing

ADC problem about ADUC7061

I post this problem in chinese version, but the china engineer can't give correct answer. So i want to post it here to found an more senior engineer. 

As you know, ADC1~ADC5 are single function port. but ADC6~ADC9 are mutil-function prots.

The SPI/I2C and analog can be changed.

I write code to sample analog signle from ADC4 and ADC8, ADC 4 is connected to ADC8 together.

But when i read, value from ADC4 is correct, but data from ADC8 is not correct.

When the voltage is 0.67V around. the value from ADC4 is 0x004xxxxx, but value from ADC8 is about 0x000005xx.

When i change the voltage, value from ADC8 will not change, or chage slightly. for example, 0x5ff, 0x5fe.

When i change another device(CPU chip), the value will be 0x606, 0x607.

I  deduce:

there are some bug in device. and the codes to initiate ADC1 need special sequence.

the Datasheed does not tell me what is sequence, the special sequence, so i get wrong result.

I can't find example code how to use adc6~adc9,  will anyone give correct resolution?

thanks.

I post my code here:

int main()
{
volatile signed long s;
signed char N = -1;
char Err = 0;
float fN = 0;

PLLKEY1 = 0xaa;
PLLCON = 0x00;
PLLKEY2 = 0x55;

POWKEY1 = 0x1;
POWCON0 = 0x38; // Set core to max CPU speed of 10.24Mhz
POWKEY2 = 0xF4;

POWKEY3 = 0x76;
POWCON1 = 0x024;
POWKEY4 = 0xB1;

DACCON = 0x0013;
DACDAT = 0x04ff0000;


while(1)
{

ADCCFG = 0x84;
ADCFLT = 0x8083;

GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
GP0PAR = 0x0f; //01110
GP0DAT = 0x10100000;

GP0KEY1 = 0x7;
GP0CON1 = 0x1; // adc
GP0KEY2 = 0x13;

ADC0CON = 0;
ADC1CON = 0x878c;;

s = ADCSTA;
s = ADC0DAT;
s = ADC1DAT;
//////////
ADCMDE = 0x83;
////
ADC1CON = 0x8004 | 0x0480;//ch 8
//ADC1CON = 0x800c | 0x0300;//ch 4

s = ADC1DAT;
s = ADCSTA;
ADCMDE = 0x82;
do
{
s = ADCSTA;
if (s & 0x2000) //adc1cerr
{
Err |= 1; //over range
}
} while(!(s & 0x2));

s = ADC1DAT;
ADCMDE = 0x83;

//3. exit adc
ADCMDE = 0x83; //idle
ADCFLT = 0x80ff;
ADC1CON = 0x78c; //internally shorted

GP0CON0 = 0x00001011; //back to spi
GP0PAR = 0x04;
GP0DAT = 0x10100000;

GP0KEY1 = 0x7;
GP0CON1 = 0x0; // exit adc
GP0KEY2 = 0x13;
}
}

Parents
  • Hi,

    You mentioned that CH4 is working while CH8 is not but looking at the configuration below, there is another difference. You bypass both buffer when reading from CH4. Can you try to bypass the buffer when using CH8 as well? This is just to check if we have an issue with the buffer. 

    ADC1CON = 0x8004 | 0x0480;//ch 8
    //ADC1CON = 0x800c | 0x0300;//ch 4

    Also, I think the lines below can be skipped.

    GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
    GP0PAR = 0x0f; //01110
    GP0DAT = 0x10100000;

     

    regards,

    Mark

  • I have checked it for several weeks,

    In facts, the ADC is correct. the reason to make wrong data of ADC is that the DAC will not work when P0 is configured as analogue input. the DAC will not ouput linear voltage.

    Finally, when USE jlink, device works correctly after programming, but will not work correctly after reset again by power off and on.

    when use ULINK, device work incorrectly after programming, but it will work in debug mode, run or step by step. if the devcei is resetted again by poweroff/on, the devcei will not work correctly again.

  • DACDAT = 0x8000000;
    DelayMs(10);

    sprintf ( (char*)szTemp, "ADC0 Result: %f\r",ulADC0Result*lsb10r9/1000000000 );

    this is because the ulADC0Result is used for the first report, and ulADC0Result  is used for the second report.

    So any value of ADC0 or ADC1 will be constant ( not considering noise), they will not swing.

    And you will find adc0 is about 1.0V. the value is wrong.

  • this is because the ulADC0Result is used for the first report, and ulADC1Result  is used for the second report.

  • Hi, 
    Please note that measurement through ADC6 to 9 inputs is only possible GP0CON1 = 0x1. I have checked switching between 0 and 1 value and I can still get correct measurement as long as GP0CON1 = 0x1 when doing the ADC measurement from ADC8 input. 

  • Hi,

    Please let me clarify the setup for my test:

    1. The board I used is the EVAL-ADUC7061MKZ so I can only download via UART downloader

    2. The example code that I provided configures the Primary and Auxiliary ADCs to use ADC2 and ADC8 as inputs respectively. I am using an external voltage source as an input to ADCs. No ADC is connected to any DAC, this is the reason why my result is showing a constant value even when DAC value is change. If I change the value in the voltage source then thats the time that the ADC result will change. 

    3. The DAC is configured to output zeroscale (0V) and midscale (0.6V) in a given time interval using VRef = 1.2V

    In conclusion, all the blocks are working fine even with P0 configured as an analog input. ADC8 is shared with P0.2 for ADUC7061 part and the DAC is still working as expected no spikes as reported in the original thread. 

    I will advise you to get the EVAL-ADUC7061MKZ and do your tests with this board. I am also open to reviewing your schematic and layout to see if there's anything that is causing the issue on your side. 

    regards,

    Mark

  • In your code:

    this is because the ulADC0Result is used for the first report, and ulADC1Result  is used for the second report.

    So, value of ADC1 will not swing, value ADC0 will not swing too.

    I don't know why you wave is square wave?

    Ok, I don't care the wave.

    You will find Vadc1/Vadc0 is not equal to DACDAT1/DACDAT0.  DACDAT1 is the second and DACDAT0 is the fist setting of DACDAT.

    In fact, I consider that you use wrong logic code. The C code is wrong. You can analysis your code logic carefully.

  • It is easy to test to use codes i give you last. The code is correct.

    But is don't consider your code is correct.

  • I do belive the resule is same on eval_axxxMKZ, as on my board.

    The board is simple and, very important is, it works correctly when i use jtag to download code.

    I can't belive your result, it is becuase your code is really according to your result.

    But you understand / analysis it with wrong logic.

    You are in the plight of thinking now, i sugesst you to analyse your result later.

    Whait is the spike? It is not noise spike.

    In your code ,you set DACDAT = 0x8000000 and dac output 1.0V when GP0CON1 = 0x1; in fact, it should be 0.9V, the DAC will output 0.9V when GP0CON1 = 0x0.

    So, if you change from GP0CON1 = 0x1 to GP0CON1 = 0x0, the output voltage will swing from 1.0V to 0.9V. This is spike.

    I have give you right code to test when GP0CON1 = 0x0, but why do not you try it?

    3823.Auxiliary_ADC_new.zip

    I give you this file three times.

  • In fact, you don't need use channel 6~9.

    you can  use channel 0~4.

  • int main(void)
    {
    	unsigned char i = 0;
    	unsigned char nLen = 0;
    	char SwapFlag = 0;
    	
    	float lsb10r9 = 143.0511; // 10^9 G
    	
    	POWKEY1 = 0x1;
    	POWCON0 = 0x78;		   // Set core to max CPU speed of 10.24Mhz
    	POWKEY2 = 0xF4;
    	
    	GP0KEY1 = 0x7; 
    	GP0CON1 = 0x1; 
    	GP0KEY2 = 0x13;	
    	
    	GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
    	GP0PAR = 0x0f; 				//01110
    	GP0DAT = 0x10100000;
    	
    	// Initialize the UART for 9600-8-N
    	GP1CON = BIT0 + BIT4;  // Select UART functionality for P1.0/P1.1
    	COMCON0 = BIT7;			// Enable access to COMDIV registers
    	COMDIV0 = 0x21;			// Set baud rate to 9600.
    	COMDIV1 = 0x00;
    
    	COMCON0 = BIT0 + BIT1 + BIT2;
    	COMIEN0 = BIT0 + BIT1;	 // Enable UART interrupts when Rx full and Tx buffer empty.
    	 
    	// DAC configuration
    	DACCON = 0 + 			// Rang internal Vref = 1.2V /AGND
    			 BIT4;					// Disable clearing of DACDAT + DAC is updated with falling edge of core clock
    	
    	// Configure ADC1 for continuous conversions, 1khz, ADC4 input
    
    //note by huang, i will open interrupt later
    	ADCMSKI = 0;	// Disable ADC1 result ready interrupt source
    	ADCFLT = 0x46;	
    	// Chop off, 0.1Khz samping rate, SF = 70.	No averaging
    
    //note by huang, close here, open later
    	ADCMDE = 0 + BIT1 + BIT0;	//IDLE
    	
    
    //error	
    	/*
    	note by huang:
    	error, ADC0 can't use channel 6~9
    	
    	ADC0CON = BIT8 + BIT7 	// ADC0 input channel 6 in Single-Ended mode.
    		+ BIT15;	    // Auxiliary-ADC Enabled
    									// Also, Int reference, 
    */
    	//ADC0 is useless, so close it;	
    // i will open adc1 later	
    	ADC0CON = 0;
    	ADC1CON = 0;
    	
    //note by huang:
    //error: 	this set channel 8, not channel 6;
    /*	
    	ADC1CON = BIT10 + BIT7 	// ADC1 input channel 8 in Single-Ended mode.
    		+ BIT15;	    // Auxiliary-ADC Enabled
    									// Also, Int reference, 
    */									
    	ADCCFG = 0;
    	IRQEN = BIT10 + BIT11; // Enable ADC1 and UART interrupts
    	bSendResultToUART = 0;
    	
    	while (1)
    	{
    		if (SwapFlag == 0)
    		{
    			GP0KEY1 = 0x7; 
    			GP0CON1 = 0x0; 
    			GP0KEY2 = 0x13;				
    		}
    		else
    		{
    			//adc input
    			GP0KEY1 = 0x7; 
    			GP0CON1 = 0x1; 
    			GP0KEY2 = 0x13;	
    		}
    		//for stable
    		DelayMs(1);
    		
    		DACDAT = 0x8000000;
    		//for stable
    		DelayMs(20);
    		
    		
    		bSendResultToUART = 0;
    		// open interrupt
    		ADCMSKI = BIT1; //Enable ADC1 result ready interrupt source
    		
    		//open ADC1
    		ADC1CON = BIT9 + BIT8 	// ADC1 input channel 4 in Single-Ended mode.
    		+ BIT15;	    // Auxiliary-ADC Enabled
    									// Also, Int reference, 		
    		
    		//read to clear
    		ulADC0Result = ADC0DAT;	// Read ADC0 conversion result
    		ulADC1Result = ADC1DAT;	// Read ADC1 conversion result
    		//open ADC1
    		ADCMDE = 0 + BIT1;	// single Conversion mode, Normal mode
    		
    		//wait for at least one sample
    		while (bSendResultToUART == 0)
    		{
    			DelayMs(1);
    		}
    		
    	 if (bSendResultToUART == 1) // Is there an ADC1 result ready for UART transmission?
    	 {	
    		 //if i receive one sample, then close ADC1 and interrupt for UART business.
    		 //if all uart send all text, then open them again
    		 ADC1CON = 0;
    		 ADCMSKI = 0;
    		 bSendResultToUART = 0;
    		 
    			if (SwapFlag == 1)
    			{
    				sprintf ( (char*)szTemp, "%05.3f\r ADC1(Ch4) Result(ADC input)\r",ulADC1Result*lsb10r9/1000000000 );// Send the ADC1 Result to the UART                          
    			}
    			else
    			{
    				sprintf ( (char*)szTemp, "%05.3f\r ADC1(Ch4) Result(GPIO)\r",ulADC1Result*lsb10r9/1000000000 );// Send the ADC1 Result to the UART                          
    			}
    			nLen = strlen((char*)szTemp);
    			for ( i = 0 ; i < nLen ; i++ )	// loop to send ADC1 result
    			{
    				 COMTX = szTemp[i];
    					 ucTxBufferEmpty = 0;
    				 while (ucTxBufferEmpty == 0)
    					 {
    					 }
    			}
    		}		
    	 
    		//swap for next test
    		if (SwapFlag == 0)
    		{
    			DelayMs(50);
    			SwapFlag = 1;
    		}
    		else
    		{
    			//adc input
    			DelayMs(150);
    			SwapFlag = 0;
    		}		
    		
    		
    		/*
    			
    			DACDAT = 0x0000000;
    			DelayMs(10);
    			
    			 sprintf ( (char*)szTemp, "ADC1 Result: %f\r",ulADC1Result*lsb10r9/1000000000 );// Send the ADC1 Result to the UART                          
       			nLen = strlen((char*)szTemp);
         		for ( i = 0 ; i < nLen ; i++ )	// loop to send ADC1 result
       			{
    	     		 COMTX = szTemp[i];
    	      		 ucTxBufferEmpty = 0;
    		  		 while (ucTxBufferEmpty == 0)
    	      		 {
    	      		 }
    				}
    		*/
    	}
    }

    This code just use ADC1 channel4, it will  read back DAC output when GP0CON1 = 0x0.

  • Hi.
    I am now using the code you sent and it still looks correct to me. In you code, you set the DAC to 0.6V (midscale with VRef = 1.2) and then I connected this DAC output to CH4 and just read the result from UART.  DAC is stable at 0.6V and ADC is reading 0.599V. I can't see the issue that you mentioned.

    By the way, I power cycled the board before measurement. 


Reply
  • Hi.
    I am now using the code you sent and it still looks correct to me. In you code, you set the DAC to 0.6V (midscale with VRef = 1.2) and then I connected this DAC output to CH4 and just read the result from UART.  DAC is stable at 0.6V and ADC is reading 0.599V. I can't see the issue that you mentioned.

    By the way, I power cycled the board before measurement. 


Children