Hi,
i have been searching on the forum and could not find my answer so i did a small test using digital output and a scope
The picture is not the best but i can manage to get to 124nano Second or 0.000000124 Second or 0.124 micro second with this code
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
}
void loop() {
PORTB |= B00100000;
PORTB &= B11011111;
delay(10); // wait for 10ms
}
as per the following typical code
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH); // set the LED on
digitalWrite(13, LOW); // set the LED off
delay(10); // wait for a 10ms
}
The fastest that we could get a output was 5 micro second
Your code above is as fast it gets on an Arduino. The compiler optimizer will reckognize these as single bit set/clear requests and code each line using a single cycle AVR assembler instruction.
The AVR's also support a toggle bit instruction and you can code for this in C as follows:
PINB = _BV(5);
This will alternately set/clear bit 5 of PORTB (digital pin 13) and is useful when you need symmetry (50% duty cycle). This compiles to a two cycle assembler instruction.
When using a timer, it is possible to generate a 8MHz (F_CPU /2) square wave output on a 16MHz Arduino. There is also an option to output the cpu clock (16MHz) directly on PB0 (digital pin-8 for AtMega328). The latter requires reprogramming a fuse.
Looks like you are trying to turn an output pin on for the briefest amount of time. Try this variation:
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, LOW); // Make sure the bit is off.
}
void loop() {
PINB = B00100000; // Toggle bit 5 on
PINB = B00100000; // Toggle bit 5 off again
delay(10); // wait for 10ms
}
Wow,
i did try
the PINB =
and the PORTB =
without the OR and the AND
as per robtillaart and johnwasser
and this is the result
half the time (both give me the same result) 62nano seconds
Not too surprising since _BV(5) is just a macro that evaluates to the constant B00100000.
Ok but why does it toggle?
That is what the PINB register does. Toggling an output pin without changing other bits of an output register is a fairly common thing to want to do. The PINA, PINB, PINC... registers are designed make that easy. You just write a byte with 1's where you want pins toggled and 0's where you don't want the pins to change.
From the datasheet:
14.2.2 Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.
where x is the port letter (A,B,C, etc) and n is the bit within the port.
It is indeed that page.
Writing a 1 to an input register bit to toggle the output is not discussed tho. What I posted is from the datasheet and definitely works.