用户工具

站点工具


learing:advanced:2016042501

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
zh:learing:advanced:2016042501 [2016/04/25 09:03] 弘毅learing:advanced:2016042501 [2023/06/07 04:23] (当前版本) – 外部编辑 127.0.0.1
行 1: 行 1:
 +====== 深入了解setup()与loop()函数 ======
 +如果大家在学校学过C语言,就知道一定会有一个main()函数。但我们在给控制器编写程序时使用的是setup()与loop(),main()函数去哪里了?
  
 +我们从源码上一探究竟!
 +
 +以OCROBOT 0005 IDE为例,我们打开IDE的hardware\avr\cores\avr\main.cpp文件,可以看到如下代码
 +<code cpp>
 +#include <Arduino.h>
 +
 +int main(void)
 +{
 +  init();
 +
 +#if defined(USBCON)
 +  USBDevice.attach();
 +#endif
 +
 +  setup();
 +
 +  for (;;) {
 +    loop();
 +    if (serialEventRun) serialEventRun();
 +  }
 +
 +  return 0;
 +}
 +</code>
 +这是一个标准的C语言代码,main()是我们的主函数,符合C99的main()函数标准。
 +<code cpp>
 +int main( void )  /* 无参数形式 */
 +{
 +    ...
 +    return 0;
 +}
 +</code>
 +如果有一些C语言基础,大家就可以理解setup()与loop()函数了,setup()是在main()的初始化部分,所以只运行一次。而loop()函数在for循环中。
 +
 +for(;;)语句相当于while(1)语句即不设初值,不判断条件,循环变量不增值,无终止地执行循环体。
 +
 +那么在setup()之前代码
 +<code cpp>
 +  init();
 +
 +#if defined(USBCON)
 +  USBDevice.attach();
 +#endif
 +</code>
 +是做什么用的?
 +
 +在hardware\avr\cores\avr\wiring.c中我们可以找到init()的函数定义。它主要是对单片机寄存器进行一系列的初始化。所以需要运行于setup()之前。
 +
 +在hardware\avr\cores\avr\USBCore.cpp中我们可以找到USBDevice.attach()的定义。它主要是针对自带USB端口的如ATmega32U4等MCU的USB部分进行初始化,以保证其正常工作。
 +
 +在loop()之后的
 +<code cpp>
 +    if (serialEventRun) serialEventRun();
 +</code>
 +是做什么用的呢?
 +
 +在\hardware\avr\cores\avr\HardwareSerial.cpp中我们可以找到serialEventRun()的定义。
 +<code cpp>
 +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
 +}
 +</code>
learing/advanced/2016042501.txt · 最后更改: 2023/06/07 04:23 由 127.0.0.1