MC9S08DN16 ADC interrupt

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

MC9S08DN16 ADC interrupt

Jump to solution
1,254 Views
vikassubramani
Contributor II

/* facing problem in MC9S08DN16 controller ADC interrupt.  Normal ADC works fine but when i enable the ADCSC1_AIEN = 1; and write the ISR for the interrupt ADC is acting weired some times interrupt occurs some time it does not occur not consistant and the ohter thing is also that it is skipping few instructions while executing I have included the entire code below please help */

 

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

 

void ADC_init(void);

void mode_initialization(void);

void MCU_init(void);

 

unsigned int higher, lower;

 

void main(void)

{

       unsigned char temp;

 

       EnableInterrupts;

       mode_initialization();

       MCU_init();

       ADC_init();

       while(1)

       {

              ADCSC1_ADCH = 2;  ADC 2 activated.

                        asm nop;

              ADCSC1 = ADCSC1 & 0x7f; // loading the same value to start conversion

              while(ADCSC1_COCO == 0);  // waiting till conversion is complete

              higher = ADCRH; /* IF i comment this then the execution gets struck in the while loop if i uncomment this line then some times the interrupt works and some times it does not */

              lower = ADCRL; 

       }

}

 

 

void ADC_init(void)

{

 

     

       ADCCFG_ADLPC = 0;          // High Speed Configuration

       ADCCFG_ADIV = 2;           // Input clock/4    

       ADCCFG_ADLSMP = 0;         // Short sample time

       ADCCFG_MODE = 2;           // 10 bit conversion

       ADCCFG_ADICLK = 0;         // bus clock selected

     

       ADCSC2_ADTRG = 0;          // Software trigger selected

       ADCSC2_ACFE = 0;           // Compare function disable

     

       ADCSC1_AIEN = 1;           // Conversion complete interrupt enable

       ADCSC1_ADCO = 0;           // Continuous conversion disable

 

       APCTL1_ADPC0 = 1;          // AD0 pin I/O control enable

       APCTL1_ADPC1 = 1;          // AD1 pin I/O control enable

       APCTL1_ADPC2 = 1;          // AD2 pin I/O control enable

       APCTL1_ADPC3 = 1;          // AD3 pin I/O control enable

       APCTL1_ADPC4 = 1;          // AD4 pin I/O control enable

       APCTL1_ADPC5 = 1;          // AD5 pin I/O control enable

}

/* fucntion to activate external oscilltor */

 

void mode_initialization(void)

{

       /* Transition from FEI mode to FBE mode */

       SOPT1_COPT = 0; // watch dog timer turn off

       MCGC2 = 0x36;

       while (MCGSC_OSCINIT == 0);

       asm SEI;  // Disables all interrupt

       MCGC1 = 0xB8;

       while(MCGSC_IREFST == 1);

       while(!(MCGSC_CLKST == 2));

     

       /* Transition from FBE mode into BLPE mode */

     

       MCGC2 = 0x3E;

       asm CLI;  // Enabled interrupt   

       MCGC1 = 0x98;

       MCGC3 = 0x44;

       while (MCGSC_PLLST == 0);

     

       /* BLPE mode transitions into PBE mode: */

     

       MCGC2_LP = 0;

       while(MCGSC_LOCK == 0);

     

}

 

 

void MCU_init(void)

{

        SOPT1_COPT = 0;

 

        SRS = 0xFF; // Clears watch dog timer

        SPMSC1 = 0x1C;                                     

        /* SPMSC2: LVWF=0,LVWACK=0,LVDV=0,LVWV=0,PPDF=0,PPDACK=0,PDC=0,PPDC=0 */

        SPMSC2 = 0x00;                                     

        /* ICGC1: RANGE=1,REFS=0,CLKS1=0,CLKS0=0,OSCSTEN=1 */

        /* Common initialisation of the CPU registers */

         /* PTASE: PTASE7=0,PTASE6=0,PTASE5=0,PTASE4=0,PTASE3=0,PTASE2=0,PTASE1=0,PTASE0=0 */

         PTASE = 0x00;                                     

         /* PTBSE: PTBSE7=0,PTBSE6=0,PTBSE5=0,PTBSE4=0,PTBSE3=0,PTBSE2=0,PTBSE1=0,PTBSE0=0 */

         PTBSE = 0x00;                                     

         /* PTCSE: PTCSE7=0,PTCSE6=0,PTCSE5=0,PTCSE4=0,PTCSE3=0,PTCSE2=0,PTCSE1=0,PTCSE0=0 */

         PTCSE = 0x00;                                     

         /* PTDSE: PTDSE7=0,PTDSE6=0,PTDSE5=0,PTDSE4=0,PTDSE3=0,PTDSE2=0,PTDSE1=0,PTDSE0=0 */

         PTDSE = 0x00;                                     

         /* PTESE: PTESE7=0,PTESE6=0,PTESE5=0,PTESE4=0,PTESE3=0,PTESE2=0,PTESE1=0,PTESE0=0 */

         PTESE = 0x00;                                     

         /* PTFSE: PTFSE7=0,PTFSE6=0,PTFSE5=0,PTFSE4=0,PTFSE3=0,PTFSE2=0,PTFSE1=0,PTFSE0=0 */

         PTFSE = 0x00;                                     

         /* PTGSE: PTGSE7=0,PTGSE6=0,PTGSE5=0,PTGSE4=0,PTGSE3=0,PTGSE2=0,PTGSE1=0,PTGSE0=0 */

         PTGSE = 0x00;                                     

         /* ### Init_COP init code */

       //   SRS = 0xFF;                          /* Clear WatchDog counter */

 

}

 

interrupt 23 void Vadc_isr (void)

{

       higher = ADCRH;

            asm nop;

       lower = ADCRL;

            asm nop;

}

Original Attachment has been moved to: ADC4.zip

Labels (1)
0 Kudos
Reply
1 Solution
1,089 Views
ankur_kala
NXP Employee
NXP Employee

Hi Vikas,

Just to explain my point further, You are polling for the COCO bit in your while loop and the same flag generates the ISR. So in effect you are doing operations in while loop that you must be doing in the ISR. To initiate a conversion you must pass the channel value in ADCSC1 register just before while loop and then move all your while(1) code in the ISR. You can then either keep the delay loop or not, it wont affect your ISR operation. Hope this ends your problem.

Please mark the answer as helpful or correct if it helps you.


Regards,

Ankur

View solution in original post

0 Kudos
Reply
5 Replies
1,089 Views
ankur_kala
NXP Employee
NXP Employee

Hi Vikas,

I would advice you to move your while(1) routine to ADC ISR. This should solve your issue.

Please mark the answer as helpful or correct if it helps you. :smileyhappy:

Regards,

Ankur

1,089 Views
vikassubramani
Contributor II

Thanks for your reply in responce to your sugestion if I move the routine in while(1) to ADC ISR  then it will not function since this is software generated interrupt i will have to load values ADCSC1 for the conversion to begin hence I activated ADC 2 by  ADCSC1_ADCH = 2;  and then began the start of conversion by loading the value to ADCSC1 as ADCSC1 = ADCSC1 & 0x7f; // loading the same value to start conversion


I have included the modified code here please take a look at comments as i have deleted a few lines in the new code.

while(1)

       {

              ADCSC1_ADCH = 2;  ADC 2 activated.

                         ADCSC1 = ADCSC1 & 0x7f; // loading the same value to start conversion

                                while(ADCSC1_COCO == 0);  /* I commented this line because when COCO is 1 interrupt generates hence it is jumping to ISR and when it comes back from ISR then COCO will be 0 so code is getting stuck at this point */

              higher = ADCRH; /* I removed this line in the new code */

              lower = ADCRL; /* I removed this line in the new code */

               delay(); /* Included this small delay function if I remove this then the code is not entering the ISR it will remain in the while(1) loop forever. I also tried adding asm nop; but no use.

       }

}

I changed the interrupt function like shown below

interrupt 23 void Vadc_isr (void)

{

       higher = ADCRH;

       lower = ADCRL;

       if(higher)

       {

            asm nop;

            num++;

       }

       else

            asm nop;

}

Note :- now the problem that i am facing is that in run mode i am able to get the result but in step by step mode code is not executing step by step. what is happening is that after i load the value to ADCSC1 to start conversion the PC it is going into delay function execute little then will jump to ISR then again jump back to delay execute fully and will go to while loop.

Thanks

-vikas

0 Kudos
Reply
1,089 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi vikas,

please upload your project and all the related problem screenshot.

thanks!

Best Regards,

ZhangJun

0 Kudos
Reply
1,089 Views
vikassubramani
Contributor II

Thanks ZhangJun  for your reply I have included the attachtment in the main thread i have made a few changes which is explained below

I have included the modified code here please take a look at comments as i have deleted a few lines in the new code.

while(1)

       {

              ADCSC1_ADCH = 2;  ADC 2 activated.

                         ADCSC1 = ADCSC1 & 0x7f; // loading the same value to start conversion

                                while(ADCSC1_COCO == 0);  /* I commented this line because when COCO is 1 interrupt generates hence it is jumping to ISR and when it comes back from ISR then COCO will be 0 so code is getting stuck at this point */

              higher = ADCRH; /* I removed this line in the new code */

              lower = ADCRL; /* I removed this line in the new code */

               delay(); /* Included this small delay function if I remove this then the code is not entering the ISR it will remain in the while(1) loop forever. I also tried adding asm nop; but no use.

       }

}

I changed the interrupt function like shown below

interrupt 23 void Vadc_isr (void)

{

       higher = ADCRH;

       lower = ADCRL;

       if(higher)

       {

            asm nop;

            num++;

       }

       else

            asm nop;

}

Note :- now the problem that i am facing is that in run mode i am able to get the result but in debug single step mode code is not executing step by step. what is happening is that after i load the value to ADCSC1 to start conversion the PC it is going into delay function execute little then will jump to ISR then again jump back to delay execute fully and will go to while loop.

I did not post any pics because i am not getting any warnign or error message just that the PC is not executing as supposed to

Thanks

-vikas

0 Kudos
Reply
1,090 Views
ankur_kala
NXP Employee
NXP Employee

Hi Vikas,

Just to explain my point further, You are polling for the COCO bit in your while loop and the same flag generates the ISR. So in effect you are doing operations in while loop that you must be doing in the ISR. To initiate a conversion you must pass the channel value in ADCSC1 register just before while loop and then move all your while(1) code in the ISR. You can then either keep the delay loop or not, it wont affect your ISR operation. Hope this ends your problem.

Please mark the answer as helpful or correct if it helps you.


Regards,

Ankur

0 Kudos
Reply