View previous topic :: View next topic |
Author |
Message |
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
12F675 ADC input on AN3 input not recognized |
Posted: Mon Feb 11, 2013 5:43 pm |
|
|
Hello all,
I have a simple system that uses the PIC12F675.
And compiler version V.103
The board has three output on GP0, GP1 and GP2.
I have a switch that goes between 1.9V, 2.9V, 3.9V and 4.9V coming in on GP4 (Analog Pin 3)
I have stripped down the program to simply look at the signal on Analog Pin 3 and turn on the GP0, GP1, GP2 or GP1 and GP3 depending on the Analog Input Value.
The problem is that no matter what the switch setting is the program always acts like it is getting 1.9V or less.
Any help would be greatly appreciated.
Below is the program.
Code: |
/* This program is for the the "C" choir light control
PORTA.0 = Digital Output - Output3
PORTA.1 = Digital Output - Output2
PORTA.2 = Digital Output - Output1
PORTA.3 = MCLR
*/
#include <12f675.h>
#fuses NOWDT,PROTECT,MCLR,PUT,NOBROWNOUT,INTRC_IO
#use delay(clock = 4000000)
#define Output3 PIN_A0
#define Output2 PIN_A1
#define Output1 PIN_A2
#define Switch PIN_A5
int16 temp_ad; // Temporary AD Result
#separate
void read_switches() // Get current adc value
{
SETUP_ADC_PORTS(sAN3);
SETUP_ADC(ADC_CLOCK_DIV_8);
SET_ADC_CHANNEL(sAN3); // Read Mode Pot Analog Channel 4
delay_ms(2);
temp_ad = READ_ADC();
delay_cycles(1);
delay_cycles(1);
if (temp_ad > 716)
{
delay_cycles(1);
output_high(Output1);
output_low(Output2);
output_low(Output3);
}
else if (temp_ad > 512)
{
delay_cycles(1);
output_low(Output1);
output_high(Output2);
output_low(Output3);
}
else if (temp_ad > 307)
{
delay_cycles(1);
output_low(Output1);
output_low(Output2);
output_high(Output3);
}
else
{
delay_cycles(1);
output_high(Output1);
output_low(Output2);
output_high(Output3);
}
}
void main()
{
output_low(Output1);
output_low(Output2);
output_low(Output3);
SETUP_ADC_PORTS(sAN3);
SETUP_ADC(ADC_CLOCK_DIV_8);
enable_interrupts(GLOBAL);
while (1==1)
{
delay_cycles(1);
read_switches();
}
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Feb 11, 2013 6:07 pm |
|
|
You want the ADC to yield 10 bit resolution, then add the following to the start of your program:
Quote: | compiler version V.103 | This is an invalid version number. Did you mean v4.103?
Code: | delay_cycles(1);
delay_cycles(1); | This can be simplified to:but.... why do you have so many of these pointless delays anyway? |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Mon Feb 11, 2013 6:54 pm |
|
|
Yes, sorry the version is 4.103
And all the "pointless delays" are put in as NOP's since the compiler does not have this feature. I use them so I can set breakpoints in the emulator.
They are also in there because I stripped out all of the code except the basic part so I could just try and figure out why the ADC routine was not working. To be honest the "delay_cycles(1)" really aren't the issue anyway.
Also I did have:
DEVICE ADC=10 in the original code but it still did not work.
I just added it to the Code I posted and still no dice.
I think I will look at the .lst output and see if the compiler is setting up the ADC correctly. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Feb 12, 2013 1:43 am |
|
|
Do a search here.
If I remember correctly, your compiler version was one that did not set up the ADC properly. PCM programmer published a fixed code for this.
If you search on the processor number, and ADC, you should find it.
Best Wishes |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Mar 04, 2013 5:04 am |
|
|
This is wrong:
Code: | SET_ADC_CHANNEL(sAN3); // Read Mode Pot Analog Channel 4 |
should be:
Code: | SET_ADC_CHANNEL(3); // Read Mode Pot Analog Channel AN3 ('4' is confusing) |
sAN3 is a constant to be used in setup_adc_ports() only. set_adc_channel() just uses the channel number, starting at zero.
RF Developer |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Mon Mar 04, 2013 6:12 am |
|
|
also ....
in your program..
enable_interrupts(GLOBAL);
..
!!! Never enable ANY interrupts without a handler(ISR code) !!!!
Sooner or later, your program will fail for some 'unknown' reason...
hth
jay
+++++++++++++++++++++++
Post by forum member 'michaeljee' removed.
Reason: spammer (now banned)
- Forum Moderator
+++++++++++++++++++++++ |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Wed Mar 06, 2013 3:18 pm |
|
|
Hi Jay,
Please help me out here on the enable_interrupts(GLOBAL); reply
Should this only be used if you are going to use all the possible interrupts?
Should I enable only the interrupts that will be used in the specific application and avoid using the enable_interrupts(GLOBAL); command altogether?
Thanks, |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Mar 07, 2013 4:35 am |
|
|
To use any interrupt you must:
a) Provide an ISR for the interrupt.
b) Enable the interrupt for the device
c) Enable interrupts globally
enable_interrupts(GLOBAL) turns the whole interrupt system on. It doesn't turn ALL interrupts on, but it must be on if you intend to use ANY interrupt. You ALSO need to enable the interrupt for the specific device. If interrupts are enabled you MUST provide an ISR for every interrupt source you have enabled.
The problem was that you enabled interrupts globally but did not provide any ISR that we can see.
RF Developer |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Thu Mar 07, 2013 6:23 am |
|
|
Thanks for the clarification.
You can teach an old dog new tricks! That is if the old dog wants to learn.
|
|
|
|