Topics Topics Edit Profile Profile Help/Instructions Help Member List Member List  
Search Last 1|3|7 Days Search Search Tree View Tree View  

C code for PIC

:: EPE Chat Zone ­:: ­Radio Bygones Message Board :: » EPE Forum Archives 2010 - » Archive through 02 March, 2012 » C code for PIC « Previous Next »

  Thread Last Poster Posts Pages Last Post
  ClosedClosed: New threads not accepted on this page        

Author Message
Top of pagePrevious messageNext messageBottom of page Link to this message

bruce
Frequent Contributor
Username: bruce

Post Number: 762
Registered: 04-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Friday, 17 February, 2012 - 09:53 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

I appreciate this isnt the proper forum for programming, but I know some of you guys know a thing or two about 'C' and this should be a trivial question for you.
A website called 'Gooligum' has some tutorials about programming PIC chips and I have had a peek at the assembler stuff. However, I decided to see if I could progress to 'C' and luckily Mr. Gooligum has tutorials on that as well.
There is some very basic code for turning LEDs on and off, which he has done by simply
'flipping' the bit concerned. The code can be:

PORTX.1 = !PORTX.1

Another way he used was the 'conditional operator' thus:

PORTX.1 = PORTX.1 ? 0 : 1 ;

I have puzzled over this one for ages yet I still dont get it. My understanding is that the first part is a statement which is either TRUE or FALSE. Well, whatever the state of 'X', it's always TRUE; 'X' will become a LOW; every time the command is executed it will become LOW and therefore nothing will change.

What have I missed?

bruce
Top of pagePrevious messageNext messageBottom of page Link to this message

alec_t
Frequent Contributor
Username: alec_t

Post Number: 762
Registered: 03-2009

Rating: N/A
Votes: 0 (Vote!)

Posted on Friday, 17 February, 2012 - 10:32 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

By 'the first part' do you mean the first code statement, or the code before the '?' in the second code statement?
Top of pagePrevious messageNext messageBottom of page Link to this message

mikehibbett
:::: Super User ::::
Username: mikehibbett

Post Number: 1370
Registered: 04-2005


Rating: N/A
Votes: 0 (Vote!)

Posted on Friday, 17 February, 2012 - 10:40 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Bruce,

the line of text:

PORTX.1 = PORTX.1 ? 0 : 1 ;

is *exactly* the same as the following:

if ( PORTX.1 )
PORTX.1 = 0;
else
PORTX.1 = 1;

Your question isn't clear enough to be able to answer it, so does the above help, and if not, perhaps you could try phrasing your question differently.

Cheers,

Mike.
Top of pagePrevious messageNext messageBottom of page Link to this message

perro
Frequent Contributor
Username: perro

Post Number: 121
Registered: 10-2007

Rating: N/A
Votes: 0 (Vote!)

Posted on Saturday, 18 February, 2012 - 11:16 am:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Bruce,

Mike's spot on - the ? : construct is simply shorthand for the code he posted, above.

However, I think your question was more to do with how the code to the right of the colon will ever execute. BUT, if I've misunderstood, or am pitching too low and telling you stuff you already know, please tell me.

The key point is: PORTX.1 refers to the value of bit-1 on PORTX (and not the literal value 1). Boolean evaluation of PORTX.1 will return FALSE if PORTX.1 is set to 0, or TRUE if it's set to 1. As you know, the logic or signal levels, HIGH & LOW, on the physical port, correspond to 1 and 0, respectively.

In truth, 'C', C++, C# and *most* other languages interpret a zero or 'null' value as FALSE, and any non-zero or non-null value as TRUE. So 0 evaluates to FALSE and 1 evaluates as TRUE, BUT 2, 3, 100, 999, -1 also ALL evaluate to TRUE. Fortunately, in your example, PORTX.1 will only ever be 1 or 0.

The code to the right of the ? will return 0 if bit-1 on PORTX is 1, or 1 if bit-1 on PORTX is 0 - i.e. it always returns the opposite to whatever the current value of bit-1 on PORTX is set to. This means that line of code simply inverts the value of PORTX.1 each time it executes.

So, lets say bit-1 on PORTX is initially 0 (i.e. we may have previously executed PORTX.1 = 0)...

The first time we execute PORTX.1 = PORTX.1 ? 0 : 1 , PORTX.1 will evaluate to FALSE, so the code to the RIGHT of the : will execute and return 1, which will be the value assigned to bit-1 on PORTX. PORTX.1 is thus set to 1

The next time that line executes, PORTX.1 will evaluate to TRUE ('cos we just set it to 1), so this time the code on the LEFT of the : will execute, causing PORTX.1 (bit-1 on PORTX) to be set to 0 again.

And so on....

This is the same as Mike's code. However, that could me made even MORE explicit, as follows.....

if(PORTX.1 == 1)
PORTX.1 = 0;
else
PORTX.1 = 1;



OR, you could say

if ( PORTX.1 != 0)
PORTX.1 = 0;
else
PORTX.1 = 1;


BTW: Sorry about the lack of indentation - I can't get it to appear properly, using the online post-editor)

OR you could use variations of the shorthand version to say any of the following....

PORTX.1 == 1 ? 0 : 1

PORTX.1 == 0 ? 1 : 0

! PORTX.1 ? 1 : 0

PORTX.1 != 0 ? 0 : 1

PORTX.1 != 1 ? 1 : 0


They ALL result in the same thing (now sod's law dictates that someone will point out a typo - in which case I apologise).

However, as we simply want just to {invert
the value of bit-1 on PORTX, the code

PORTX.1 = ! PORTX.1

is the clearest and most concise way to write (in my opinion).

Regards

(Message edited by Perro! on 18 February, 2012)
Top of pagePrevious messageNext messageBottom of page Link to this message

bruce
Frequent Contributor
Username: bruce

Post Number: 763
Registered: 04-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Saturday, 18 February, 2012 - 12:58 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

OK guys, that was your starter for 10; now the tricky bit....

I think I understand both the if...else and the 'conditional' statements ( well, the general idea ). You look at the state of the PORT pin and, in general terms, ask a question about it. If the answer is right, do one thing; if it's wrong, do something else.
In this specific case, of course, the pin is only either 0 or 1.
The next part of the software decides whether the answer you got is TRUE or FALSE. If it's TRUE then you set the pin to 0, otherwise it's FALSE and you set it to 1.
So ( I hope you're with me ) the burning question you need to ask is: is PORTX.1 a 1?
I can see, in the blink of an eye, that:

IF PORTX.1 = 1 should be a statement of the state of the pin and is either TRUE or FALSE. But I realise the syntax is wrong. It must be:

IF PORTX.1 == 1 ( I'm working on that )

But how does 'if(PORTX.1)' work?
Or, put it another way: why is:
PORTX.1 = PORTX.1 untrue? Looks OK to me.

I hope I've explained myself better,

bruce
Top of pagePrevious messageNext messageBottom of page Link to this message

alexr
Frequent Contributor
Username: alexr

Post Number: 200
Registered: 02-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Saturday, 18 February, 2012 - 03:51 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

The single equal sign is an assign statement, it assigns the right hand side of the statement to the left hand side so the statement if(portx.1 = 1) would result in portx.1 being set to a value of 1. Since 1 is considered true, the if statement would always be true regardless of the initial value of portx.1

The double equal sign is a test for equality. The statement if(portx.1 == 1) tests the value of portx.1 and if is equal to 1 then it carries out the next instruction.

The statement if(portx.1) tests portx.1 for true or false. A value of 0(zero) is considered false, any non-zero value is considered true.

The statement portx.1 = portx.1 does nothing or to be more specific it is assigning the present value of portx.1 to portx.1 Any half descent compiler would either throw up an error or simply optimise the statement out.
Alex
Top of pagePrevious messageNext messageBottom of page Link to this message

foxyrick
Member
Username: foxyrick

Post Number: 8
Registered: 01-2012

Rating: N/A
Votes: 0 (Vote!)

Posted on Saturday, 18 February, 2012 - 03:55 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

(oops, beaten to it. Must type faster!)

May I help out here?

In C, a single = is an assignment operator. A=3 sets the value variable A to be 3.

A double equal sign is a relational operator, testing for equality. The result of the whole expression is a logical value (TRUE or FALSE).

The result of the relational operator is then acted on by the IF, FOR, WHILE, etc.

So, in the expression (A==1), the result of that will be TRUE if A is 1, and FALSE if A is not 1.

Also, one can simply write the expression (A) which will return the value TRUE if A is anything other than zero, and FALSE if A is zero. That is by definition in the language, that zero will be FALSE and anything else will be TRUE.

That's why the if(PORTX.1) works. It's effectively the same as writing if(PORTX.1 == 1) since it can only be 0 or 1.

C is full of shorthand like that; I think it makes it easier and quicker to read, once one is used to it all! Unfortunately, that can take a while and the code can look quite convoluted at first.

Does that make sense?

(Message edited by foxyrick on 18 February, 2012)
Top of pagePrevious messageNext messageBottom of page Link to this message

foxyrick
Member
Username: foxyrick

Post Number: 10
Registered: 01-2012

Rating: N/A
Votes: 0 (Vote!)

Posted on Saturday, 18 February, 2012 - 04:40 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Another thing to be aware of in these cases is operator precedence.

Everything has a priority, relative to everything else. Assignment has the lowest, so is done last. That's why A=B*3 works to make A the result of B*3. = has a lower priority that *, so B*3 is done before the A= part.

Looking at your two examples from the OP:

PORTX.1 = !PORTX.1

So, the operator precedence is to do the ! (logical not operator or inverter) before the = (assignment operator). Thus , the value of PORTX.1 is inverted with the result being stored temporarily in some register which the compiler takes care of for you (PORTX.1 is not changed immediately by the ! operator), then that value is assigned to PORTX.1 from the temporary register.


The other example can also be looked at in terms of precedence:

PORTX.1 = PORTX.1 ? 0:1

Here, the order of doing things is that the ? (conditional operator) happens first. The PORTX.1 to the right of the = is the relational operator and, in this case, is the only thing there so it is simply a logical test of PORTX.1's current value. It's like the (A) from my examples above.

So, if the current value of PORTX.1 evaluates to TRUE (i.e. it is 1) then first expression in the two options will be evaluated. If FALSE, then the second option will be evaluated. In this case the options are simply 0 and 1.

Thus, if PORTX.1 is currently 1 (TRUE) then the first option is evaluated, returning 0 for the whole expression [PORTX.1?0:1].

That returned value is finally used for the assignment operator, which puts that value in PORTX.1 so it gets the new value. Remember that PORTX.1 is not changed until that point - all the calculations are done in temporary registers/memory.

(Message edited by foxyrick on 18 February, 2012)
Top of pagePrevious messageNext messageBottom of page Link to this message

bruce
Frequent Contributor
Username: bruce

Post Number: 764
Registered: 04-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Monday, 20 February, 2012 - 10:15 am:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Cant thank you guys enough for your help, although I'm still trying to get my head around the syntax, as, to be honest, I'm still not comfortable with it.
Unfortunately, another project has priority right now over fun and games. When that's done, I'll get back to my PORT, probably over a glass of Port.

bruce
Top of pagePrevious messageNext messageBottom of page Link to this message

davejs
Regular Contributor
Username: davejs

Post Number: 35
Registered: 09-2009

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 21 February, 2012 - 11:37 am:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Bruce
I know this will derided by all the C programmers out there, but if you are finding the syntax drives you mad, it may be worth giving Oshonsoft Basic a try - it is cheap (and free to try), is pretty powerful, has simple syntax, a very good simulator, loads of hardware drivers (serial ports, RC servos, stepper motors, etc.) and once you've got used to its unusual IDE easy to use.
Dave
Top of pagePrevious messageNext messageBottom of page Link to this message

motchjv
Frequent Contributor
Username: motchjv

Post Number: 64
Registered: 12-2011

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 21 February, 2012 - 12:47 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

I see pascal is available for pic programming from Mikropascal. The problem is you need their programmer, dosn't work with a pickit. Pascal is a bit easier to learn than C

John
Top of pagePrevious messageNext messageBottom of page Link to this message

bruce
Frequent Contributor
Username: bruce

Post Number: 766
Registered: 04-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 21 February, 2012 - 11:40 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Hello guys,
I appreciate your input, but I'm going to struggle on with 'C'. I did start doing some BASIC programming ( I used the Amicus compiler ), but had become increasingly exasperated that virtually every site I Googled for projects was using 'C'. Even Microcip themselves are dedicated to it, so I figure it's time to try and master it. I mean, how difficult can it be? ( answers on a post-card... )

bruce

Administration Administration Log Out Log Out   Previous Page Previous Page Next Page Next Page