code generated for setting a port bit

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

code generated for setting a port bit

Post by Jerry Messina » Wed Apr 01, 2009 11:26 am

I just noticed that if I use

Code: Select all

dim b as byte
PORTA.0 = b
the compiler generates

Code: Select all

        BSF LATA,0,0
        BTFSS M1_U08,0,0
        BCF LATA,0,0
which results in the port pin always being set high first, which wreaks havoc with my hardware. (It doesn't do this if 'b' is declared as a 'bit').

I've had to result to using

Code: Select all

if (b = 0) then
    PORTA.0 = 0
else
    PORTA.0 = 1
endif
Is this to be expected?

Thanks,
Jerry

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Wed Apr 01, 2009 3:16 pm

First,

Code: Select all

dim b as byte
LATA.0 = b 

Always READ FROM PORTx registers and write to LATx registers (this let you also avoid Read/Write/Modify behaviour of PIC ports) !!!


Second, for your problem,
you are assigning a BYTE variable to a BIT variable. So the compiler has to check lower bit of b (byte) variable and set/reset bit 0 of your port accordingly.

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Apr 01, 2009 3:41 pm

Always READ FROM PORTx registers and write to LATx registers (this let you also avoid Read/Write/Modify behaviour of PIC ports) !!!
SF (at least 2.1.0.1) is nice enough to take care of that automatically for you... if you look at the generated code, you'll see that writing to a "port" actually writes to the LAT register, while reading from the port reads the value of the port pins.
you are assigning a BYTE variable to a BIT variable. So the compiler has to check lower bit of b (byte) variable and set/reset bit 0 of your port accordingly.
I realize that... my issue is with the fact that it first sets the LAT bit HIGH, even if it's going to set it to 0, causing the output pin to toggle.

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Wed Apr 01, 2009 4:05 pm

:shock:
I cant see how it can be done, as the state of PORTA cannot be known when setting one of its bits. The compiler must put the bit in a known state to be able to switch it if needed.

I dont have SF at hand, but what happens if you make your b variable as an ALIAS to the PortA.bit0 ? did the compiler generate the same code?

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Apr 01, 2009 5:00 pm

As I stated, if 'b' is declared as a bit, then the code works as expected...

Code: Select all

dim b as bit
PORTA.0 = b
generates

Code: Select all

?I000003_F000_000024_M000000 ; L#MK PORTA.0 = B
        BTFSC M0_U01,0,0
        BSF LATA,0,0
        BTFSS M0_U01,0,0
        BCF LATA,0,0
and there are no extra writes to the LAT.

I was expecting similar code to be generated when 'b' is a byte... test b and either BSF or BCF the latch bit.
Declaring b as an alias to PORTA.0 sort of defeats the purpose of what I was doing in the rest of the code.

The compiler must put the bit in a known state to be able to switch it if needed.
I disagree... that's the whole problem.

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Wed Apr 01, 2009 10:57 pm

Jerry Messina wrote:Declaring b as an alias to PORTA.0 sort of defeats the purpose of what I was doing in the rest of the code.
Hello Jerry,
I have now an SF under hand and I can do tests.

You could simply solve your problem by aliasing the Bit0 of your b (byte) variable.

Code: Select all


dim b as byte
dim tmpBit as b.0

PORTA.0 = tmpBit 

tmpBit is an alias of your b.0 so you can use it anywhere you want to access bit0 of b variable, and since it's a (it acts like a) bit variable, it gives the wanted result:

Code: Select all

?I000000_F000_000017_M000000 ; L#MK PORTA.0 = TMPBIT
        BTFSC M0_U01,0,0
        BSF LATA,0,0
        BTFSS M0_U01,0,0
        BCF LATA,0,0
?I000001_END; L#MK

Regards

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Apr 01, 2009 11:34 pm

That's one solution. I guess I just wasn't expecting the result I got at first.
It still doesn't seem right to me.

Thanks, octal.

Jerry

Post Reply