用户工具

站点工具


learing:advanced:2016042501

深入了解setup()与loop()函数

如果大家在学校学过C语言,就知道一定会有一个main()函数。但我们在给控制器编写程序时使用的是setup()与loop(),main()函数去哪里了?

我们从源码上一探究竟!

以OCROBOT 0005 IDE为例,我们打开IDE的hardware\avr\cores\avr\main.cpp文件,可以看到如下代码

#include <Arduino.h>
 
int main(void)
{
  init();
 
#if defined(USBCON)
  USBDevice.attach();
#endif
 
  setup();
 
  for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
  }
 
  return 0;
}

这是一个标准的C语言代码,main()是我们的主函数,符合C99的main()函数标准。

int main( void )  /* 无参数形式 */
{
    ...
    return 0;
}

如果有一些C语言基础,大家就可以理解setup()与loop()函数了,setup()是在main()的初始化部分,所以只运行一次。而loop()函数在for循环中。

for(;;)语句相当于while(1)语句即不设初值,不判断条件,循环变量不增值,无终止地执行循环体。

那么在setup()之前代码

  init();
 
#if defined(USBCON)
  USBDevice.attach();
#endif

是做什么用的?

在hardware\avr\cores\avr\wiring.c中我们可以找到init()的函数定义。它主要是对单片机寄存器进行一系列的初始化。所以需要运行于setup()之前。

在hardware\avr\cores\avr\USBCore.cpp中我们可以找到USBDevice.attach()的定义。它主要是针对自带USB端口的如ATmega32U4等MCU的USB部分进行初始化,以保证其正常工作。

在loop()之后的

    if (serialEventRun) serialEventRun();

是做什么用的呢?

在\hardware\avr\cores\avr\HardwareSerial.cpp中我们可以找到serialEventRun()的定义。

void serialEventRun(void)
{
#ifdef serialEvent_implemented
  if (Serial.available()) serialEvent();
#endif
#ifdef serialEvent1_implemented
  if (Serial1.available()) serialEvent1();
#endif
#ifdef serialEvent2_implemented
  if (Serial2.available()) serialEvent2();
#endif
#ifdef serialEvent3_implemented
  if (Serial3.available()) serialEvent3();
#endif
}
learing/advanced/2016042501.txt · 最后更改: 2023/06/07 04:23 由 127.0.0.1