|
|
View previous topic :: View next topic |
Author |
Message |
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
16f628 A4 output |
Posted: Thu Jul 21, 2005 1:28 pm |
|
|
I'm using A4 as an output (with a pullup resistor), but something continuously keeps it low. I CAN make it high by doing an output_high followed by a delay, just as a test. But without the delay, something immediately yanks it low again.
I'm suspicious of A4 also being a comparator output, but doing setup_comparator(nc_nc_nc_nc) doesn't help.
Maybe it's the TOCKI reference, but I don't find anything helpful on that.
Any Ideas?
Regards,
Don |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 21, 2005 1:37 pm |
|
|
What is your version of the compiler ?
The version number is given at the top of the .LST file, which
can be found in your project folder. It will be a number like
3.191, or 3.225, or 3.228, etc. |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
3.152 |
Posted: Thu Jul 21, 2005 1:53 pm |
|
|
3.152 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 21, 2005 2:09 pm |
|
|
setup_comparator(NC_NC_NC_NC); works correctly with your version
of the compiler. So, post a small test program that demonstrates
the problem. Show all #fuses, #use, and #include statements. |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
|
Posted: Thu Jul 21, 2005 5:10 pm |
|
|
#include <16F628.h>
#fuses nowdt,nolvp,intrc_io,noput,nomclr,protect
// internal clock
#use delay( clock=4000000 )
#nolist
#include <string.h>
#list
/*
A4 output to channel 3 of 2003 driver chip [open collector!] relay K3
*/
/*
port usage:
A4 [open collector] relay K3 110v chime (needs pullup resistor)
*/
#rom 0x2100={1,4,2,3, // access code
0, // Access=0 Exit=1 Armed=2 Entry=3 Alarm=4 mode
10, // Exit Chime Time (1/2 secs)for exit delay
10, // Entry Chime Time (1/2 secs)for entry delay
10 } // Horn Time (1/2 secs) for intrusion alarm
#define Dial_1 pin_A1 // K6 intrusion caller
#define Intrusion pin_B0 // input
#define Access 0
int Mode = 0 ;
int Bits2 = 0x02 ;
#bit NewMode = Bits2.1 // initially = 1
void main() // M A I N
{
set_tris_a(0x20); // 0=output
set_tris_b(0xFF) ;
port_b_pullups(true) ;
setup_comparator(nc_nc_nc_nc) ; // SEEMS TO MAKE NO DIFFERENCE
Mode = read_eeprom( 0x2104 ) ; // Access=0
for(;;) // forever
{
// THIS IS STRANGE! IF THE FOLLOWING 3 LINES ARE COMMENTED-OUT, THE PROBLEM
// GOES AWAY (i.e. A4 WILL STAY ON WHEN COMMANDED.
output_bit(pin_A2,bit_test(mode,0) );
output_bit(pin_A3,bit_test(mode,1) );
output_bit(pin_A7,input(intrusion) );
switch( Mode )
{
case Access:
if( NewMode )
{
output_high(pin_A4) ; // THIS IS THE OUTPUT THAT WON'T STAY ON
delay_ms(500) ; // AND THIS DELAY LETS ME SEE THAT AT LEAST IT IS TRYING
NewMode=false ;
}
break ;
}
} // main |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Thu Jul 21, 2005 6:59 pm |
|
|
I canīt test the code you posted because it is uncomplete.
Try a simple test like this, if it works fine, re-check your code.
Code: |
#include <16F628.h>
#fuses nowdt,nolvp,intrc_io,put,nomclr,noprotect
// internal clock
#use delay( clock=4000000 )
void main() // M A I N
{
set_tris_a(0x20); // 0=output
set_tris_b(0xFF) ;
port_b_pullups(true) ;
setup_comparator(nc_nc_nc_nc) ;
for(;;) // forever
{
output_high(pin_A4) ;
delay_ms(500) ;
output_low(pin_A4);
delay_ms(500) ;
}
}
|
Best wishes,
Humberto |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 21, 2005 7:39 pm |
|
|
Quote: |
A4 output to channel 3 of 2003 driver chip [open collector!] relay K3
// THIS IS STRANGE! IF THE FOLLOWING 3 LINES ARE COMMENTED-OUT,
// THE PROBLEM GOES AWAY (i.e. A4 WILL STAY ON WHEN COMMANDED.
output_bit(pin_A2,bit_test(mode,0) );
output_bit(pin_A3,bit_test(mode,1) );
output_bit(pin_A7,input(intrusion) );
output_high(pin_A4) ; // THIS IS THE OUTPUT THAT WON'T STAY ON
delay_ms(500) ; // AND THIS DELAY LETS ME SEE THAT AT LEAST IT IS TRYING
|
It sounds like a Read-Modify-Write problem on Port A. Anytime you
write to a Port register in a PIC, the PIC first reads all the pin values into
an internal register. Then it changes the specific bit (A2, A3, or A7 in this
case), and writes the entire byte back out to Port A. So this means that
pin A4 is at a low level when you're writing to those other bits.
(The 18F series PICs fixed this problem by providing a Latch register).
I'm trying to think of reasons why pin A4 could be read as a low level.
1. What's the size of your pull-up resistor on pin A4 ?
2. Do you have a back-EMF diode connected across your relay coil ?
If the pull-up was too large or if you're missing the diode, it's possible
that this could cause the problem.
Also, even though I looked at the code built by vs. 3.152 and
setup_comparator() looks OK, you should still try this:
#byte CMCON = 0x1F
void main()
{
CMCON = 7;
}
If the problem can't be fixed by the suggestions above, then read my
long post in the following thread, which explains how to fix a RMW problem on Port A.
http://www.ccsinfo.com/forum/viewtopic.php?t=21825&start=15 |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
|
Posted: Mon Jul 25, 2005 11:05 pm |
|
|
Sorry, been a few days getting back to this project. Humberto's suggestion doesn't illustrate the problem because I can get A4 to respond momentarily, and I have put delays after the commands to see that it actually did happen.
I also tried setting CMCON=7, but it made no difference.
Strangely, I use A0 & A4 in similar fashion. That is, they both flash HI & LO in a timer1 interrupt routine. And A0 works fine. I then tried changing the #defines for the A0 & A4 associations. The problem stayed with the A4 pin. It didn't change with the logical associations. This would indicate that it's not in the program, but somewhere in the chip's behavior with respect to A4.
If it was an RMW issue, it should move to the other pin.
So I'm not at a solution yet.
Regards,
Don |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
|
Posted: Mon Jul 25, 2005 11:39 pm |
|
|
Oh yeah -- pullups & diodes . . .
It's a 22K pull-up on A4, which feeds an input to a 7-channel 2003 darlinton chip, that will (eventually) run the relay. The 2003 already incorporates suppression diodes. For now the 2003 output just drives an LED thru a resistor. Same for all the other "A" outputs.
Eventually they will drive relays that control chimes, horns and telephone dialers, but, for now, it's easier to watch the LEDs.
Regards,
Don |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 25, 2005 11:46 pm |
|
|
Just do the mod with the shadow register. If it fixes the problem,
it was a RMW issue. If not, it's something else. |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
|
Posted: Mon Jul 25, 2005 11:53 pm |
|
|
Yup, I did the shadow_Port_A thing from your example -- same. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 26, 2005 12:02 am |
|
|
What's the size of the pullup resistor on pin A4 ?
Do you have a back-emf diode on the relay coil ? |
|
|
Don P
Joined: 26 Aug 2004 Posts: 23 Location: California
|
|
Posted: Tue Jul 26, 2005 12:08 am |
|
|
see a couple msgs back. ( This forum doesn't seem to like cut & paste from other posts). It's 22K driving 2003, which has diode built in. And relay isn't hooked up yet; just an LED. Simple program to turn A4 on & off works the pin OK. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 26, 2005 12:30 am |
|
|
To me, it still smells like RMW.
I decided to research this a little more.
Here's a thread from Piclist where someone's doing exactly what
you're doing (or what you'll eventually be doing).
http://groups-beta.google.com/group/comp.arch.embedded.piclist/browse_thread/thread/ceae357b5f2871be/07a188d57fb22a37?
They explain that the voltage on the pin will never go above 0.7v,
which is the drop across the transistor's B-E junction. They
suggest using a series resistor in the base circuit. In other words,
first comes the pic pin, then the pull-up, then the series resistor,
and then the base of the transistor.
That would be a hardware fix.
I still say that it can be fixed in software by use of a shadow
register. You just have to make sure that all writes to Port A
are done by doing byte-wide write of the shadow register.
No other writes are allowed.
I may do a test program tomorrow on a demo board to prove this. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jul 26, 2005 8:01 am |
|
|
Don P wrote: | see a couple msgs back. ( This forum doesn't seem to like cut & paste from other posts). It's 22K driving 2003, which has diode built in. And relay isn't hooked up yet; just an LED. Simple program to turn A4 on & off works the pin OK. |
Look at the internal equivalent circuit of a 2003. It has a 2.7K resistor to the base of the first transistor, and from this point, a 7.2K across the first transistors B-E junction, and then a 3.3K across the second. Ignoring the diode clamp effects completely, a 22K resistor, would only pull the input up to (5/(22000+13200))*13200v. 1.875v. The diode bypass effect of both B-E junctions will slightly lower this, to give typically 1.6v. Since Vih for A4 is typically 4v, as PCM Programmer says, you _will_ see the RMW problem.
I suspect your attempt to use a shadow register, was perhaps missing one I/O instruction somewhere, ad hence not working.
To get a 'high' that is seen as a high on this pin, you would need a pull up of less than 964ohms. Or substitute the ULN2004, and you can then use 3.7K.
In fact this is worth doing, since it will reduce the currents drawn by the other pins as well.
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
|