CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to use output_bit or output_high with a variable

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
John_Lintern



Joined: 30 Sep 2004
Posts: 14

View user's profile Send private message Send e-mail

How to use output_bit or output_high with a variable
PostPosted: Wed Sep 07, 2005 8:03 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 07, 2005 8:13 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 07, 2005 8:15 am     Reply with quote

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







PostPosted: Wed Sep 07, 2005 9:08 am     Reply with quote

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

View user's profile Send private message

Re: How to use output_bit or output_high with a variable
PostPosted: Fri Sep 09, 2005 11:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Sep 09, 2005 11:40 am     Reply with quote

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

View user's profile Send private message

ok, but yet I have a real newbie question I'm afraid
PostPosted: Wed Jun 14, 2006 1:21 am     Reply with quote

---->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
PostPosted: Wed Jun 14, 2006 8:19 am     Reply with quote

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
PostPosted: Wed Jun 14, 2006 9:03 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 14, 2006 11:57 am     Reply with quote

Replacement functions for output_low/high accepting variables:
PIC16: http://www.ccsinfo.com/forum/viewtopic.php?t=25280
PIC18: http://www.ccsinfo.com/forum/viewtopic.php?t=25591
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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