MCF52233 ADC INTERRUPT????????????

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

MCF52233 ADC INTERRUPT????????????

3,038 Views
osanz
Contributor I
Hi;
 
I'm not able to have ANY kind of ADC interrupt on coldfire MCF52233 processor.
 
Here is the init code for ADC's:

void ColdfireADCInit( WORD clockDivisor, BYTE interruptEnable )
{
                    
//GPIO config.
MCF_GPIO_PANPAR  = 0xFF;      //COMO ADC                    
                      
MCF_ADC_POWER = 0x00D4;
MCF_ADC_CTRL2 = ( clockDivisor & 0x001F );                       
                   
 if( interruptEnable )
 {
 MCF_ADC_CTRL1 = 0x2802;     
 }
 else
 {
 MCF_ADC_CTRL1 = 0x2002;
 }
 MCF_ADC_ADSTAT = 0x1800;
}

The other interrupt config are ok since i have tested it by forcing these interrupts BY INTFRCHn registers.

Does any of you achieved to have ADC interrupts??? Because most of the examples i found are based on pooling....

Thank's in advance;

Labels (1)
0 Kudos
Reply
2 Replies

964 Views
Technoman64
Contributor III
I have been using ATD interrupt with MCF52223 mcu. I used CFInt software available from Freescale website to create the initialization code. I have found this to be a very helpful application.
 
I am using 80Mhz external clock in this example. You will need to change divisor values to work with your clock.
 
First off, initialize ATD
Code:
    /* Pin assignments for port AN            Pin AN7 : Battery voltage            Pin AN6 : Oil Psi            Pin AN5 : Analog Input2            Pin AN4 : Analog Input1            Pin AN3 : Water Temp            Pin AN2 : GPIO output, initially logic '0'            Pin AN1 : GPIO output, initially logic '0'            Pin AN0 : GPIO output, initially logic '0'     */    MCF_GPIO_PORTAN = 0;    MCF_GPIO_DDRAN = MCF_GPIO_DDRAN_DDRAN2 |                     MCF_GPIO_DDRAN_DDRAN1 |                     MCF_GPIO_DDRAN_DDRAN0;    MCF_GPIO_PANPAR = MCF_GPIO_PANPAR_PANPAR7 |                      MCF_GPIO_PANPAR_PANPAR6 |                      MCF_GPIO_PANPAR_PANPAR5 |                      MCF_GPIO_PANPAR_PANPAR4 |                      MCF_GPIO_PANPAR_PANPAR3;/********************************************************************** init_adc - Analog-to-Digital Converter (ADC)                       ***********************************************************************/static void init_adc (void){   /* Scan mode = Triggered sequential        ADC clock frequency = 2.00 MHz        Voltage reference supplied by VREFH and VREFL                 The following interrupt source are enabled:            End-of-Scan A                 Sample list:            Sample 0 : AN3                       Low limit = $000, High limit = $FFF, Offset = $000            Sample 1 : AN4                       Low limit = $000, High limit = $FFF, Offset = $000            Sample 2 : AN5                       Low limit = $000, High limit = $FFF, Offset = $000            Sample 3 : AN6                       Low limit = $000, High limit = $FFF, Offset = $000            Sample 4 : AN7                       Low limit = $000, High limit = $FFF, Offset = $000            Sample 5 : Disabled            Sample 6 : Disabled            Sample 7 : Disabled     */    /* Initialise LOLIM, HILIM and OFFST registers of enabled channels: */    MCF_ADC_ADLLMT0 = 0;    MCF_ADC_ADHLMT0 = MCF_ADC_ADHLMT_HLMT(0xfff);    MCF_ADC_ADOFS0 = 0;    MCF_ADC_ADLLMT1 = 0;    MCF_ADC_ADHLMT1 = MCF_ADC_ADHLMT_HLMT(0xfff);    MCF_ADC_ADOFS1 = 0;    MCF_ADC_ADLLMT2 = 0;    MCF_ADC_ADHLMT2 = MCF_ADC_ADHLMT_HLMT(0xfff);    MCF_ADC_ADOFS2 = 0;    MCF_ADC_ADLLMT3 = 0;    MCF_ADC_ADHLMT3 = MCF_ADC_ADHLMT_HLMT(0xfff);    MCF_ADC_ADOFS3 = 0;    MCF_ADC_ADLLMT4 = 0;    MCF_ADC_ADHLMT4 = MCF_ADC_ADHLMT_HLMT(0xfff);    MCF_ADC_ADOFS4 = 0;    /* Initialise ADC */    MCF_ADC_ADZCC = 0;    MCF_ADC_ADLST1 = MCF_ADC_ADLST1_SAMPLE3(0x6) |                     MCF_ADC_ADLST1_SAMPLE2(0x5) |                     MCF_ADC_ADLST1_SAMPLE1(0x4) |                     MCF_ADC_ADLST1_SAMPLE0(0x3);    MCF_ADC_ADLST2 = MCF_ADC_ADLST2_SAMPLE7(0x7) |                     MCF_ADC_ADLST2_SAMPLE6(0x6) |                     MCF_ADC_ADLST2_SAMPLE5(0x5) |                     MCF_ADC_ADLST2_SAMPLE4(0x7);        MCF_ADC_ADSDIS = MCF_ADC_ADSDIS_DS7 |                     MCF_ADC_ADSDIS_DS6 |                     MCF_ADC_ADSDIS_DS5;        MCF_ADC_CAL = 0x0;        MCF_ADC_CTRL1 = MCF_ADC_CTRL1_STOP0   |        MCF_ADC_CTRL1_SYNC0      |                    MCF_ADC_CTRL1_EOSIE0     |                    MCF_ADC_CTRL1_SMODE(0x4);                        MCF_ADC_CTRL2 = MCF_ADC_CTRL2_DIV(0x9);    /* Power up ADC converter(s) in use */ MCF_ADC_POWER = MCF_ADC_POWER_PUDELAY(0xd) |                    MCF_ADC_POWER_PD2;    /* Wait for converter A power up to complete */    while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS0)     ;       /* Wait for converter B power up to complete */    while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS1)     ;}

 
Start conversion sequence, every .05 second for my application
Code:
 /* Enter task loop */     while (TRUE) {      if(!AnalogActiveFlag && !TimeoutFlag)     {   MCF_ADC_CTRL1 = MCF_ADC_CTRL1_SYNC0      |                      MCF_ADC_CTRL1_EOSIE0     |                      MCF_ADC_CTRL1_SMODE(0x4);            /* Start ATD conversion */      MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0;    /* Set analog active flag */   AnalogActiveFlag = TRUE;     }             /* Wait for another .05 second */  OSTimeDly(5); }

 
Finally the ATD conversion complete interrupt. This code will take ANALOG_SAMPLE_COUNT number of samples and calc the average. For my application 20 samples. Also the 12-bit result is shifted to make a 10-bit result. I use 1024 entry lookup tables. Note the result registers are 16-bit with the 12-bit result left justified in the result register with sign bit. This is why it is shifted 5 bits to get 10-bit result. See referance manual for more details on this.
Code:
/* ATD conversion complete interrupt */void AtdInterrupt(void) { /* Clear interrupt flag */ MCF_ADC_ADSTAT = MCF_ADC_ADSTAT_EOSI0; /* Get current conversion results */ WaterTempResult += MCF_ADC_ADRSLT0 >> 5; AnalogInput2Result += MCF_ADC_ADRSLT1 >> 5; AnalogInput1Result += MCF_ADC_ADRSLT2 >> 5; OilPsiResult += MCF_ADC_ADRSLT3 >> 5; BatteryVoltageResult += MCF_ADC_ADRSLT4 >> 5;  /* Increment sample count */ AnalogInCount++;  /* Sample array full— */ if(AnalogInCount >= ANALOG_SAMPLE_COUNT) {  /* Reset AnalogInCount */   AnalogInCount = 0;  /* Get conversion results */  WaterTempBinary = WaterTempResult / ANALOG_SAMPLE_COUNT;  AnalogInput2Binary = AnalogInput2Result / ANALOG_SAMPLE_COUNT;  AnalogInput1Binary = AnalogInput1Result / ANALOG_SAMPLE_COUNT;  OilPsiBinary = OilPsiResult / ANALOG_SAMPLE_COUNT;  BatteryVoltageBinary = BatteryVoltageResult / ANALOG_SAMPLE_COUNT;  /* Clear analog in results */  WaterTempResult = 0;  AnalogInput2Result = 0;  AnalogInput1Result = 0;  OilPsiResult = 0;  BatteryVoltageResult = 0; } /* Clear analog active flag */ AnalogActiveFlag = FALSE;}

 
Thsi may not be the best way to use the interrupt driven ATD, however, it works well for me.
 
Hope this helps...
0 Kudos
Reply

964 Views
osanz
Contributor I
Technoman64;
 
Thanks a lot for your help.
I'm still working on it, but your example has been very usefull.
0 Kudos
Reply