View previous topic :: View next topic |
Author |
Message |
23.North
Joined: 19 Aug 2010 Posts: 4
|
Set specific pin as analog |
Posted: Thu Aug 19, 2010 2:04 pm |
|
|
I'm using 18F2525 and was wondering whether it is possible to set pins A0,A1,A2 as digital outputs and to have AN3 as an analog input at the same time.
The definitions in the .h file doesn't suit me, as they would also set the first pins as analog inputs, which I'm trying to avoid.
The only way i was thinking of going round this problem is to at first set all pins as digital outputs, then use the first ones, then set all of them as analog inputs, use A3 and then again setup the pins as no_analogs to finish the job?
However, someone had mentioned that it was possible to assign a specific pin as Analog input. Can anyone help?
What should be set in the set_adc_ports()? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Aug 19, 2010 2:23 pm |
|
|
The ultimate authority is the PIC datasheet. On the 16 series PICs that I am familiar with only certain combinations of analog and digital pins are supported by the PIC hardware. Your .h file is a strong suggestion that this is true for your PIC as well. The PIC datasheet will tell you for sure. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 19, 2010 2:30 pm |
|
|
Quote: | The definitions in the .h file doesn't suit me |
Those are the only available options. You can't change it by doing
sequential calls to setup_adc_ports(). Only the latest call is valid.
The PIC's hardware design defines this situation, not the compiler.
One solution is to try to find another PIC that allows you to select
the analog pins individually. You could look at the 18F25K20. |
|
|
23.North
Joined: 19 Aug 2010 Posts: 4
|
|
Posted: Thu Aug 19, 2010 2:36 pm |
|
|
Of course I understand that is how the hardware is designed, and not the software, that is valid. But I thought that you can set AN0 as an output, that it is also optional for other analog pins.
So, is the idea mentioned in the first post realizable (about constantly switching them from NO_analogs to AN0_TO_AN3), as the application is time-limited? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 20, 2010 2:30 am |
|
|
Remember also though, that even if you use multiple statements, to switch to/from operating in analog mode, if a pin is left with an analog voltage attached, and switched to being a digital input, you still retain the 'transition region' power problem. If a pin with the digital input circuitry attached is held at a voltage in the 'undecided' switching area, extra power is drawn by the input cicuitry. If power consumption is important, this may be a problem....
Best Wishes |
|
|
23.North
Joined: 19 Aug 2010 Posts: 4
|
|
Posted: Fri Aug 20, 2010 3:56 am |
|
|
I have found one of the shown topic, but now the other covered part of the questions that i had.
Just to sum up. Is this possible (and i think won't have the extra power drainage )
Code: | setup_adc_ports(AN0_TO_AN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(3);
output_high(PIN_A0);
output_low(PIN_A1);
output_bit(PIN_A2,1); // + the toggle function will work ?
adc_output=read_adc(); //read from AN3
|
Another question: Can this be used as an attachment to the code above:
Code: | //part 1
int8 port=7;
output_a(port); // Will set A0,A1,A2 as high, but will this switch A3 to low as an output?
adc_output=read_adc(); //read from AN3
//part2
port=8;
output_a(port); //will set A3 as high (A0,A1,A2 as low)
adc_output=read_adc(); //will A3 be switched again to an analog input?
|
I think that it is not a good idea to use(part 1+ 2). Is there any other way to do? |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Fri Aug 20, 2010 6:04 am |
|
|
I had a similar problem once, but mine were digital inputs instead of outputs.
I just config'd the ports as analog, did the conversion and reset them as all outputs. It worked fine and nothing died. The datasheet does warn that the current draw may be out of spec, I never checked, but it wasn't important in my situation. If you have some series resistance on the ad channel, you could always set it as a digital output when its not in use.
Best if you can switch to a different chip, but in my case i couldn't.
I'd say try it and see. PIC's are cheap. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 20, 2010 6:54 am |
|
|
Quote: |
Another question: Can this be used as an attachment to the code above:
Code: | //part 1
int8 port=7;
output_a(port); // Will set A0,A1,A2 as high, but will this switch A3 to low as an output?
adc_output=read_adc(); //read from AN3
//part2
port=8;
output_a(port); //will set A3 as high (A0,A1,A2 as low)
adc_output=read_adc(); //will A3 be switched again to an analog input?
|
I think that it is not a good idea to use(part 1+ 2). Is there any other way to do? |
Depends on your I/O mode.
If you select 'fast_io', or 'fixed_io' mode, then A3, will stay selected as an input (assuming you set it this way), and you can still do 'port wide' I/O on the other pins. With 'standard_io', when you perform the port wide output, A3, will be set as an output, and will _not_ be set back to an input by the analog statements.
Best Wishes |
|
|
23.North
Joined: 19 Aug 2010 Posts: 4
|
|
Posted: Fri Aug 20, 2010 12:04 pm |
|
|
Thank you all. I partly tested the program. The fast_io trick works, though I haven't measured the adc. Now I'm left with all kinds of other programming, which reminds me (I don't want to spam the forum with another topic).
Which is the fastest way to calculate trigonometric functions?
I need to calc. around 40 acos() in under 10-12ms and the fastest way is with a look up table.
12000us with 100ns per instruction (at 40Mhz) which makes 120 instructions. Which is practically impossible. I am right? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 20, 2010 2:15 pm |
|
|
Basically yes.
It depends massively on how much accuracy you need.
I have done an application in the past, and the solution here was to used scaled integers, rather than floats, then a 180 element lookup table, for one quadrant. Using this, and then linear intepolating, gave resolutions to just on 3 digits, in about the timescale you need.
Using scaled integers, massively speeded up the interpolation, and the rest of the arithmetic involved.
Best Wishes |
|
|
|