View previous topic :: View next topic |
Author |
Message |
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
Read the digital value using interrupt |
Posted: Wed Mar 06, 2013 12:02 pm |
|
|
I want read the digital value from the Analogue voltage AO pin by using AD interrrupt, and print the value on the screen. The code I wrote couldn't worked and shown below, I can't find the reason, help me please! thanks a lot!!!
Code: |
#include <18F45K20.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES PROTECT //Code protected from reads
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV18
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed
Addressing mode disabled (Legacy mode)
#FUSES NODELAYINTOSC
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <adint.h>
#include <stdlib.h>
#int_AD
unsigned int8 value,ready;
void AD_isr(void)
{
value=read_adc();
ready=1;
}
void main()
{
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
//setup_pp(PMP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
do{
if(ready==1)
{printf("value=%u",value);}
}while(TRUE);
} |
Last edited by yuyljk on Wed Mar 06, 2013 1:02 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Mar 06, 2013 12:49 pm |
|
|
First you've got the Low Voltage Programming fuse enabled.It's unlikely you really wants this,so tell us what programmer you're using to download the code into the PIC.
2nd. Have you got the simple '1Hz Blinking LED' and 'Hello World' programs to run correctly? The first will confirm basic PIC operation, the 2nd communications to a PC.
3rd. You do NOT need ISR to use the ADC. Simply examine some of the CCS supplied examples( in the EXAMPLES folder) to see how easy it can be.
There are several other 'points' to consider but you must first confirm your PIC hardware is running right.
hth
jay |
|
|
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
read digital value using interrrupt |
Posted: Wed Mar 06, 2013 12:56 pm |
|
|
temtronic wrote: | First you've got the Low Voltage Programming fuse enabled.It's unlikely you really wants this,so tell us what programmer you're using to download the code into the PIC.
2nd. Have you got the simple '1Hz Blinking LED' and 'Hello World' programs to run correctly? The first will confirm basic PIC operation, the 2nd communications to a PC.
3rd. You do NOT need ISR to use the ADC. Simply examine some of the CCS supplied examples( in the EXAMPLES folder) to see how easy it can be.
There are several other 'points' to consider but you must first confirm your PIC hardware is running right.
hth
jay |
I use ccs to write the code and import to mplabx, and then load to PIC18F45K20 controller.
Before i use polling system to get the digital value correctly. Now I want use interrrupt to instead that, because if i just use do while loop to get digital value, when I power off the analogue pin, the program will be stopped as well but I need the program can be run whether powerred to the analogue pin(A0) or not.
Regards,
Hilary |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 06, 2013 1:50 pm |
|
|
Your programs has several errors and things that are less than optimum,
but this one below, prevents the interrupt from working.
You have a line of code between the #int_ad statement and the AD_isr()
function. That's not correct. There must be No Code between those
two lines.
Quote: | #int_AD
unsigned int8 value,ready;
void AD_isr(void)
{
value=read_adc();
ready=1;
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Mar 06, 2013 6:02 pm |
|
|
When you do get your code working, it'll print furiously forever once it gets a reading from the ADC.
Mike |
|
|
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
Read digital value using interrupt |
Posted: Thu Mar 07, 2013 6:43 am |
|
|
PCM programmer wrote: | Your programs has several errors and things that are less than optimum,
but this one below, prevents the interrupt from working.
You have a line of code between the #int_ad statement and the AD_isr()
function. That's not correct. There must be No Code between those
two lines.
Quote: | #int_AD
unsigned int8 value,ready;
void AD_isr(void)
{
value=read_adc();
ready=1;
} |
|
I fixed my code and received the value, but the value is incorrect and it can't change by changing the voltage from the analogue pin. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Mar 07, 2013 10:08 am |
|
|
I'll list a few of the problems:
1)
Code: |
void AD_isr(void) {
value=read_adc();
ready=1;
}
|
This triggers a _new_ ADC conversion. Doesn't take the reading already done if the interrupt has fired. As such, a waste of time....
2) What is ever going to trigger the ADC?. I think you are seriously misunderstanding the ADC, and interrupts on the PIC. To read the ADC, requires that you trigger a conversion, then wait for the conversion to finish, and read the value. The read_adc function, used without any variables, does this entire sequence. To read the ADC with an interrupt, you need to use something _else_ to trigger the conversion (normally perhaps the CCP interrupt). INT_AD then fires when the conversion completes, and the value can be read (using a different value to read_adc - read the manual). This is just about the _only_ occasion when it is worth trying to use the interrupt. If you trigger the interrupt yourself, it generally takes longer to get into and out of the interrupt handler, than just to wait for the ADC, which is why the default behaviour of the CCS code is to not use interrupts....
3) The ADC _only_ interrupts when a conversion is complete, and something else has to start the conversion. It _won't_ trigger on it's own.
4) Your code actually never calls the interrupt. Since you don't clear 'ready', it's value is indeterminate, and it is just happening to wake up as '1', so the print executes for ever.
5) Read the data sheet. Is ADC_CLOCK_INTERNAL recommended at 4MHz?.
What does this line in the data sheet mean?....
"When the device frequency is greater than 1 MHz, the FRC clock source is only recommended if the conversion will be performed during Sleep."
Are you using sleep?.
6) You have LVP enabled. 99.9% of systems _must not have this enabled_. You _must_ have pin RB5 pulled up to 5v if this option is enabled, or chip execution will be erratic.
7) Does this:
Code: |
setup_spi(SPI_SS_DISABLED);
|
Make any sense. This is _not_ the command to disable the SSP.
Probably more, but I gave up.....
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Mar 07, 2013 11:10 am |
|
|
1) Work on the KISS principle.
2) Read the forum guidelines.
3) Tell us specifically what works and what doesn't.
4) Try the CCS examples for starters, rather than cooking your own.
Mike |
|
|
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
Read digital value from the analogue pin by interrupt |
Posted: Fri Mar 08, 2013 10:11 am |
|
|
Mike Walne wrote: | 1) Work on the KISS principle.
2) Read the forum guidelines.
3) Tell us specifically what works and what doesn't.
4) Try the CCS examples for starters, rather than cooking your own.
Mike |
For now, i use the external interrupt instead of AD interrupt to read the digital value from the analogue pin. I need the value can be changed when the analogue voltage change. But it just can read correct value once, then stopped. Do I must use the ccp to trigger the interrupt, let it can change all the time by changing voltage?
If i need use the ccp, can anyone give me some idea how to use the ccp to trigger my interrupt? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Mar 08, 2013 12:32 pm |
|
|
Search the forum.
Some time ago, another user was asking how to take ADC readings at timed intervals, and I posted a complete program to do this.
Best Wishes |
|
|
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
Read digital value using interrupt |
Posted: Fri Mar 08, 2013 12:51 pm |
|
|
Ttelmah wrote: | Search the forum.
Some time ago, another user was asking how to take ADC readings at timed intervals, and I posted a complete program to do this.
Best Wishes |
Before i use polling system to get the digital value correctly. Now I want use interrrupt to instead that, because if i just use do while loop to get digital value, when I power off the analogue pin, the program will be suspended, but I need the program can be run whether powerred to the analogue pin(A0) or not. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Mar 08, 2013 12:55 pm |
|
|
Er....
The analog inputs don't care whether they have 'power' or not. The ADC can still read, it'll just read zero.
The timed code will take readings at timed intervals.
Best Wishes |
|
|
yuyljk
Joined: 06 Mar 2013 Posts: 7
|
Read digital value using interrupt |
Posted: Fri Mar 08, 2013 1:02 pm |
|
|
Ttelmah wrote: | Er....
The analog inputs don't care whether they have 'power' or not. The ADC can still read, it'll just read zero.
The timed code will take readings at timed intervals.
Best Wishes |
i have tested, when I power off the analogue pins, the program was suspended. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Mar 08, 2013 1:11 pm |
|
|
I don't see how you can 'power off the analog pins'. If you mean you switch off external circuitry attached to these pins, then what you describe does not happen. It sounds as if something in your code is possibly stopping when it sees no voltage, or something else in your PIC is getting 'powered off'.
Are you perhaps powering off the ADC Vef or possibly removing the ADC Vdd?. If the latter, this is not legal for the chip...
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Mar 08, 2013 4:25 pm |
|
|
I'm getting rather frustrated by this thread, and totally confused.
You keep moving the goal posts.
Just tell us what you are trying to do, as SIMPLY as possible.
Mike |
|
|
|