|
|
View previous topic :: View next topic |
Author |
Message |
John_Lintern
Joined: 30 Sep 2004 Posts: 14
|
How to use output_bit or output_high with a variable |
Posted: Wed Sep 07, 2005 8:03 am |
|
|
I am trying to use the 'pin' parameter as a variable in the command output_bit.
e.g output_bit (pin, value)
I want the 'pin' parameter to be a variable so that the output bit depends on the value of the variable.
As PORT B bit 0 is defined as 48
e.g #define PIN_B0 48
I decided to use a variable called 'SelectBit' which will have one of the following values...
SelectBit=48 (for PORT B bit 0)
SelectBit=49 (for PORT B bit 1)
SelectBit=50 (for PORT B bit 2)
SelectBit=51 (for PORT B bit 3)
SelectBit=52 (for PORT B bit 4)
SelectBit=53 (for PORT B bit 5)
I want to use the value of 'SelectBit' to determine what output bit is used.
But I cant use my variable 'SelectBit' in the command output_bit or output_high.
e.g.
output_bit (SelectBit, 1)
or
output_high (SelectBit)
I get a compile errror saying 'The expression must evaluate to a constant'.
How can I use a variable to determine the selected output bit of a port ? |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Sep 07, 2005 8:13 am |
|
|
Have you looked at the function bit_set()? This might enable you to pass a variable to set a particular pin high or low. The help file shows a 'crude' example of how to set a pin that way.
Ronald |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 07, 2005 8:15 am |
|
|
Quote: | 'The expression must evaluate to a constant' |
That means is can't be a variable, it must be a constant. You'll have to write you own function. |
|
|
Ttelmah Guest
|
|
Posted: Wed Sep 07, 2005 9:08 am |
|
|
Try:
#define set_bit(x) bit_set(*(int8 *)((x-PIN_A0)>>3),(x&3))
#define clear_bit(x) bit_clear(*(int8 *)((x-PIN_A0)>>3),(x&3))
An archive search sould find these, and several other versions to do the same.
Best Wishes |
|
|
adrian
Joined: 08 Sep 2003 Posts: 92 Location: Glasgow, UK
|
Re: How to use output_bit or output_high with a variable |
Posted: Fri Sep 09, 2005 11:12 am |
|
|
John_Lintern wrote: | I am trying to use the 'pin' parameter as a variable in the command output_bit.
e.g output_bit (pin, value)
|
Here is a bit of code I wrote yonks ago to test out a board of mine. It just cycles round setting each bit of Port A high. Not a brilliant bit of coding, but I think it should do what you want?
Code: |
//PORT A CONFIGURATION
#byte PORTA= 0X05 //port address
#define PORTA_DDR 0x00 //bin 0000 0000 set I/O direction
#define PORTA_OUT 0x00 //bin 0000 0000 set output state
#define CYCLE 1000
void main(void)
{
//declare and initialise local variables
int apin = 0;
//INITIALISATION
set_tris_a(PORTA_DDR); //set direction of I/O
PORTA = PORTA_OUT; //set output pins
//MAIN CODE STARTS HERE
do
{
//reset loop variables
apin = 0;
//reinitialise outputs
PORTA = PORTA_OUT; //set output pins
delay_mS(CYCLE);
for ( ; apin<=7; ++apin)
{
bit_set(porta,apin);
delay_mS(CYCLE);
}
}
while(1);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Sep 09, 2005 11:40 am |
|
|
Quote: | #define set_bit(x) bit_set(*(int8 *)((x-PIN_A0)>>3),(x&3))
#define clear_bit(x) bit_clear(*(int8 *)((x-PIN_A0)>>3),(x&3)) |
What parameter is used for 'x' in the macros above ?
For CCS-style pin numbers, I know the following macros work.
That's because the CCS pin numbers have the bit number
in the bottom 3 bits, and the port address in the upper bits.
Code: |
#define set_bit_var(x) bit_set(*(int8 *)(x >> 3), x & 7)
#define clear_bit_var(x) bit_clear(*(int8 *)(x >> 3), x & 7)
#define read_bit_var(x) bit_test(*(int8 *)(x >> 3), x & 7)
|
For example, PIN_B1 is 49 (0x31) as given in the 16F877.H file.
So masking down the bottom 3 bits with 'x & 7' gives 1, which is
the bit number. Then shifting 0x31 right 3 times gives 0x06,
which is the address of Port B. |
|
|
Miguel
Joined: 14 Jun 2006 Posts: 1 Location: Spain
|
ok, but yet I have a real newbie question I'm afraid |
Posted: Wed Jun 14, 2006 1:21 am |
|
|
---->Edited: Ok, good news. I have found a solution for it to work (would love if there is anything else). I have seen TRISB is from start set to 0xFF making it an "entry port". I have cleared it with set_tris_b(0x00) and now it is working like a charm.
---->End of added edit
First of all let me say I'm new to the forum and hope I can get to enter the community the right way. Actually I'm starting to program a PIC 18F8722 and I must say I'm an absolute newbie in this matter. I have programmed others but much more simple than this one.
I mean I can get to understand (I think) these macros, but when trying to use them I find myself with the bit being written not in lets say bit 5 of PortB, but instead in bit 5 of LatchB. Result of it no flashing the led I have connected on that pin.
I'm using CCS 3.249 on a 18F8722 using the ICD-U debugger/programmer jst in case it might help. I keep on searching, but just in the meanwhile maybe someone could clarify this.
In fact I have had an idea I will take a look at right now because maybe it is only an address issue making me change any or both of those 3 and 7 values on the macros posted.
Thanks for any help _________________ Best regards |
|
|
Ttelmah Guest
|
Re: ok, but yet I have a real newbie question I'm afraid |
Posted: Wed Jun 14, 2006 8:19 am |
|
|
Miguel wrote: | ---->Edited: Ok, good news. I have found a solution for it to work (would love if there is anything else). I have seen TRISB is from start set to 0xFF making it an "entry port". I have cleared it with set_tris_b(0x00) and now it is working like a charm.
---->End of added edit
First of all let me say I'm new to the forum and hope I can get to enter the community the right way. Actually I'm starting to program a PIC 18F8722 and I must say I'm an absolute newbie in this matter. I have programmed others but much more simple than this one.
I mean I can get to understand (I think) these macros, but when trying to use them I find myself with the bit being written not in lets say bit 5 of PortB, but instead in bit 5 of LatchB. Result of it no flashing the led I have connected on that pin.
I'm using CCS 3.249 on a 18F8722 using the ICD-U debugger/programmer just in case it might help. I keep on searching, but just in the meanwhile maybe someone could clarify this.
In fact I have had an idea I will take a look at right now because maybe it is only an address issue making me change any or both of those 3 and 7 values on the macros posted.
Thanks for any help |
LatchB, _is_ portB...
On the 18 chips, the output latch is separate from the actual direct I/O register. Writing to the latchB register, will output to portB.
The problem you are hitting, is the IO mode. The PIC, as well as having an output register for the port, has a 'TRIS' register, which controls whether each pin, is configured as an input or output. There are three separate IO 'modes' supported by the compiler:
StandardIO - on this, every normal IO instruction, sets the TRIS register before accessing the pins, based on the direction needed to support the IO.
FixedIO - on this, the IO instructions still set the TRIS register, but the value sent is defined in the FixedIO statement, rather than being selected based on the IO being done.
FastIO - on this,_you_ have to manually set the tris register. However this is also the fastest mode.
Now 'standardIO', is the normal form used by the compiler by default. The registers is _only_ updated when a 'normal' IO function is carried out. The macros, _do not_ call the normal IO functions, and so will not update TRIS.
To use the macros as given, you need to set the I/O mode of the pins yourself, using either fast_io, and TRIS, or the FixedIO instruction.
Best Wishes |
|
|
Guest
|
Re: ok, but yet I have a real newbie question I'm afraid |
Posted: Wed Jun 14, 2006 9:03 am |
|
|
Ttelmah wrote: | LatchB, _is_ portB...
On the 18 chips, the output latch is seperate from the actual direct I/O register. Writing to the latchB register, will output to portB.
The problem you are hitting, is the IO mode. The PIC, as well as having an output register for the port, has a 'TRIS' register, which controls whether each pin, is configured as an input or output. There are three seperate IO 'modes' supported by the compiler:
StandardIO - on this, every normal IO instruction, sets the TRIS register before accessing the pins, based on the direction needed to support the IO.
FixedIO - on this, the IO instructions still set the TRIS register, but the value sent is defined in the FixedIO statement, rather than being selected based on the IO being done.
FastIO - on this,_you_ have to manually set the tris register. However this is also the fastest mode.
Now 'standardIO', is the normal form used by the compiler by default. The registers is _only_ updated when a 'normal' IO function is carried out. The macros, _do not_ call the normal IO functions, and so will not update TRIS.
To use the macros as given, you need to set the I/O mode of the pins yourself, using either fast_io, and TRIS, or the FixedIO instruction.
Best Wishes |
Ok, thanks for the directions Ttelmah!! I will read further on that way and investigate it some more. My interest on using the macros is just to avoid having to write a full set of switches to control which pin of which port has to be set/clear/read. I feel it is way too much unnecessary code and macros are the solution I've found here in this forum from the help of more experienced users like yourself. I suppose there is not any better solution other than this to accomplish this task, so I will keep clearing TRISB. Al old friend from 16F84 days.
Once again, thanks so much |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
|
|
|
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
|