View previous topic :: View next topic |
Author |
Message |
Al
Joined: 13 Nov 2003 Posts: 28 Location: Belfast
|
A/D conversion and interrupt timer conflict |
Posted: Tue Feb 17, 2004 4:36 am |
|
|
I am developing code using a 16F877 chip which has an interrupt routine which interrupts every second and sets PIN_C0 high and then low. A short time after the interrupt routine is called it will read from 3 A/D channels.
The problem I am having is that the A/D conversions do not work properly when the interrupt routine is enabled. When I disable the Interrupt routine the A/D conversions work fine. I suspected they were both using the same internal clock, so I changed the interrupt routine from RTCC to Timer1, but the problem was the same.
I would be grateful if anyone has any ideas _________________ Alan Murray |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Feb 17, 2004 8:36 am |
|
|
When your timer interupts set a flag to start the ADC readings. Only take as many as you have time for then wait for a flag. |
|
|
Al
Joined: 13 Nov 2003 Posts: 28 Location: Belfast
|
|
Posted: Tue Feb 17, 2004 9:51 am |
|
|
I tried your suggestion Neutone - the problem is still present.
I have noticed that I have a second ISR (#int_rda) - when I comment this ISR out the A/D conversions work fine. Strange as I am not yet receiving any data over the RS232 link. Could it be that it does not like the presence of 2 ISRs, but works happily with a single ISR. _________________ Alan Murray |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Feb 17, 2004 10:16 am |
|
|
In your serial recieve ISR you must read the byte from the serial port. Not doing this will cause the interupt to be called repeatedly. You can fix the problem by pulling the serial input pin high. |
|
|
Guest
|
|
Posted: Tue Feb 17, 2004 10:30 am |
|
|
Sorry, I do actually have a call in the ISR to 'cmd=getch();'.
I should just clarify what I mean by 'not receiving characters'. I am not transmitting chars from PC to PIC yet. Also I have not enabled that ISR explicitly. I do however call 'enable_interrupts(GLOBAL);' |
|
|
Al
Joined: 13 Nov 2003 Posts: 28 Location: Belfast
|
|
Posted: Wed Feb 18, 2004 3:31 am |
|
|
Hi Neutone,
I am just reposting this so that you know it is from me. I didn't realise I was posting as guest the last time.
Anonymous wrote: | Sorry, I do actually have a call in the ISR to 'cmd=getch();'.
I should just clarify what I mean by 'not receiving characters'. I am not transmitting chars from PC to PIC yet. Also I have not enabled that ISR explicitly. I do however call 'enable_interrupts(GLOBAL);' |
_________________ Alan Murray |
|
|
Al
Joined: 13 Nov 2003 Posts: 28 Location: Belfast
|
|
Posted: Wed Feb 18, 2004 8:41 am |
|
|
Here is a condensed sample of the code I have been using. Although I am only reading one ADC channel, the problem remains.
NOTE: if either ISR is removed the problem goes away. So I'm thinking the problem is interrupts, timers or ADC conflicting with interrupts.
#include <16f877A.h>
#fuses HS,NOLVP,NOWDT,PUT
#use delay (clock=20000000)
#use rs232(debugger)
#define INTS_PER_SECOND 76 // ~(4000000/(4*256*256))
BYTE seconds; // A running seconds counter
BYTE int_count; // Number of interrupts left before a second has elapsed
int Flag;
int cmd;
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
disable_interrupts(GLOBAL); // For this program this is apx 76 times
if(--int_count==0) { // per second.
output_high(PIN_C0);
output_low(PIN_C0);
int_count=INTS_PER_SECOND;
Flag=1;
}
enable_interrupts(GLOBAL);
}
#int_rda
void serial_isr() {
disable_interrupts(GLOBAL);
//if(kbhit()) //this command does not solve the problem
cmd=getch();
enable_interrupts(GLOBAL);
}
main () {
int ADReading;
Flag=0;
int_count=INTS_PER_SECOND;
set_timer0(0);//checked out
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
// Initialise ADCs
setup_adc_ports( RA0_RA1_RA3_ANALOG );
setup_adc(ADC_CLOCK_INTERNAL);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
set_adc_channel(0); //using input from RA1
while(true){
if(Flag == 1){
ADReading = read_adc();
printf("AD:%03u\n", ADReading);
Flag = 0;
}
}
}// end of MAIN _________________ Alan Murray |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Wed Feb 18, 2004 9:32 am |
|
|
Change this
#int_rda
void serial_isr() {
disable_interrupts(GLOBAL);
//if(kbhit()) //this command does not solve the problem
cmd=getch();
enable_interrupts(GLOBAL);
}
To this
#int_rda
void serial_isr() {
cmd=getch();
}
Remove this line
enable_interrupts(INT_RDA);
untill you declare the serial port with #use rs232 for the hardware USART |
|
|
Al
Joined: 13 Nov 2003 Posts: 28 Location: Belfast
|
|
Posted: Thu Feb 19, 2004 6:43 am |
|
|
Aha! The problem only occurs when I use the debugger, as you implied Neutone. When I download the code and run the actual RS232 over hyperterminal it appears to work fine. _________________ Alan Murray |
|
|
|