新建一个Arduino程序。可是建完就郁闷了,因为只看到了setup和loop函数,却没有基本的c函数。

void setup() {// put your setup code here, to run once:
}void loop() {// put your main code here, to run repeatedly:
}

于是好奇心就来了,当然对于开源代码来说这个没有什么秘密。查一下源代码就知道了。
       从配置文件来看,核心代码在cores\arduino下。进入代码目录可以看到这里各个文件都是按照功能来命名的,所以很好辨认。很容易就能找到main.cpp,我们打开来看看具体内容:

int main(void)
{init();#if defined(USBCON)USBDevice.attach();
#endifsetup();for (;;) {loop();if (serialEventRun) serialEventRun();}return 0;
}

看到我们熟悉的main函数了吧,同时看到main函数里在初始化时调用了setup函数,在for循环里调用了loop函数,所以这下大家明白了为什么在arduino中写代码的时候只看到setup和loop函数了吧,setup函数和loop函数已经预调用了。

接下来再打开一个最简单的例子Blink。

int led = 13;// the setup routine runs once when you press reset:
void setup() {               // initialize the digital pin as an output.pinMode(led, OUTPUT);
}// the loop routine runs over and over again forever:
void loop() {digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)delay(1000);               // wait for a seconddigitalWrite(led, LOW);    // turn the LED off by making the voltage LOWdelay(1000);               // wait for a second
}

这个代码原理很简单,把引脚13设置成输出,然后使用for循环,在13脚交替输出高低电平;这个逻辑很好理解。但是这其中又有疑问了;写过avr c代码的同学肯定都知道,一般对某个端口或者引脚操作都是使用DDRX,PORTX,PINX来操作的,为什么这里可以直接用数字来操作呢?
       接下来继续分析一下pinMode这个函数,这个函数在cores\arduino\Wiring_digital.c文件里。

void pinMode(uint8_t pin, uint8_t mode)
{uint8_t bit = digitalPinToBitMask(pin);uint8_t port = digitalPinToPort(pin);volatile uint8_t *reg, *out;if (port == NOT_A_PIN) return;// JWS: can I let the optimizer do this?reg = portModeRegister(port);out = portOutputRegister(port);…………
}

我只贴出了主要功能函数,其它部分代码感兴趣的可以自己去研究。这里可以看出主要函数是digitalPinToBitMask,digitalPinToPort,portModeRegister,portOutputRegister这几个。本着打破砂锅问到底的精神,我们继续搜索这几个函数的实现,这下可以看到是4个宏。

#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )

对于pgm_read_byte这个函数说明如下:

读取指令pgm_read_xxx宏定义其实就是一段包括了flash读取指令的内联汇编代码。函数原型为:

pgm_read_byte(address_short);pgm_read_word(address_short);pgm_read_dword(address_short);pgm_read_float(address_short);//括号中是地址值。

本文的关键,不是pgm_read_byte这个函数,而是pgm_read_byte这个函数里面的参数:digital_pin_to_port_PGM,digital_pin_to_bit_mask_PGM,pgm_read_word( port_to_input_PGM,pgm_read_word( port_to_mode_PGM。看看这四个参数的定义在哪里。

经过搜索发现在   hardware\arduino\variants\leonardo\ Pins_arduino.h里,是不是很眼熟呀,是的,就是讲配置文件的时候讲过这个文件作用。

所以不难发现,arduino是是先把各个芯片的端口和引脚的映射关系都定义成几个表格,这几个表格把引脚所在的位置作为索引,在使用的时候通过引脚位置,通过查表得到对应的功能寄存器。然后就可以设置输出输入模式,设置输入输出电平,对于arduino来说只需要告诉它需要操作哪个引脚,以及要怎么操作。而不需要去关心这个引脚在哪个port上,是在PORTA还是在PORTB,更不用关心这个芯片是什么型号。
       对于芯片的定时器,pwm等基础功能arduino都是按照这种方式实现的。就不再多说了。有了这些相信各位同学对arduino的使用会更加得心应手。

Arduino 代码机制相关推荐

  1. 【点灯科技+esp8266+小爱同学】实现语音控制的米思齐代码和arduino代码

    以下转换后的arduino代码. #define BLINKER_WIFI #include <Blinker.h> char auth[] = "点灯分配的密钥"; ...

  2. 基于HTTPS长连接的ESP32+VS1053网络电台收音机Arduino代码

    基于HTTPS长连接的ESP32+VS1053网络电台收音机Arduino代码 代码下载地址:ESP32+VS1053网络电台收音机Arduino完整源代码.-硬件开发文档类资源-CSDN下载 硬件搭 ...

  3. Arduino 代码示例 -- 光电开关

    Arduino 代码示例 光电开关 型号:E18-D80NK 接线:棕色(红色)接正极,黑色接信号,蓝色接负极. 特点:检测到目标时低电平输出,未检测高电平输出.检测距离可以调(扭后面的一个小螺丝). ...

  4. arduino代码运行时间测试函数,代码性能运行时间测试方法

    先感谢"皮皮学电子"同学的帮助,秒回完美快速的解决了我的问题(难得遇到明白人).我在GitHub上找了半天,以为需要额外的库函数调用定时器才能实现代码运行时间的测试功能,没想到ar ...

  5. 【arduino】arduino代码运行时间测试函数,代码性能运行时间测试方法

    先感谢"皮皮学电子"同学的帮助,秒回完美快速的解决了我的问题(难得遇到明白人).我在GitHub上找了半天,以为需要额外的库函数调用定时器才能实现代码运行时间的测试功能,没想到ar ...

  6. arduino代码_纯纯小白开发arduino--我的调试经验

    arduino 是什么我就不做介绍了.这里的小白并不是说我没有嵌入式开发经验而是说从来没有实际开发过arduino.虽然它在世界范围内都很流行,可是不知为何国内专业做嵌入式开发的人对它大多都嗤之以鼻. ...

  7. arduino代码_arduino智能小车项目——01、配件介绍及代码部分教程

    各位小伙伴大家好: 本期我们开始制作智能小车项目,这因该是资源包里面难度相对较大的项目. 所以我们从易到难把项目进行分解,先从实现较为简单的功能开始. 本期我们的目标是实现小车的自主运动,代码部分也相 ...

  8. 米斯齐超声波传感器显示测量距离(oled)内附Arduino代码

    用到的东西:     超声波传感器,uno,SSD1306 OLED显示屏 超声波:gnd-gnd              vcc-5v              trig-接脚这里是A0     ...

  9. 180°和360°伺服电机速度控制,转向控制Arduino代码与库(亲测可用)

    写在前面的话:如果你只想要我代码,建议你复制粘贴第一个和最后一个,试试.如果你想学习以后如何解决类似问题而不是仅仅的抄代码,建议你读完我啰嗦的话.希望对你有所帮助.你可以抄袭我代码,但请添加出处/引文 ...

最新文章

  1. android native堆内存泄露,Android Native内存泄露检测
  2. 西安交通大学计算机科学与技术学科评估,西安交通大学学科评估排名!附西安交大a类学科名单...
  3. 在Python中实现SVM分类
  4. oracle锁表导致update,delete,insert出现无反应的问题
  5. jdbc获取结果行数_如何获取JDBC中的行数?
  6. Windows 7 X64平台编译LLVM+clang
  7. VTK:Points之PoissonExtractSurface
  8. Bootcamp Mac 安装Win10 教程
  9. 随机函数(Pascal入门)
  10. vscode 调试 PHP 打造PHP本地开发环境
  11. 总结之使用lowagie.text添加PDF水印
  12. jQuery支持移动触摸设备的Lightbox插件
  13. 新媒体运营工具大盘点,收藏方便不备之需!
  14. css美化浏览器默认滚动条样式
  15. 关于getc与fgetc和getchar的本质区别
  16. 社交产品分析:共同看片,微光
  17. 联想拯救者新款 R9000X价格是多少 配置强不强
  18. 视频断点续传+java视频
  19. Android-AQS
  20. 低频125KHZ|134.2KHZ安卓手持机|RFID智能终端CK-LH100-SYS性能与应用方案

热门文章

  1. Oracle(3)——Oracle图形界面工具创建数据库
  2. ASP.NET MVC 在控制器中获取某个视图动态的HTML代码
  3. VUE组件 之 Drawer 抽屉
  4. iOS 二叉树相关算法实现
  5. java类与对象 —(10)
  6. 《深入理解Java虚拟机》读书笔记八
  7. 架构设计杂谈004——架构师
  8. SQLSEVER 中的那些键和约束
  9. CANVAS运用-对图片的压缩上传(仅针对移动浏览器)
  10. Code First02---CodeFirst配置实体与数据库映射的两种方式