PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 31, 2006 2:41 pm |
|
|
Quote: | Did you mean to take all 32 readings while in the interrupt and without leaving it between each reading? |
No.
Quote: |
I gather that one cannot obtain the value read by the A/D in the interrupt routine, |
You mean the INT_EXT interrupt routine ? Yes, you can call the
read_adc() function while inside the isr.
Quote: |
but you can write the data to an array? Would the array be declared as global? |
Yes, you can write it to an array. Yes, the array would be global.
However, in your code it's apparent that you want to add each value
to a running sum, so do that instead of saving it to an array.
Quote: | Can one place an interrupt inside of another interrupt? That would allow repeated readings at the proper time without going back to the main program. |
No.
Quote: | I also gather from some earlier questions, that possibly using a timer would be a better approach? |
Don't know. Upon looking at your code, I'm not really sure what you're
doing, but apparently you want to sample a value once every 5 ms.
When you do sample it, you want to take the sample at a certain
point on the waveform, at a pre-defined time after the rising edge.
You don't really need an interrupt to do that. You could just
poll the INTF flag to see when the rising edge has been found.
Then delay for your pre-defined time and read the A/D.
Don't create an #int_ext isr. It isn't needed for this method.
Also don't enable INT_EXT interrupts. Don't enable GLOBAL
interrupts either, unless you have some other interrupt that
needs it, such as a timer.
Here is a sample program that shows how to do this.
This program isn't really complete, as it could get stuck in the
while() loop if the INTF interrupt never occurs. You really should
have a timeout that will break you out of the loop in that case.
Possibly this could be done by starting a hardware timer, and
adding a check in the while() statement for the timer interrupt
flag being set. Or, a variable that's decremented by a timer isr
could be checked to see if it has counted down to zero and thus
you have "timed out". Adding this safety feature is up to you.
The program below only demonstrates how to do your inner loop.
It doesn't include all of your other code.
Code: | #include <16F877A.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#bit INTF = 0x0B.1 // External interrupt flag
//===================================
void main()
{
int8 i;
int16 value, sum;
ext_int_edge(L_to_H);
sum = 0;
for(i = 0; i < 32; i++) // Take 32 samples
{
delay_ms(5);
clear_interrupt(INT_EXT);
while(!INTF); // Wait for rising edge
delay_us(100);
value = read_adc();
sum += value;
}
while(1);
} |
|
|