MCF52259 Demo Board Continous ADC.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF52259 Demo Board Continous ADC.

2,648 Views
FWFan
Contributor III

Hi All,

 

Can you help to see what I have been doing wrong?  I have tried for awhile now but still do not have any success.  I am trying to do a continous adc sampling of just the first channel.  I then scoop the samples every once in awhile.  So far I can get 128 samples, but the numbers do not represent a sine wave I am trying to get.  They seem like random numbers, but they do stay within the high and low limits of the adc output.  My divider is 0x1F to get the lowest sampling rate.  I think my system frequency is 80 MHz.  I am also using the samples as unsigned, so I do not do any special offseting.  I just use the result as is.

 

Thank you,

FWFan

 

void gpio_init(void) {

    /* Enable the proper UART pins */
    switch (TERMINAL_PORT)
    {
        case 2:
            MCF_GPIO_PUCPAR = 0
                | MCF_GPIO_PUCPAR_URXD2_URXD2
                | MCF_GPIO_PUCPAR_UTXD2_UTXD2;
            break;
        case 1:
            MCF_GPIO_PUBPAR = 0
                | MCF_GPIO_PUBPAR_URXD1_URXD1
                | MCF_GPIO_PUBPAR_UTXD1_UTXD1;
            break;
        case 0:
        default:
            MCF_GPIO_PUAPAR = 0
                | MCF_GPIO_PUAPAR_URXD0_URXD0
                | MCF_GPIO_PUAPAR_UTXD0_UTXD0;
    }
  
  /* PANPAR: PANPAR0=1, assumes adc primary function */
  /* this code dosn't seem to effect the functioning. */
  MCF_GPIO_PANPAR |= (unsigned char)0x01;

}

 

void adc_init(void)
{
 /* ### Init_ADC init code */
  /* CTRL1: STOP0=1,START0=0,SYNC0=1,EOSIE0=0,ZCIE=0,LLMTIE=0,HLMTIE=0,CHNCFG=0,SMODE=2 */
  MCF_ADC_CTRL1 = 0x5002U;                           
  /* CTRL2: DIV=0x1F */
  MCF_ADC_CTRL2 = (unsigned short int)((MCF_ADC_CTRL2 & (unsigned short int)~0x87C0) | 0x1FU);    
  /* ADSDIS: DS7=1,DS6=1,DS5=1,DS4=1,DS3=1,DS2=1,DS1=1,DS0=0 */
  MCF_ADC_ADSDIS = 0xfcU/*FeU*/;                           
  /* ADSTAT: CIP0=0,CIP1=0,EOSI1=1,EOSI0=1,ZCI=0,LLMTI=0,HLMTI=0,RDY7=0,RDY6=0,RDY5=0,RDY4=0,RDY3=0,RDY2=0,RDY1=0,RDY0=0 */
  MCF_ADC_ADSTAT = 0x1800U;                           
  /* ADLSTAT: HLS7=1,HLS6=1,HLS5=1,HLS4=1,HLS3=1,HLS2=1,HLS1=1,HLS0=1,LLS7=1,LLS6=1,LLS5=1,LLS4=1,LLS3=1,LLS2=1,LLS1=1,LLS0=1 */
  MCF_ADC_ADLSTAT = 0xFFFFU;                           
  /* ADZCSTAT: ZCS7=1,ZCS6=1,ZCS5=1,ZCS4=1,ZCS3=1,ZCS2=1,ZCS1=1,ZCS0=1 */
  MCF_ADC_ADZCSTAT = 0xFFU;                           
  /* ADLLMT0: LLMT=0 */
  MCF_ADC_ADLLMT0 = 0x00U;                           
  /* ADLLMT1: LLMT=0 */
  MCF_ADC_ADLLMT1 = 0x00U;                           
  /* ADLLMT2: LLMT=0 */
  MCF_ADC_ADLLMT2 = 0x00U;                           
  /* ADLLMT3: LLMT=0 */
  MCF_ADC_ADLLMT3 = 0x00U;                           
  /* ADLLMT4: LLMT=0 */
  MCF_ADC_ADLLMT4 = 0x00U;                           
  /* ADLLMT5: LLMT=0 */
  MCF_ADC_ADLLMT5 = 0x00U;                           
  /* ADLLMT6: LLMT=0 */
  MCF_ADC_ADLLMT6 = 0x00U;                           
  /* ADLLMT7: LLMT=0 */
  MCF_ADC_ADLLMT7 = 0x00U;                           
  /* ADHLMT0: HLMT=0x0FFF */
  MCF_ADC_ADHLMT0 = 0x7FF8U;                           
  /* ADHLMT1: HLMT=0x0FFF */
  MCF_ADC_ADHLMT1 = 0x7FF8U;                           
  /* ADHLMT2: HLMT=0x0FFF */
  MCF_ADC_ADHLMT2 = 0x7FF8U;                           
  /* ADHLMT3: HLMT=0x0FFF */
  MCF_ADC_ADHLMT3 = 0x7FF8U;                           
  /* ADHLMT4: HLMT=0x0FFF */
  MCF_ADC_ADHLMT4 = 0x7FF8U;                           
  /* ADHLMT5: HLMT=0x0FFF */
  MCF_ADC_ADHLMT5 = 0x7FF8U;                           
  /* ADHLMT6: HLMT=0x0FFF */
  MCF_ADC_ADHLMT6 = 0x7FF8U;                           
  /* ADHLMT7: HLMT=0x0FFF */
  MCF_ADC_ADHLMT7 = 0x7FF8U;                           
  /* ADOFS0: OFFSET=0 */
  MCF_ADC_ADOFS0 = 0x00U;                           
  /* ADOFS1: OFFSET=0 */
  MCF_ADC_ADOFS1 = 0x00U;                           
  /* ADOFS2: OFFSET=0 */
  MCF_ADC_ADOFS2 = 0x00U;                           
  /* ADOFS3: OFFSET=0 */
  MCF_ADC_ADOFS3 = 0x00U;                           
  /* ADOFS4: OFFSET=0 */
  MCF_ADC_ADOFS4 = 0x00U;                           
  /* ADOFS5: OFFSET=0 */
  MCF_ADC_ADOFS5 = 0x00U;                           
  /* ADOFS6: OFFSET=0 */
  MCF_ADC_ADOFS6 = 0x00U;                           
  /* ADOFS7: OFFSET=0 */
  MCF_ADC_ADOFS7 = 0x00U;                           
  /* ADZCC: ZCE7=0,ZCE6=0,ZCE5=0,ZCE4=0,ZCE3=0,ZCE2=0,ZCE1=0,ZCE0=0 */
  MCF_ADC_ADZCC = 0x00U;                           
  /* ADLST1: SAMPLE3=3,SAMPLE2=2,SAMPLE1=1,SAMPLE0=0 */
  MCF_ADC_ADLST1 = 0x3210U;                           
  /* ADLST2: SAMPLE7=7,SAMPLE6=6,SAMPLE5=5,SAMPLE4=4 */
  MCF_ADC_ADLST2 = 0x7654U;                           
  /* CAL: SEL_VREFH=0,SEL_VREFL=0 */
  MCF_ADC_CAL = 0x00U;                           
  /* POWER: ASB=0,PSTS2=0,PSTS1=0,PSTS0=0,PUDELAY=0x0D,APD=0,PD2=1,PD1=1,PD0=0 */
  MCF_ADC_POWER = 0xD6U;                           
  /* CTRL1: STOP0=0,START0=0 */
  MCF_ADC_CTRL1 &= (unsigned short int)~0x6000; 
  MCF_ADC_POWER &= ~(MCF_ADC_POWER_PD0 | MCF_ADC_POWER_PD1 | MCF_ADC_POWER_PD2);
 // power-up converter A, converter B and voltage reference circuit

 while (MCF_ADC_POWER & (MCF_ADC_POWER_PSTS0 | MCF_ADC_POWER_PSTS1 | MCF_ADC_POWER_PSTS2))
 {}; // stay here as long as converter A, B and voltage reference circuit are power-down             
}

 

I start the conversion and let it go forever. 

void startAdc(void)
{
 /* write 1 to START0 to initiate conversion */
 MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0/*(uint16)0x2000*/; 
}

This is how I scoop the samples.

uint16 *adcArryPtr(void)
{
 uint16 i; 
 static uint16 adcRes[ARRAYSIZE];
 
 for(i=0; i<ARRAYSIZE; i++){
    *(adcRes+i) = (uint16)MCF_ADC_ADRSLT0;
 }
 
 return adcRes;
}

 

This is how I set up and initialize the adc.

void __initialize_hardware(void)
{

 asm
 {
     /* Initialize IPSBAR */
     move.l  #__IPSBAR,d0
     andi.l  #0xC0000000,d0 // need to mask
     add.l   #0x1,d0
     move.l  d0,0x40000000

    

     /* Initialize FLASHBAR */
     move.l  #__FLASHBAR,d0
     andi.l  #0xFFF80000,d0 // need to mask
     add.l   #0x61,d0
     movec   d0,FLASHBAR

 }

 pll_init();
 gpio_init();
 adc_init();
 allow_interrupts();
 
 initialize_exceptions();
}

Labels (1)
0 Kudos
9 Replies

934 Views
ipa
Contributor III

Hi,

If you  need to see samples as a sine-wave you must start

the ADC at regular time intervals = sine_period/Number_of_samples

and stop afer the aquisition of all samples and then process them.

Depending on application, you must take into account also the need

to use an anti-aliasing filter.

 

Regards,

ipa

0 Kudos

934 Views
FWFan
Contributor III

Thank you Ipa.  That gives me an idea of using ISR to start and stop the adc.  I was going to use dsp to filter this signal actually.  But do you think I also need to use the anti-aliasing filter anyway before that?  In the past, I used the 8-bit microcontroller and I was able to get the sine wave samples okay.  But with this micro, I could not see any remnants of a sine wave at all.  I am injecting the signal directly from a function generator.  I guess basically I need to see the sine wave before I do any further modification to the program.

 

Thank you again.

FWFan 

0 Kudos

934 Views
ipa
Contributor III

Hi,

Depends also on application: if your signal is pure sine of variable frequency you can measure the frequency and then finding suitable variable sampling time; if the signal is composite, all sampling theory apply and you need anti-aliasing filter + sampling at least twice the highest frequency in spectrum (this is the case for dsp filtering - and in this case you need a good filter simulation first and no need to see sine samples).

Regards,

ipa

0 Kudos

934 Views
FWFan
Contributor III

Hi Ipa,

 

I understand your thoughts and will persue those in the near future.  I know there are lots to be done with dsp tasks.  But my problem right now is just trying to get the adc samples from the micro.  I don't think what I am getting back is correct.  They just seem to be random  samples; right now I am just injecting a pure sine wave from the function generator.  I just get a string of samples that are the same, for example, 30 samples of the same number.

 

Thank you so far for your help.

FWFan

0 Kudos

934 Views
ipa
Contributor III

Hi,

It is possible that your sampling rate to be too high, so 

30 samples with same number could be normal. To verify 

yourself, try to increase the signal frequency around 160KHz;

if you still get same number then something must be wrong in

your code. At this frequency 30 samples must describe a sine

shape. Check yourself: supposing the sample rate is 5MHz (200ns

time interval) then 30 samples X 200ns = 6 microseconds  for

sinal period (~160KHz). Use an oscilloscope and check the 

waveform right on the ADC input pin.

Regards,

ipa

0 Kudos

934 Views
FWFan
Contributor III

Hi Ipa,

 

You were correct.  I increased the ac signal frequencies and I did see the sine wave and square wave.  The square wave was pretty good but the sine wave is still a staircase.  Now I need to increase the sampling samples.  This introduces a new problem with the user-ram variable.  In any case, thank you for your help so far.

 

FWFan

0 Kudos

934 Views
All4Know
Contributor I

Hello,

 

I'm happy for you that your SW works now :smileyhappy: in fact i'm starting with a project in which i need to set up ADC and to get 16 samples every 0.5 us. Can you provide me your project to not start from 0?

my email is: barhoum-1-2-3@hotmail.com

 

thanks you

0 Kudos

933 Views
FWFan
Contributor III

Hi All4Know,

 

Sorry I couldn't get back to you sooner.  I was very busy.  I am enclosing three files that I think will show you how I initialize the ADC and how I use it.  I basically turn on the adc continously and capture the results.  I think I turn it off when I don't need to use it.   I use a pointer to point to the adc array.  If you need more files, I can send you some more.  I hope this help.

 

Good luck.,

FWFan

0 Kudos

934 Views
FWFan
Contributor III

Hi Ipa,

 

That's what I thought before too.  But I don't think that's the problem.  I have my sampling rate at the slowest possible.  I change my code a bit to poll for the EIS0 flag then capture the inputs.  This gives me different sample for each read.  I am also trying a dc signal for starter instead of the sine wave.  My reading seems to be correct.  I also discover that I translate the adc reading to the LCD  incorrectly.  I think this is why I cannot see the sine wave.  So I need to redo my translating codes.  I will keep you updated as I get this fixed.  I hope this is the problem.

 

Thank you for your help.

FWFan

0 Kudos