Port problems on dsPIC33FJ128MC802

I have a problem that is driving me nuts. I am sure, that there is someting I just don't get, but can someone please tell me what?

That setup is a dsPIC33FJ128MC802 which I try to program in C.

I have the following code (Let's assume that everything is setup and all ports are digital and outputs).

If I write this in my code:

PORTA = 3;

and take my measure thingy (danish for multimeter, I can see that Port a0 and a1 is high as expected. If I single step using the PIC simulator, I can see that PORTA is 0000011.

If I write this in my code:

PORTAbits.RA0 = 1;
PORTAbits.RA1 = 1;

and take my measure thingy, Port A0 is low and A1 is high. BUT, if I single step using the PIC simulator, I can see that PORTA is 00000011. Which should indicate that port A0 should be high too.

Someone please enlighten me.

 

 

 

Got it. I’ll explain here,

Got it. I’ll explain here, in case someone else needs an answer to this.

For some reason that is buried in the datasheet, you can’t switch on two bits after another. You need a NOP instruction between, so the way to do it is either do the bitworks in a separate variable and modify PORTA in one go or

PORTAbits.RA0 = 1;
ASM(“NOP”);
PORTAbits.RA1 = 1;

Sorry

I wonder if this is the same problem Fritsy speaks of elsewhere in PicAXE. I think he has a bit somewhere which is always the opposite of what he expects it to be. Can’t quite remember.

Anyway, if you really want to optimise and set two bits one after the other, try this inline assembler:

ASM(“BSET PORTA, 0”)

ASM(“BSET PORTA, 1”)

That’s the code to set the two bits individually. I don’t know if it will work inline (I don’t know if PORTA is defined by your C preprocessor). If it doesn’t, you could try:

ASM(“BSET 0x02C2, 0”)

ASM(“BSET 0x02C2, 1”)

Where 02C2 is the address of the PORT A register. (I dunno in your compiler if this has to be decimal or hex.)

Fingers crossed: I’ve only ever used the 8-bit RISC before; never used the dsPIC33 variations…!

Thanks,I checked the

Thanks,

I checked the disassembly of my own code and it compiles into the two instructions that you write, so it is optimized.

The datasheet states, in section 10.2.1 that “One instruction cycle is required between a port direction change or port write operation and a read operation of the same port”. I don’t know how the BSET instruction works, but if it reads the port, modifies the bit and writes the new value back, the last thing the first instruction does is write to the port and the first thing the second instruction does is a read, which is a violation of the statement in 10.2.1 and the NOP is required to “calm things down” between the two operations.

Interesting

Oh, so although I correctly guessed the assembly, it wouldn’t have worked anyway. I haven’t read up on BSET, but the 8-bit RISC equivalent, BSF operates over 4 Q-cycles and it is, indeed, a read->modify->write.

Incidentally, if anyone’s wondering, that’s why a PIC running a 4MHz clock only processes instructions at 1MHz. Each instruction takes four clock cycles. Typically, the first is a decode operation, followed by a read of a memory location or a literal, a modification or processing step and a write back to the memory.

Note to anyone who hasn’t fallen asleep yet: jumps take twice as long to execute as any other instruction.