learing:advanced:2016042501
两侧同时换到之前的修订记录前一修订版 | |
zh:learing:advanced:2016042501 [2016/04/25 09:40] – 弘毅 | learing:advanced:2016042501 [2023/06/07 04:23] (当前版本) – 外部编辑 127.0.0.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> |