ADC interupts?
ADC interupts?
Hello
With the Analog to digital converter taking so much time in convertion is it possible to start the convertion and have an interupt wating utill adcon0 register bit 1 is done, while in the mean time the pic is doing some other calculations? If it is possible how can I do it?
With the Analog to digital converter taking so much time in convertion is it possible to start the convertion and have an interupt wating utill adcon0 register bit 1 is done, while in the mean time the pic is doing some other calculations? If it is possible how can I do it?
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello
It is quite possible to achieve this. What you need to do is work out approximatley how long the conversion takes. To do this you could start the conversion and then start the Timer0. You will need to enable interrupts for the timer0. You could say light a LED if the conversion is done when the timer times out or light another LED if the conversion is not done. This way you can tune the value you load the timer with to create a interrupt delay as close as possible to the ADC sample time.
Place this code into the Supplementary code defines window
Place this code into the Supplementary code functions window
Please note that the Sample ADC function may need editing depending on the PICmicro you are using.
Using C Code blocks
You can call the ADC routines by using a C code block with the following
In your Tmr0 Interrupt routine
C Code Block
It is quite possible to achieve this. What you need to do is work out approximatley how long the conversion takes. To do this you could start the conversion and then start the Timer0. You will need to enable interrupts for the timer0. You could say light a LED if the conversion is done when the timer times out or light another LED if the conversion is not done. This way you can tune the value you load the timer with to create a interrupt delay as close as possible to the ADC sample time.
Place this code into the Supplementary code defines window
Code: Select all
void FCD_ADC0_SampleADC(char ADC_Chan);
char FCD_ADC0_ReadAsByte();
short FCD_ADC0_ReadAsInt();
Please note that the Sample ADC function may need editing depending on the PICmicro you are using.
Code: Select all
void FCD_ADC0_SampleADC(char ADC_Chan)
{
char ta, tb, cnt;
adcon1 = 0x00;
ansel=0x7F;
ta = trisa;
tb = trisb;
#if (ADC_Chan == 0)
trisa = trisa | 0x01;
#endif
#if (ADC_Chan == 1)
trisa = trisa | 0x02;
#endif
#if (ADC_Chan == 2)
trisa = trisa | 0x04;
#endif
#if (ADC_Chan == 3)
trisa = trisa | 0x08;
#endif
#if (ADC_Chan == 4)
trisa = trisa | 0x10;
#endif
#if (ADC_Chan == 5)
trisb = trisb | 0x40;
#endif
#if (ADC_Chan == 6)
trisb = trisb | 0x80;
#endif
adconADC_Chan = 0x81 | (0 << 3);
cnt = 0;
while (cnt < 220) cnt++;
adcon0 = adcon0 | 0x04; //Start conversion
//while (adcon0 & 0x04); //Dont wait just carry on with prog
//trisa = ta;
//trisb = tb;
//ansel = 0x00;
//adcon0 = 0x80;
}
char FCD_ADC0_ReadAsByte()
{
return adresh;
}
short FCD_ADC0_ReadAsInt()
{
short iRetVal;
iRetVal = (adresh << 2);
iRetVal += (adresl >> 6);
return (iRetVal);
}
You can call the ADC routines by using a C code block with the following
Code: Select all
FCD_ADC0_SampleADC(0); //Sample ADC Channel 0
FCV_SAMPLE = FCD_ADC0_ReadAsByte(); //Store value into variable sample
C Code Block
Code: Select all
while (adcon0 & 0x04); //While ADC Still Working
trisa = ta;
trisb = tb;
ansel = 0x00; //Set I/O to digital
adcon0 = 0x80;
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
- Steve
- Matrix Staff
- Posts: 3422
- Joined: Tue Jan 03, 2006 3:59 pm
- Has thanked: 114 times
- Been thanked: 422 times
- Contact:
What you need to do is to create a custom interrupt that looks for the ADC interrupt flag (ADIF).
You will also need to write your own C code to start the ADC conversion. This can be similar to Ben's example, but does not need to be so general because you know exactly which ADC channel you are using.
In the macro that is called by the ADC interrupt, you will need to turn the ADC off and set all bits to digital i/o. You should also store the ADC result (by accessing adresh and possibly adresl and saving it to a global Flowcode variable).
Keep the ADC interrupt macro as short as possible, and deal with any ADC conversion within your main program.
You will also need to write your own C code to start the ADC conversion. This can be similar to Ben's example, but does not need to be so general because you know exactly which ADC channel you are using.
In the macro that is called by the ADC interrupt, you will need to turn the ADC off and set all bits to digital i/o. You should also store the ADC result (by accessing adresh and possibly adresl and saving it to a global Flowcode variable).
Keep the ADC interrupt macro as short as possible, and deal with any ADC conversion within your main program.
In the component macro for the ADC there are 3 options. SampleADC,ReadAsByte,ReadAsInt. I was under the impression that the SampleADC option starts the conversion and only when another macro is added to the flowchart with one of the other two options enabled will the program actually acuire the value.
Also how can I make a ADC interrupt that looks for the ADIF flag? In the custom interupt option it needs: Enabble Register, Enable Bit, Flag Register, Flag Bit. I assume that the flag register is ADIF and the Flag bit is bit 6. What goes inside the Enabble Register and Enable Bit boxes?
(Note: I am using a 18f4550 pic microcontroller and I read 2 analog values from chanels 0 and 1. the values come from a rate gyro so I must read them very often in a second.)
Sorry for all the trouble but I have only just started using Flowcode and although my questions are a bit too much, I am just a newbee
Also how can I make a ADC interrupt that looks for the ADIF flag? In the custom interupt option it needs: Enabble Register, Enable Bit, Flag Register, Flag Bit. I assume that the flag register is ADIF and the Flag bit is bit 6. What goes inside the Enabble Register and Enable Bit boxes?
(Note: I am using a 18f4550 pic microcontroller and I read 2 analog values from chanels 0 and 1. the values come from a rate gyro so I must read them very often in a second.)
Sorry for all the trouble but I have only just started using Flowcode and although my questions are a bit too much, I am just a newbee
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hi Serstel
Ok in the custom interrupt properties window you want something like this (note that these settings are for the 18F4550 PICmicro sampling ADC channel 0 - for other devices refer to their datasheet)
Custom Interrupt Name = ADC_INT
Enable Register = pie1
Enable Bit = ADIE
Flag Register = pir1
Flag Bit = ADIF
The ADC sample process is now started by using a C Code Block with the following code.
The Interrupt will sample ADC channel 0. To configure other ADC channels please refer to the device datasheet.
When the ADC has finished converting the signal the macro ADC_INTERRUPT will run. Using a C Code block add the following lines to disable the ADC, retrieve the sample data and allow proper function of the digital I/O pins.
Ok in the custom interrupt properties window you want something like this (note that these settings are for the 18F4550 PICmicro sampling ADC channel 0 - for other devices refer to their datasheet)
Custom Interrupt Name = ADC_INT
Enable Register = pie1
Enable Bit = ADIE
Flag Register = pir1
Flag Bit = ADIF
The ADC sample process is now started by using a C Code Block with the following code.
Code: Select all
char cnt = 0;
adcon1 = 0x0E; //Enable ADC0 Input(Change for different ADC Channel)
adcon2 = 0x03; //Set ADC Sample Time
trisa = trisa | 0x01; //(Change for different ADC Channel)
adcon0 = 0x01; //Switch on ADC(Change for different ADC Channel)
while (cnt <220) cnt++; //Allow ADC Capacitor to charge / discharge
adcon0 = adcon0 | 0x02; //Start Conversion Process
When the ADC has finished converting the signal the macro ADC_INTERRUPT will run. Using a C Code block add the following lines to disable the ADC, retrieve the sample data and allow proper function of the digital I/O pins.
Code: Select all
adcon1 = 0x0f; //Enable Digital I/O
adcon0 = 0x00; //Disable ADC Module
trisa = trisa & 0xFE; //Restore Tris Registers(Change for different ADC Channel)
FCV_SAMPLE = (adresh << 2);
FCV_SAMPLE += (adresl >> 6);
Last edited by Benj on Fri Jan 26, 2007 4:28 pm, edited 3 times in total.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
An example Flowcode V3 program is available from the following link
http://www.matrixmultimedia.com/software/ADC_INT.fcf
In this example program the Analogue converter is started and ended using an interrupt.
The top line of the LCD shows the output of the LCD.
The bottom line of the LCD shows the number of cycles between the ADC being started and the result being generated.
http://www.matrixmultimedia.com/software/ADC_INT.fcf
In this example program the Analogue converter is started and ended using an interrupt.
The top line of the LCD shows the output of the LCD.
The bottom line of the LCD shows the number of cycles between the ADC being started and the result being generated.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 209
- Joined: Thu Oct 19, 2006 11:46 am
- Location: Bakewell, UK
- Has thanked: 20 times
- Been thanked: 16 times
- Contact:
Benj,
Thanks for this code. I was needing to set up a custom interrupt (RS232 input), being able to use the mnemonics is a big help, as is an your example as a guide.
Serstel, The example flowcode file has C code in it and this does not simulate, the Flowcde simulator only simulates Flowcode. However, it should work when if download it to a HP-488 board (for example).
Mark
Thanks for this code. I was needing to set up a custom interrupt (RS232 input), being able to use the mnemonics is a big help, as is an your example as a guide.
Serstel, The example flowcode file has C code in it and this does not simulate, the Flowcde simulator only simulates Flowcode. However, it should work when if download it to a HP-488 board (for example).
Mark
Go with the Flow.