|
|
View previous topic :: View next topic |
Author |
Message |
mgr Guest
|
why this won't work |
Posted: Sun Jul 30, 2006 5:36 am |
|
|
hi,
can anybody tell my why this code won't work ??
Code: |
#include <16F648A.h>
#fuses WDT, XT, MCLR , NOCPD, NOLVP, NOBROWNOUT
#use delay(clock=4000000)
#define GREEN PIN_A2
#define RED PIN_A1
void main()
{
output_high(GREEN);
output_low(RED);
while(true)
{
output_toggle(GREEN);
//sprawdzanie wejscia
output_high(PIN_A3);
if (!input(PIN_A3))
{
output_high(GREEN);
output_toggle(RED);
delay_ms(5000);
}
delay_ms(400);
}
}
|
when porta.3 is in low 'red' shoutbe high
another low pulse on porta.3 'red' shoutbe low |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Jul 30, 2006 7:54 am |
|
|
Code: | output_high(PIN_A3); |
Makes the PIN an output and sets in high
Makes the PIN an input and reads the level of what is connected to it. |
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 30, 2006 7:57 am |
|
|
The cause of this sort of problem, is that the pin is not actually getting to the 'high' level at the moment you read it. You 'output' a signal on A3, and this switches on the driver. However depending on the capacitance present, and any resistances loading the line, it _will_ take time for the line to actually go high (if it ever does). Now pin A3, has a Schmitt trigger input buffer. This has a 'Vih' specification of 0.8* the supply voltage. The actual operation sequence occurring is:
Set tris to make pin A3 an output.
Drive the pin high.
Set tris to make pin A3 an input.
Read the voltage currently on the pin.
If this voltage is greater than 0.8*Vdd, see the input as 'high', otherwise see it as 'low'.
Now you can see that the pin is only 'driven' for a tiny fraction of a second, and that there is then another instruction time between this drive and the actual 'read'. As such, whether a high, or a low is seen, will depend totally on what is connected to the line, and may not be what is 'expected'.
Seperately, there is then the question of whether 'output_toggle' will ever see the right level on pin A2.
Here the 'sequence' is:
Set tris to make the pin an input.
Read the voltage present.
If the voltage > 0.8*Vdd, return a 'high' otherwise if the voltage is < 0.2*Vdd, return a 'low'. Invert this value, set tris to make the pin an input, and output the new value.
Depending on the resistor value chosen to feed the LED, the line may never actually get to the 'high' logic level (or 'low' if this is a 'pull down' drive). It'll then always try to drive high after this instruction, rather than 'toggling'.
These particular problems come from the actual output/input drive structure of the PIC, and is known as the 'read, modify, write' (RMW) problem. There have been many posts about this in the past, and MicroChip, used to have an application note about this.
To use pins reliably this way, you need to ensure that the loadings are inside the specifications, and timings are such that the signals will actually be 'at' the expected voltage when you read. The alternative is to store a 'shadow' copy of what you want to output, and toggle _this_, rather than relying on the voltage read from the pin. In the A3 case, assuming this is some sort of capacitive 'drive', then consider adding a delay between driving the pin, and actually reading it. For the LED case, consider toggling a local copy of what you want to send.
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
|