/* 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
Solved! Go to Solution.
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
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
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
Hi vikas,
please upload your project and all the related problem screenshot.
thanks!
Best Regards,
ZhangJun
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
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