I recently decided to learn direct port manipulation instead of builtin arduino routines.
First I tried this piece of code
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("on");
delay(500);
digitalWrite(LED_BUILTIN, LOW);
Serial.println("off");
delay(500);
}
This program on running instantly established connection with the serial monitor on my arduino IDE.
But when I try this code
int main(void)
{
Serial.begin(9600);
DDRB = B11111111;
while(1)
{
PORTB = PORTB | 0x20;
Serial.println("off");
_delay_ms(500);
PORTB = PORTB & 0xDF;
Serial.println("on");
_delay_ms(500);
}
}
But this program is taking some time, about 5-10 seconds to establish serial connection. Also delay() is not working too. When I use delay() instead of _delay_ms(), the entire arduino board freezes like a computer and stops blinking the LED instead LED is fully ON.
I tried is on several programs, while "setup-loop" program connects instantly, AVR C programs does not.
why does it happen?
1 Answer 1
By defining your own main()
you are circumventing the Arduino startup procedures.
Normally with Arduino code main()
first runs an init()
function before setup()
and (repeatedly) loop()
. This init()
function will configure, amongst other things, the timer for millis()
and delay()
.
This is the normal main()
for a basic AVR-based board:
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
It first initializes common functions, then board-specific ones (normally nothing), and if applicable, the USB interface (for ATMega32U4 based boards, like the Leonardo).
Only then does it go on to run your sketch.
If you want to use both your own main()
and Arduino functions like delay()
then you will have to call those initialization routines before running the rest of your code.
-
Could you explain the significance of "serialEventRun"?User– User2020年08月09日 16:45:07 +00:00Commented Aug 9, 2020 at 16:45
-
If you haven't defined a
serialEvent()
function then it has no significance at all. If you have defined one then it runs it.Majenko– Majenko2020年08月09日 16:53:21 +00:00Commented Aug 9, 2020 at 16:53 -
What is the purpose of initVariant()?User– User2020年08月09日 16:55:08 +00:00Commented Aug 9, 2020 at 16:55
-
1That is the bit where I say
then board-specific ones (normally nothing)
Majenko– Majenko2020年08月09日 17:03:23 +00:00Commented Aug 9, 2020 at 17:03 -
I just rewrote my code to include just init() and nothing else, the serial communication, both read and write, is now working. So my question, is USBDevice.attach() necessary?User– User2020年08月09日 17:15:59 +00:00Commented Aug 9, 2020 at 17:15
main()
initializes all the appropriate hardware and timers. You're circumventing that with your ownmain()
so nothing Ardunioy works.