fastest way to flip a bit in I/O port, atmega328, using C?

Thread Starter

mikewax

Joined Apr 11, 2016
230
Hello i'm trying to toggle a bit on my arduino CPU, the port B bit 0, i'm programming in C, and i wanna find an instruction that will take less than 100ns to execute.
so far what i have is:
"PORTB = 0" and "PORTB = 1"
both of these instructions are executing in about 120ns, according to my rough measurement.
anyone know a faster way to do this operation?

thanx, mike
 

Thread Starter

mikewax

Joined Apr 11, 2016
230
Which version arduino are you using? 120nS sounds like you may be using one with an 8MHz clock. If that is so, then is as fast as it's going to get. You could swap to a faster chip.
https://www.arduino.cc/en/Products/Compare
it's an Olimexino-328, with a 16MHz crystal, and yeah i'm gonna eventually be using an STM32F0406 processor, but for now i'm stuck with the 328 chip. i hope i can find a way to do it.
 

MrChips

Joined Oct 2, 2009
34,628
Why are you stuck with an ATmega328?
Get a STM32F4DISCOVERY and you will ask yourself why you didn't switch sooner.
 

Thread Starter

mikewax

Joined Apr 11, 2016
230
When it comes down to it clock speed will have a bearing.
This may be a good read if you have not already seen it.
http://forum.arduino.cc/index.php?topic=4324.0
yeah that's a good (but real slow) read. i haven't yet seen any methods that were faster. so it appears that the "PINx = " and the "PORTB = " instructions are both gonna take two clock cycles to execute, so that's 125ns. and maybe that's just the best i can do.
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,237
Not an expert on this. I haven't programmed in assembly since the advent of the original TRS-80.

But would using inline assembler be any faster? There are several threads on the Arduino forum about toggling a pin that way.
 

Thread Starter

mikewax

Joined Apr 11, 2016
230
Ya can't write to an input register. What kinda nonsense you peddlin'
it's a "trick" that's mentioned in the atmega data sheet.
"The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register."
apparently some of the guys at the arduino forum have done this. but it still takes two cycles to execute :-(
 

Papabravo

Joined Feb 24, 2006
22,058
well that's giving me an error:

"PORTB.0=~PORTB.0;
^ (pointing at the 0)
error: expected ';' before numeric constant"

dunno the right syntax.
The notation is a common "C" extension for processors with bit addressing instructions like Complement Bit (CPL). The compiler has to be smart enough to have the syntax and semantics for using bit instructions. There is a complement bit instruction in the instruction set. Get yourself a full featured compiler if you want to push the envelope. Better yet learn to code in assembly language. Then you'll know for sure what you can and cannot do.
 

Papabravo

Joined Feb 24, 2006
22,058
You're trying to change the value of a constant, aren't you with that snippet ?
No! The C fragment should compile to a single read-modify-write instruction that writes the complement of PORTB, bit 0, back into the Port latch without affecting the other bits in PORT B. There is at least one compiler in the wild that does it that way.

A really good optimizing compiler might generate a single instruction for:

PORTB ^=1 ;

but then again it might generate the three instruction stupid way of doing it.
 

Thread Starter

mikewax

Joined Apr 11, 2016
230
Not an expert on this. I haven't programmed in assembly since the advent of the original TRS-80.
But would using inline assembler be any faster? There are several threads on the Arduino forum about toggling a pin that way.
i know what you mean, i had and old Atari. but WTF if i can do it with just one cycle i'll try editing the assembly code. If, that is, i can figure out how.
 

Papabravo

Joined Feb 24, 2006
22,058
it's a "trick" that's mentioned in the atmega data sheet.
"The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register."
apparently some of the guys at the arduino forum have done this. but it still takes two cycles to execute :-(
Is this true for ALL AVR and ATMega parts? Maybe only some of the newer ones?
 

Thread Starter

mikewax

Joined Apr 11, 2016
230
The notation is a common "C" extension for processors with bit addressing instructions like Complement Bit (CPL). The compiler has to be smart enough to have the syntax and semantics for using bit instructions. There is a complement bit instruction in the instruction set. Get yourself a full featured compiler if you want to push the envelope. Better yet learn to code in assembly language. Then you'll know for sure what you can and cannot do.
i've used assembler before and DAMN what a PITA! but if there's a way to edit one of the compiler files and recompile, i might be able to pull it off.
 

Papabravo

Joined Feb 24, 2006
22,058
The notation is a common "C" extension for processors with bit addressing instructions like Complement Bit (CPL). The compiler has to be smart enough to have the syntax and semantics for using bit instructions. There is a complement bit instruction in the instruction set. Get yourself a full featured compiler if you want to push the envelope. Better yet learn to code in assembly language. Then you'll know for sure what you can and cannot do.
EDIT: There is a complement bit instruction on some processors, but apparently not on this one. I've been writing code in C so long I sometimes forget what's under the hood. If writing 1 to the PINB register will toggle the output then that probably as good as you're going to be able to do. Don't forget that the instruction fetch is overlapped with the execution of the previous instruction so you have to take that into account.

I apologize for the misdirection.
 
Top