|
|
View previous topic :: View next topic |
Author |
Message |
kd5uzz
Joined: 28 May 2006 Posts: 56
|
PIN_A4 "Open-drain" Problems... |
Posted: Sat Jun 03, 2006 11:07 pm |
|
|
I'm sorry if this is a little too low level for you guys...
I've seen mention of this problem elsewhere on the forum, and I thought I understood how to fix it. It seems I was wrong. I'm using a 16F876 (not an 'a') and I'd like to use PIN_A4 as an output. As I understand it A4 is an 'open-drain' output...what that means exactly I'm not sure. Basicly if I pull that output high I can then have the PIC drive it low. Ok, gotcha. Except it doesn't work. I'm pulling it high with a 4.7k resister and watching the output of the pin w/ my multi meter. When I run:
Code: |
while (TRUE){
output_high(PIN_A4);
output_high(PIN_A3);
delay_ms(75);
output_low(PIN_A4);
output_low(PIN_A3);
delay_ms(75);
}
|
I see no change in the voltage on PIN_A4, but I do see a change on A3. This pin is multiplexed as a timer0 input...do I need to disable that? I've played with the Project Wizard trying to see what it did if I set A4 as an output but I didn't see anything special.
Code: |
+5v
\
/ 4.7k ohm
\
/ LED0 330ohm
Pin A4-------------|<----/\/\/----- GND
|
Before I knew the output was an Open Drain I didn't use the pullup resistor...is there anyway I could have destroyed that pin?
Any help would be great!
-Daniel
KD5UZZ
Last edited by kd5uzz on Sun Jun 04, 2006 12:31 am; edited 1 time in total |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Re: PIN_A4 "Open-drain" Problems... |
Posted: Sun Jun 04, 2006 12:24 am |
|
|
kd5uzz wrote: | Code: |
while (TRUE){
output_high(PIN_A4);
output_high(PIN_A3);
delay_ms(74);
output_low(PIN_A4);
output_low(PIN_A3);
}
|
|
Your pins are low for a miniscule amount of time. If you are trying to produce square waves, you should add another delay after output_low(PIN_A3).
kd5uzz wrote: | Code: |
+5v
\
/ 4.7k ohm
\
/ LED0 330ohm
Pin A4-------------|<----/\/\/----- GND
|
|
Since the output on pin A4 is open drain, the LED will never light up in this topology. If you want to drive an LED with an open-drain output, you could do this:
Code: |
+5v
\
/ 330 ohm
\
LED0 /
Pin A4---|<------
|
and the LED will light up, when thr output on the pin is low. |
|
|
kd5uzz
Joined: 28 May 2006 Posts: 56
|
Re: PIN_A4 "Open-drain" Problems... |
Posted: Sun Jun 04, 2006 12:31 am |
|
|
The actual code does include another delay_ms(75) line at the bottom of the while, my mistake. Is there no way to turn off the LED by driving the output low (i.e. simulate the function of all other i/o pins)?
-Daniel |
|
|
Ttelmah Guest
|
|
Posted: Sun Jun 04, 2006 4:09 am |
|
|
You are hitting a 'classic' problem, known as the 'RMW' problem. This stands for 'read modify write'. When you set/clear a pin on the PIC, the current value on the port is read, the value is modified with the change you want, and then the result is written back to the port. Now your code, then does the following:
Read current value on Port A
Set the bit for A4.
*)Output this to the port.
At this point Pin A4, _starts_ rising, driven by the resistor. The time it takes to get 'high', will depend on the loads present (both resistive and capacitive).
You then carry on.
*)Read current value on Port A
Set the bit for A3.
Output this to the port.
Now the 'key' is whether pin A4, has got high enough in voltage between the two asterisks, to be _seen_ as high. If not, at the second read, the value will be read as a 'low', and it is this that will be written back to the port, and the pin will no longer be driving high!...
Now the 'read, modify, write', is all performed in one instruction of the PIC, with the read at the start of the instruction, and the write at the end. Hence there is very little time indeed, between the value being 'output' in the 'output_high(pin_A4)' instruction, and needing to be read again, for the next output instruction.
So, if you want to perform successive output operations like this, _you_ have to ensure that enough time is allowed for the pin to reach the required level, between one instruction and the next (in fact you also have to ensure that the drive is enough, so that it _will_get to the required level). Hence in some cases when driving devices that limit the voltage the pin can reach, the problem can appear at any time.
Provided 4K7, is a low enough resistor, to actually pull the output up to _4v_ (pin A4, has a 'schmitt' input buffer, so the pin must reach 0.8*Vdd, before it'll be seen as a 'high'), then all you need to do, is add a short delay between the A4 output instruction, and the A3 output. Otherwise you need to reconsider the resistor value needed...
The problem will also occur on pins wih normal drives, when a significant load is present. This is a hardware limitation of the way the PIC works.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|