View previous topic :: View next topic |
Author |
Message |
James Bolver Guest
|
The fastest way to set and clear multible ports ? |
Posted: Tue Apr 12, 2005 5:04 am |
|
|
Hi, I have 7 outputs on two different ports. At any given time I need 6 to be floating and 1 to be high. Is there a better way to do that other then setting each one depending on an if statement ?
Another problem is that it needs to happen fast so I would rather not just set all pins to float then figure out which needs to be high. I was thinking of using this but CCS does not compile because i is not a constant.
Code: |
for (i=PIN_C0; i<PIN_C6; i++) {
if (i != toggle_variable)
output_float(i);
else
output_high(i);
}
|
Obviously this is not for two ports, but no problem since it does not work anyway. Also, I have inputs on the remaining pins.
Thanks for your time!
James Bolver |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Apr 12, 2005 6:22 am |
|
|
ORing the tris register with a value will make the pin an input (float)
say we have trisc defined somewhere and we want C0,C1,C2, and C4 to be inputs (float)
Code: |
trisc |= 0b00010111; // make them inputs
|
want them to be outputs then
Code: |
trisc &= 0b11101000; // make them outputs
|
You can do the same for setting outputs high or low
Code: |
trisc &= 0b11101000; // make them outputs
portc |= 0b00010111; // make them high
portc &= 0b11101000; // make them low
|
If usings a pic18 it is better to use the lat register. See the datasheet and read about read write modify. |
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 9:03 am |
|
|
Is trisc a key word in your version of CCS ?
Am I missing somthing here |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Apr 12, 2005 9:08 am |
|
|
It is a register name. You will have to define it base on your PIC. Something like
#byte portc = 0x07
#byte trisc = 0x87 |
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 9:18 am |
|
|
Code: |
#byte portb = 6
#byte portb_tris = 0x00
|
nevermind. [/code] |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Apr 12, 2005 9:19 am |
|
|
that doesn't look right for the portb_tris. |
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 10:31 am |
|
|
I dont know. Its from the CCS help file. I havn't had a chance to try it yet,
I do have a problem that I dont want to effect the rest of the pins on either port. Just the ones I'm interested in.
I'll need to come up with somthing for that. Maybe storing in the bits I dont change, setting the ones I do and restoring the old ones. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Apr 12, 2005 10:54 am |
|
|
James Bolver wrote: | I dont know. Its from the CCS help file. I havn't had a chance to try it yet,
I do have a problem that I dont want to effect the rest of the pins on either port. Just the ones I'm interested in.
I'll need to come up with somthing for that. Maybe storing in the bits I dont change, setting the ones I do and restoring the old ones. |
Yeah, that's what the code I posted does. |
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 1:39 pm |
|
|
Really ?
The &= must be throwing me off then. Isn't that going to set my first two bits (lets imagine I'm using the last 6) regardless of if I want it to or no ?
So if I have
trisc = 10111011 in my program (C2 is my currently high, C6 and C7 is doing other stuff)
Then I want to change C2 from high to float and light up C3 you are saying use & but that will screw up the mystery bits 7 and 6 (which I dont care to check the state of before I do this), so ^
trisc |= 00000100; //make C2 float
trisc ^= 00001000; //XOR will do this I think
now trisc should be 10110111 no ?
THEN I would have to go ahead and make that output correct too.
Hmmm... If I have the first nibble set to LOW and then I switch that port to input is it still LOW when I switch back ? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Apr 12, 2005 1:55 pm |
|
|
James Bolver wrote: | Really ?
The &= must be throwing me off then. Isn't that going to set my first two bits (lets imagine I'm using the last 6) regardless of if I want it to or no ?
So if I have
trisc = 10111011 in my program (C2 is my currently high, C6 and C7 is doing other stuff)
Then I want to change C2 from high to float and light up C3 you are saying use & but that will screw up the mystery bits 7 and 6 (which I dont care to check the state of before I do this), so ^
trisc |= 00000100; //make C2 float
trisc ^= 00001000; //XOR will do this I think
now trisc should be 10110111 no ?
THEN I would have to go ahead and make that output correct too.
Hmmm... If I have the first nibble set to LOW and then I switch that port to input is it still LOW when I switch back ? |
My example didn't use the last 6. It used the ones that I stated. But for your example:
trisc |= 0b00000100; //make C2 float
trisc &= 0b11110111; //make C3 output
portc |= 0b00001000; //set c3 high |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 12, 2005 1:59 pm |
|
|
Quote: | that doesn't look right for the portb_tris. |
When Mark said it "doesn't look right" he wasn't expressing doubt,
he was just using a conversational tone. He means it's dead wrong.
Just to let you know....
Quote: | I dont know. Its from the CCS help file. I havn't had a chance to try it yet, |
I searched the CCS help file that comes with PCM vs. 3.22 for portb_tris
and there's only one article that has that string in it. It has these lines:
Code: | #byte portb = 6
#byte portb_tris = 0x86 |
|
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 2:14 pm |
|
|
Oh, what is it that 0x86 does ? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Apr 12, 2005 2:19 pm |
|
|
It's an address. The address of the port b tris register in the pic's RAM. Or it should be, I didn't check it. Take a look at the pic's data sheet - there will be a section on its' memory organization. Look for a table of the "special function registers" - port b will be at address 6, and I'm assuming that port b's tris register will be at 0x86. |
|
|
Ttelmah Guest
|
|
Posted: Tue Apr 12, 2005 2:20 pm |
|
|
It is the _address_ of the register.
The '#byte' operator, allows you to associate a particular 'name' to I/O on a particular address. The data sheet for the chip, will tell you what address each register is on (it changes for the larger '18' chips, and the smaller '12' chips). '0x86', is the address of the portb TRIS register, on the 16 chips. Setting this to '0', mans that when you talk to the variable 'portb_tris', you will actually talk to the indirect addressing register, and could destroy data anywhere in memory...
To send '0' to portb_tris, involves first stting the register address with the #byte operator, then having something like:
portb_tris=0;
Which transfers '0' to the register now referred to by 'portb_tris'.
Best Wishes |
|
|
James Bolver Guest
|
|
Posted: Tue Apr 12, 2005 3:21 pm |
|
|
Does the output state reset every time or does it stay in memory ?
IE: If I set the trisc to half low and half high then make portc inputs then switch back to outputs are all low again? |
|
|
|