MicroC Bit replacemnt.

Status
Not open for further replies.

aljamri

Member
Hi,

again I'm using Mikroc and doing the following command:

if (PORTA.F2 = 1) PORTB.F4 = 1 ; else PORTB.F4 = 0 ;

Instead of the non clear term "PORTA.F2", I want to write a meaningful term like "S1".


I've tried:

S1 = PORTA.F2;

but not sucsed.

then tried adding assembly piece:

asm {
# define S1 PORTA,2
}

but then error message came " assinging to non I value"

my question is : how to replace PORTA.F2 with S1?

Thanks
 
if (PORTA.F2 = 1) PORTB.F4 = 1 ; else PORTB.F4 = 0 ;
should be
if (PORTA.F2 == 1) PORTB.F4 = 1 ; else PORTB.F4 = 0 ;

Do the define in C not ASM

#define S1 PORTA.F2
 
Last edited:
Thank you 3v0,

but what is the difference between PORTA.F2 == 1 and PORTA.F2 = 1 ?

= is an assignment operator, the left hand side is assigned the value of the expression on the right hand side

== is a comparison operator as are >, <, >=, <= etc


**broken link removed**
 
Last edited:
I tried both = and == and got the same results:

the following code is to make switches (S1-S5) control LEDs (L1-L5):

Code:
Loop:                    // loop starts again and again
        if (S1 == 1) L1 = 1 ; else L1 = 0 ;
        if (S2 == 1) L2 = 1 ; else L2 = 0 ;
        if (S3 == 1) L3 = 1 ; else L3 = 0 ;
        if (S4 == 1) L4 = 1 ; else L4 = 0 ;
        if (S5 == 1) L5 = 1 ; else L5 = 0 ;
goto loop;    }

gave me same result as this code:

Code:
Loop:                    // loop starts again and again
        if (S1 = 1) L1 = 1 ; else L1 = 0 ;
        if (S2 = 1) L2 = 1 ; else L2 = 0 ;
        if (S3 = 1) L3 = 1 ; else L3 = 0 ;
        if (S4 = 1) L4 = 1 ; else L4 = 0 ;
        if (S5 = 1) L5 = 1 ; else L5 = 0 ;
goto loop;    }

any way both of them did what I need, thank you 3v0, both suggestion were from you.
 
Last edited:
This should also do the same thing:

Code:
Loop:
    L1 = S1;
    L2 = S2;
    L3 = S3;
    L4 = S4;
    L5 = S5;
goto loop;
 
Last edited:
Code:
Loop:                    // loop starts again and again
        if (S1 = 1) L1 = 1 ; else L1 = 0 ;
        if (S2 = 1) L2 = 1 ; else L2 = 0 ;
        if (S3 = 1) L3 = 1 ; else L3 = 0 ;
        if (S4 = 1) L4 = 1 ; else L4 = 0 ;
        if (S5 = 1) L5 = 1 ; else L5 = 0 ;
goto loop;

In this code the code "S1=1" .. "S5 =1" will always evaluate to 1 which is seen as true in C.
So all of these if statments could be written as "if(1)" so you code is the same as

Code:
Loop:                    // loop starts again and again
        if (1) L1 = 1 ; else L1 = 0 ;
        if (1) L2 = 1 ; else L2 = 0 ;
        if (1) L3 = 1 ; else L3 = 0 ;
        if (1) L4 = 1 ; else L4 = 0 ;
        if (1) L5 = 1 ; else L5 = 0 ;
goto loop;

Given that the code now has all "if(1)"'s we know they will always be true and write the code as suggested by Ian

Code:
Loop:
    L1 = S1;
    L2 = S2;
    L3 = S3;
    L4 = S4;
    L5 = S5;
goto loop;

But if you use the == operator in the if statements the result will depend on the value of variables S1 .. S5. So the = and == operators do different things and you must use the correct one.
 
The reason that the single equals works is because it is testing an input. Writing 1 to an input has no effect and so the if looks at the pin value.

BTW, how is S1 more meaningful than PORTA.F2?

Mike.
 
I wrote some code last week and used a bunch of #defines like this found myself wanting to use the port pin names. I then started to think about this and realized that i didn't have any more chips and that's where them #defines shine change only in one place the port pins like from PORTB to PORTC in my case.

But I don't think it was meaningful, maybe a name like SW_RB0 or something like that. But then if you change ports.

So a SW0 goes on any PORTX.0 pin would be the way to go

I was going to post it's a input is why it worked,But Mike pointed that out I wouldn't use the one = even if it works because you'll run into places it doesn't work and wonder for hours why.

I've done that often using C and C++ seeing I used basic and it doesn't care if it's one = it looks at how your using. C is looking a lot better the more I use it.
 
Last edited:
BTW, how is S1 more meaningful than PORTA.F2?
Mike.

Hi Pommie,
I did this as college assignment, starting with circuit, flow chart, up to the program. For user friendly terms, I've used SW1 to indicate switch 1 rather clear than PORTA.F2that only Pic hobbies know.
 
I was thinking that Switch1 would be more meaningful than S1. ( I'm not sure when S1 turned into SW1).

Mike.
 
The reason that the single equals works is because it is testing an input. Writing 1 to an input has no effect and so the if looks at the pin value.
...

I get your point Pommie but is that really correct? I thought the compiler would convert
if(blah = 1)
to a statement that writes 1 to blah then always executes the if() as it must be 1, ie always true?

I assume that as the compiler is pretty dumb regarding what is an input and what is not, so it would treat most labels the same.

In MikroC from what I have seen it seems to treat PIC ports just as another memory location and make the same compiled code for anything which is a port (or hardware register) or a RAM location. The compiler just handles the bank selecting if needed and reads/writes that location.
 

I assume the port pins are defined as volatile and so no assumption would (should) be made.

Mike.
P.S. sorry for late reply - been busy.
 
Thanks Pommie. I just tested this in MikroC (target 16F877A);
Code:
void main()
{
  if(PORTB = 1)
  {
    PORTA = 0xFF;
  }
}

and it compiles to;

Code:
;Led_Blinking.c,20 :: 		void main()
;Led_Blinking.c,22 :: 		if(PORTB = 1)
$0004	$3001			MOVLW	1
$0005	$1303			BCF	STATUS, RP1
$0006	$1283			BCF	STATUS, RP0
$0007	$0086			MOVWF	PORTB
$0008	$0806			MOVF	PORTB, 0
$0009	$1903			BTFSC	STATUS, Z
$000A	$280D			GOTO	L_main_0
;Led_Blinking.c,24 :: 		PORTA = 0xFF;
$000B	$30FF			MOVLW	255
$000C	$0085			MOVWF	PORTA
;Led_Blinking.c,25 :: 		}
$000D	$	L_main_0:
;Led_Blinking.c,26 :: 		}
$000D	$280D			GOTO	$

So it looks as though first 1 is assigned to PORTB, then the if() is done by PORTB being tested for true or false by the MOVF,F and the result will depend on how PORTB is read.

So you were correct if PORTB is an input the if() test can actually test the inputs, however it won't test for if(PORTB==1) it will actually test if(PORTB!=0) and will include ALL input AND output pins! Pretty nasty.

(edit) I just tested with a variable and I was wrong there the variable is treated differently;
Code:
;Led_Blinking.c,23 :: 		if(foob = 1)
$0004	$3001			MOVLW	1
$0005	$1303			BCF	STATUS, RP1
$0006	$1283			BCF	STATUS, RP0
$0007	$00A0			MOVWF	_foob
;Led_Blinking.c,25 :: 		PORTA = 0xFF;
$0008	$30FF			MOVLW	255
$0009	$0085			MOVWF	PORTA
;Led_Blinking.c,26 :: 		}
$000A	$	L_main_0:
;Led_Blinking.c,27 :: 		}
$000A	$280A			GOTO	$

The optimiser removed the if() test. As you said the PORT was treated as volatile and if I changed the variable foob to volatile the result was the same as the PORT example.
 
Last edited:
Here's how BoostC does it (on a 16F1828 target);

Code:
   void main()
   {
     if(portb = 1)
0078  3001  	MOVLW 0x01
0079  0020  	MOVLB 0x00
007A  008D  	MOVWF gbl_portb
       porta = 255;
007B  30FF  	MOVLW 0xFF
007C  008C  	MOVWF gbl_porta

So BoostC doesn't treat PORTB as volatile, correct?
 
Last edited:
It sure appears that way. However it might also be the optimiser which is usually done in pre-processing, so if the optimiser assumed the if() would always be true it might be removing the if() test, and basically overriding whether the variable is volatile or not because there is no longer a test on the variable.

Thanks for the example Mike that was pretty much what i assumed the compiler would do to it which i said in post #12.
 
So you were correct if PORTB is an input the if() test can actually test the inputs, however it won't test for if(PORTB==1) it will actually test if(PORTB!=0) and will include ALL input AND output pins! Pretty nasty.

Good job the OP had if(PORTA.F2=1) as that will behave (seemingly) "correctly".

I'm surprised at BoostC as the include file has volatile char portb @PORTB; and so it shouldn't have optimized it.

Mike.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…