完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
为了让有一定编程基础和开发经验的同学能够快速的上手 Arduino 同时Arduino 新手也可以借此巩固下知识如果你有过类似 51 STM32 NXP 等开发经验,根据本篇文章,可以快速的了解并上手Arduino ,同时对于Arduino新手而言,可以有一个系统的学习。 可结合IDE介绍博客一起学习,更好的掌握Arduino Arduino语言 Arduino使用C/C++编写程序,虽然C++兼容C语言,但这是两种语言,C语言是一种面向过程的编程语言,C++是一种面向对象的编程语言。早期的Arduino核心库使用C语言编写,后来引进了面向对象的思想,目前最新的Arduino核心库采用C与C++混合编写而成。 通常我们说的Arduino语言,是指Arduino核心库文件提供的各种应用程序编程接口(Application Programming Interface,简称API)的集合。这些API是对更底层的单片机支持库进行二次封装所形成的。例如,使用AVR单片机的Arduino的核心库是对AVR-Libc(基于GCC的AVR支持库)的二次封装。 传统开发方式中,你需要厘清每个寄存器的意义及之间的关系,然后通过配置多个寄存器来达到目的。 而在Arduino中,使用了清楚明了的API替代繁杂的寄存器配置过程,这点在下方的代码中你将深有体会,这也是Arduino能成为简单入门单片机的核心。 C语言基础部分 判断语句: if if语句是最常用的选择结构实现方式,当给定表达式为真时,就会运行if内的语句 if(表达式){语句;} if…else 若这个表示式为真,语句1部分的代码就会被执行。若这个表示式为假,则执行紧接着else之后的语句2部分代码。 if(表达式){语句1;}else{语句2;} if…else if 若这个表示式1为真,语句1部分的代码就会被执行。若这个表示式1为假,则紧接着判断else if之后的表达式2,如果表达式2为真,则执行语句2 ,否则依次往下循环。 一旦 else if 成功,将不会测试剩余的else if或else语句。 if(表达式1){语句1;}else if(表达式2){语句2;}else if(表达式3){语句3;}else if(表达式4){语句4;}…… switch…case 类似于if语句, switch … case 通过允许程序员指定应在各种条件下执行的不同代码来控制程序的流程。 switch 语句将变量的值与 case 语句中指定的值进行比较。当发现一个case语句的值与变量的值匹配时,运行case语句中的代码。如果所有的case都不符合switch的表达式 则执行default语句中的代码。 比起一串冗长的if叙述,使用swith case可使程序代码看起来比较简洁。 switch(表达式){case 常量表达式1: 语句1 break;case 常量表达式2: 语句2 break;default : // 以上条件都不符合时,预设执行的动作 语句n break;}
while循环 当while之后的条件成立时,执行括号内的程序代码。 while循环将会连续、无限循环,直到括号()内的表达式变为false。或者使用break语句跳出循环,否则while就是死循环。 while(表达式){ 语句;} do…while循环 和while 相似,不同的是while前的那段程序代码会先被执行一次,才会判断特定的条件式为真或为假。如果为真则继续执行,如果为假则跳出循环。因此若有一段程序代码至少需要被执行一次,就可以使用do…while架构。 do{ 语句;}while(表达式); for循环 假如您需要运行代码多次,且每次使用不同的值,那么for循环则非常适用 for (循环变量类型 循环变量名称;循环条件;更新语句) for(循环变量名称;循环条件;更新语句){ 语句;} 每次循环完一次都会执行更新语句 只要还满足循环条件就会一直进行循环 for (i=0; i<5; i++) { } 就是初始化i=0 当i小于5时运行循环体中的语句,每循环完一次,i自加1,总共循环5次 break语句 当 break 关键字用于 while、for循环时,会终止循环而执行整个循环语句后面的代码。break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。 while(1){ //循环条件为死循环 sum+=i; i++; if(i>100) break; } while 循环条件为 1,是一个死循环。当执行到第100次循环的时候,计算完i++;后 i 的值为 101,此时 if 语句的条件 i> 100 成立,执行break;语句,结束循环。 一个 break 语句只向外跳一层 continue语句 continue 语句的作用是跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。 i=0;b=0;if(i<10){i++; if(i<5) b++; else continue;} 上方代码就会在i小于5的时候执行b++ 在i大于5的时候执行continue语句 继续循环 最后i=10,b=5 语法符号
// 这是一个单行注释 /* 这是一个多行注释 注释内容1注释内容2 …… */ 运算符: 常见CC++运算符 Arduuino复合运算符 *+= , -= , = , /= 对一个变量和另一个参数或变量完成一个数学运算。+=(以及其他)可以缩短语法长度。 Syntax语法 x += y; // 等价于 x = x + y; x -= y; // 等价于 x = x - y; x *= y; // 等价于 x = x * y; x /= y; // 等价于 x = x / y; Parameters参数 x:任何变量类型 y:任何变量类型或常数 Examples范例 x = 2; x += 4; // x现在为6 x -= 3; // x现在为3 x *= 10; // x现在为30 x /= 2; // x现在为15 Syntax语法 x++; // increment x by one and returns the old value of x // 将x的值加1并返回原来的x的值。 ++x; // increment x by one and returns the new value of x // 将x的值加1并返回现在的x的值。 x-- ; // decrement x by one and returns the old value of x // 将x的值减1并返回原来的x的值。 –x ; // decrement x by one and returns the new value of x // 将x的值减1并返回现在的x的值。 Parameters参数 x: an integer or long (possibly unsigned) x:一个整数或长整数(可以无符号) Returns返回 The original or newly incremented / decremented value of the variable. 返回变量原始值或增加/消耗后的新值。 Examples范例: x = 2; y = ++x; // x now contains 3, y contains 3 // x现在为3,y为3 y = x–; // x contains 2 again, y still contains 3 // x现在仍然为2,y将为3 数据类型: 整型: [tr]类型取值范围说明[/tr]
布尔类型的值只能为真(true)或是假(false) boolean会占用1个字节的内存空间。 byte 字节类型 储存的数值范围为0到255。如同字符一样字节型态的变量只需要用一个字节(8位)的内存空间储存。 浮点型 浮点数也就是常说的小数。在Arduino中有float和double两种浮点类型, float类型占用4个字节(32位)内存空间, double类型占用8个字节(64位)内存空间。可表达最大值为 1.7976931348623157 x 10308 float最多有8位小数 double最多有16位小数 float 和double 都不能为0 字符型 char 用于存储字符数据 单一字符例如 A 占用一个字节内存空间,存储字符时,字符需要用单引号引用 Arduino使用ASCII 码来存储字符数据 用数字表示一个字符时,它的值有效范围为 -128 到127。 char Str='A'; String char只能表示一个字符,如果需要多个字符的话,就需要用到String 它是由多个ASCII字符组成 可以用来保存多个字符 如: String Str = "Helloo,World"; 相较于数组形式的定义方法,使用String类型定义字符串会占用更多的存储空间。 数组: 数组是由一组相同数据类型的数据构成的集合。数组概念的引入,使得在处理多个相同类型的数据时,程序更加清晰和简洁。 其定义方式如下: 类型说明符 数组名[常量表达式]; 例如: int a[5]; 它表示定义了一个整型数组,数组名为 a,定义的数组称为数组 a 此时数组 a 中有 5 个元素,每个元素都是 int 型变量,而且它们在内存中的地址是连续分配的。也就是说,int 型变量占 4 字节的内存空间,那么 5 个int型变量就占 20 字节的内存空间,而且它们的地址是连续分配的。 数组中的下标是从 0 开始的,例如“int a[5];”表示定义了有 5 个元素的数组 a,这 5 个元素分别为 a[0]、a[1]、a[2]、a[3]、a[4]。 初始化: 在定义时初始化 int a[5] = {1, 2, 3, 4, 5}; int a[5]; a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5; 要将A[4]的值除以2并将结果赋值给变量x,我们将写: x = A[ 4 ] / 2; 数据类型转换:
char str = 'a';int sch = int(str); //将字符a 转换为整数 按照ASCII码 a的ASCII码数值是97 注意,由高精度想低精度转换,会出现bug 比如把int类型转换为byte类型,就会出现数据缺失的情况 (int最大2,147,483,647 byte最大255) 常量和变量: 常量:在Arduino语言中事先定义了一些具特殊用途的保留字。 其值不能改变 可以用const关键字来定义常量 const 类型 常量名 = 常量值 还可以用宏定义来定义常量 #define 宏名 值 例如: const int a =0;#define b = 1; 那么在该程序种,a就只能是0 b就只能是1 变量:变量可以用来储存各种类型数据,并且可以更改数据 其定义方法如下 类型 变量名; 例如,定义一个整型变量i: int i=95; Arduino使用的C语言中的变量具有名为scope(范围)的属性。scope是程序的一个区域,有三个地方可以声明变量。它们是:
在函数或代码块中声明的变量是局部变量。局部变量只能在其函数内使用 Void loop () { int x , y ; x = 0; y = 0; }y = 2; //这样就是错的 形式参数 作为函数的参数来使用,用来传递其他变量的值 void Led(int a){a = 0;}int b=2;Led(b); //把b的值传递给形参a 全局变量 全局变量在所有函数之外定义,通常位于程序的顶部。全局变量将在程序的整个生命周期中保持其价值。 全局变量可以被任何函数访问。也就是说,一个全局变量可以在整个程序中声明后使用。 int y = 0; //全局变量Void loop () { int x; x = 0; y = 1; //这样是对的}y = 2; //这样是对的 在Arduino中定义了许多常量,是不可修改的,也是我们常用的 常量PI Arduino核心库中已定义的常数PI, #define PI 3.1415926535897932384626433832795 HIGH | LOW 表示数字IO口的电平,HIGH 表示高电平(1),LOW 表示低电平(0)。 HIGH 和LOW 也用来表示你开启或是关闭了一个Arduino的脚位(pin) INPUT | OUTPUT 表示数字IO口的方向,INPUT 表示输入(高阻态),OUTPUT 表示输出(AVR能提供5V电压 40mA电流) true | false true 表示真(1),false表示假(0)。 Arduino 语言部分 此部分我们来探讨Arduino的语言特性,让你来真正的掌握Arduino Arduino结构 Arduino程序中没有main函数。 main函数的定义隐藏在了Arduino的核心库文件中,所以Arduino开发一般不直接操作main函数,而是使用Setup和loop这个两个函数。 **Arduino软件结构包括两个主要函数:
Void loop ( ) {} 在setup()函数之后,即初始化之后,loop() 让你的程序循环地被执行。使用它来运转Arduino。连续执行函数内的语句,这部份的程式会一直重复的被执行,直到Arduino 板子被关闭。 Arduino I/O函数 数字 I/O pinMode()函数 pinMode(13,OUTPUT); //定义引脚的模式 数字IO口输入输出模式定义函数,将接口定义为输入或输出接口 pinMode()函数用于将特定引脚配置为输入或输出。可以使用INPUT_PULLUP模式启用内部上拉电阻。此外,INPUT模式显式禁止内部上拉。
pinMode(7,INPUT); // 将脚位 7 设定为输入模式 pinMode(1,INPUT);//将脚位1设定为输入模式 pinMode(2,INPUT);//将脚位2设定为输入模式 pinMode(3,INPUT);//将脚位3设定为输入模式 引脚配置为INPUT Arduino引脚默认配置为输入 ,输入模式下,由外部器件向Arduino对于引脚输入电平,和数据,Arduino识别电平及数据,进行相应的处理。 引脚配置为OUTPUT 引脚配置为输出模式,Arduino引脚向其他电路提供大量的电流。Arduino引脚可以向其他器件/电路提供(提供正电流)或吸收(提供负电流)高达40mA(毫安)的电流。这是足以点亮LED或者运行许多传感器的电流(不要忘记串联电阻),但不足以运行继电器,螺线管或电机。 上拉电阻 上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用,增强输出引脚的驱动能力,提高芯片输入信号的噪声容限,增强抗干扰能力。 也就是默认状态下io为高电平 ,下拉电阻与此同理。 digitalWrite()函数 digitalWrite(pin,value); //定义引脚的电平
数字IO口输出电平定义函数,将数字接口值至高或低、开或关,即digitalWrite(接口名称, HIGH或LOW)。但脚位必须先透过pinMode明示为输入或输出模式digitalWrite才能生效。比如定义HIGH可以驱动LED。 范例: digitalWrite(8,HIGH); //将脚位 8设定输出高电位 digitalRead函数 引脚电平读取函数 int digitalRead(pin) 数字IO口读输入电平函数,读出数字接口的值 比如可以读数字传感器。当感测到脚位处于高电位时时回传HIGH,否则回传LOW。 范例: val = digitalRead(7); // 读出脚位 7 的值并指定给 val 模拟 I/O analogRead()函数 int analogRead(pin)
通过使用**analogRead()**函数,我们可以读取施加到其中一个引脚的电压。比如可以读模拟传感器(10位AD,0~5V表示为0~1023)。 范例: val = analogRead(2); //读出类比脚位 2 的值并赋值给 val analogWrite函数 analogWrite(pin, value); 数字IO口PWM输出函数,给一个接口写入模拟值(PWM波)改变PWM脚位的输出电压值可用于电机PWM调速或音乐播放。
范例 : analogWrite(9,128); // 输出电压约2.5伏特(V) 扩展 I/O shiftOut函数 shiftOut(dataPin, clockPin, bitOrder, value) SPI外部IO扩展函数,通常使用带SPI接口的74HC595做8个IO扩展,把资料传给用来延伸数位输出的暂存器,此函式通常使用在延伸数位的输出。函式使用一个脚位表示资料、一个脚位表示时脉。dataPin为数据口,clockPin为时钟口,bitOrder用来表示位元间移动的方式,为数据传输方向(MSBFIRST高位在前,LSBFIRST低位在前),value会以byte形式输出,表示所要传送的数据(0~255),另外还需要一个IO口做74HC595的使能控制。 范例 : shiftOut(dataPin, clockPin, LSBFIRST, 255); pulseIn()函数 unsigned long pulseIn(pin, value) 脉冲长度记录函数,设定读取脚位状态的持续时间,返回时间参数(us),例如使用红外线、加速度感测器测得某一项数值时,在时间单位内不会改变状态。pin表示为0~13,value为HIGH或LOW。比如value为HIGH,那么当pin输入为高电平时,开始计时,当pin输入为低电平时,停止计时,然后返回该时间。 范例: time = pulsein(7,HIGH); // 设定脚位7的状态在时间单位内保持为HIGH Arduino 时间函数 Arduino提供四种不同的时间操作函数 delay(ms) 延时函数 delay (ms) ; delay(ms) 延时函数(单位ms),延时一段时间,暂停晶片执行多少毫秒, delay(1000)为一秒。 范例: //LED闪烁实验void loop() { digitalWrite(ledPin, HIGH); // 打开LED灯 delay(1000); // 延时1秒钟 digitalWrite(ledPin, LOW); // 关闭LED灯 delay(1000); // 延时1秒钟} delayMicroseconds()函数 delayMicroseconds (us) ;
delayMicroseconds()函数接受单个整数(或数字)参数。此数字表示时间,以微秒为单位。一毫秒内有一千微秒,一秒内有一百万微秒 目前,可以产生精确延迟的最大值是16383 范例: delayMicroseconds(1000); //暂停1豪秒 millis()函数 unsigned long millis() 返回时间函数(单位ms), 回传晶片开始执行到目前的毫秒,此函数用于返回Arduino板开始运行当前程序时的毫秒数,该参数溢出大概需要50天时间。 范例: void loop() { Serial.print("Time:"); //延时1S计算运行时间 time = millis(); delay(1000); } micros()函数 micros () ; micros()函数返回Arduino板开始运行当前程序时的微秒数。该数字在大约70分钟后溢出,即回到零。在16 MHz Arduino板(例如Duemilanove和Nano)上,此函数的分辨率为4微秒(即返回值总是4的倍数)。在8 MHz Arduino板(例如LilyPad)上,此函数的分辨率为8微秒。 范例: void loop() { Serial.print("Time:"); //延时1S计算运行时间 time = micros(); delay(1000); } Arduino数学函数 Arduino数学库(math.h)包含了许多用于操作浮点数的有用的数学函数。 min(x, y) 求最小值 ,回传两数之间较小者 范例: val = min(10,20); // val=10 max(x, y) 求最大值 ,回传两数之间较大者 范例: val = max(10,20); // val=20 abs(x) 计算绝对值 ,回传该数的绝对值, 范例: val = abs(-5); // val=5 constrain(x, a, b) 约束函数,下限a,上限b,判断x变数位于a与b之间的状态。 x若小于a回传a; 介于a与b之间回传x本身; 大于b回传b 范例: val = constrain(i, 0, 255); // 将i的值赋值给val 并且i的取值为0~255 map(value, fromLow, fromHigh, toLow, toHigh) 约束函数,value必须在fromLow与toLow之间和fromHigh与toHigh之间。将value变数依照fromLow与fromHigh范围,对等转换至toLow与toHigh范围。时常使用于读取类比讯号,转换至程式所需要的范围值。 范例: val = map(analogRead(0),0,1023,100, 200); // 将analog0 所读取到的讯号0~1023对等转换至100,200之间的数值。 pow(base, exponent) 开方函数,base的exponent次方。回传一个数(base)的指数(exponent)值。 范例: double x = pow(y, 32); // 设定x为y的32次方 sq(x) 平方 平方函数,返回x的平方值 范例: val=sq(2); //val等于2的平方 sqrt(x) 开根号 回传double型态的取平方根值。 范例: double val = sqrt(1138); // 回传1138平方根的近似值 33.73425674438 double log (double __x) log()函数返回参数x的自然对数。 范例: double val = log(2); double round (double __x) round()函数将x四舍五入到最近的整数,但中间情况不舍入到0(不是到最近的偶数整数)。不可能会溢出。 范例: double val = round(5.6); //val=6 Arduino三角函数 Arduino提供了传统的三角函数(sin,cos,tan,asin,acos,atan) double sin(double x); //返回x弧度的正弦double cos(double y); //返回y弧度的余弦double tan(double x); //返回x弧度的正切double acos(double x); //返回A,对应于cos(A)=x的角度double asin(double x); //返回A,与sin(A)=x相对应的角度double atan(double x); //返回A,与tan(A)=x相对应的角度 范例: double sine = sin(2); // 近似值 0.90929737091double cosine = cos(2); //近似值-0.41614685058double tangent = tan(2); //近似值-2.18503975868 Arduino 随机数函数 randomSeed()函数 randomSeed(seed) 随机数端口定义函数,seed表示读模拟口analogRead(pin)函数 randomSeed(seed)函数重置Arduino的伪随机数生成器 虽然random()返回的数字的分布本质上是随机的,但是顺序是可预测的。所以如果需要一个真正的乱数,可以呼叫此函式重新设定产生乱数种子。你可以使用乱数当作乱数的种子,以确保数字以随机的方式出现,通常会使用类比输入当作乱数种子,藉此可以产生与环境有关的乱数(例如:无线电波、宇宙雷射线、电话和萤光灯发出的电磁波等)。 范例: randomSeed(analogRead(5)); //使用来自模拟管脚5的噪声随机化 random()函数 long random(min, max) 随机数函数,返回数据大于等于min,小于max。 long random(max) 返回数据大于等于0,小于max。 范例: long randnum = random(11); // 回传 0 -10之间的数字long randnum = random(0, 100); // 回传0 – 99 之间的数字 Arduino外部中断函数 中断:** 中断(interrupt)停止Arduino的当前工作,以便可以完成一些其他工作。 什么是中断: CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);通俗点说:你正在家里做家务,突然有人来找你,打断了你的进程,在你们交谈完之后,你就又回去继续进行你的家务活,这其中被打断的过程,就叫做中断,而在中断结束之后,你则会继续进行本来应该做的事情
attachInterrupt()函数 attachInterrupt(interrupt,function,mode) interrupt:中断源(在Arduino中,中断源可选值为0或1,一般分别对应2号和3号引脚) function:需要中断的函数名 mode:
detachInterrupt()函数 detachInterrupt(interrupt) 中断开关函数,interrupt=1 开,interrupt=0 关。 范例: detachInterrupt(1)//打开中断 中断使能函数 interrupts()// 使能中断noInterrupts() //禁止中断 Arduino串口收发函数 Arduino Uno R3开发板上,硬件串口位于Rx(0)和Tx(1)引脚上,Arduino的USB口通过转换芯片与这两个引脚连接。该转换芯片会通过USB接口在PC机上虚拟出一个用于Arduino通讯的串口,我们下载程序也是通过串口进行的。 Serial.begin(speed)
Serial.begin(9600) Serial.end()
int count = Serial.available(); Serial.read()
int data = Serial.read(); Serial.readBytes()
Serial.flush(); Arduino语言库文件 官方库文件 · EEPROM - EEPROM读写程序库 · Ethernet - 以太网控制器程序库 · LiquidCrystal - LCD控制程序库 · Servo - 舵机控制程序库 · SoftwareSerial - 任何数字IO口模拟串口程序库 · Stepper - 步进电机控制程序库 · Wire - TWI/I2C总线程序库 · Matrix - LED矩阵控制程序库 · Sprite - LED矩阵图象处理控制程序库 Arduino 内部集成电路I2C 内部集成电路(I2C)是用于微控制器和新一代专用集成电路之间的串行数据交换系统。当它们之间的距离很短(接收器和发射器通常在同一个印刷电路板上)时使用。通过两根导线建立连接。一个用于数据传输,另一个用于同步(时钟信号)。 Arduino板的I2C引脚 I2C总线由两个信号组成 - SCL和SDA。SCL是时钟信号,SDA是数据信号。当前总线主机总是产生时钟信号。一些从设备可能迫使时钟低电平以延迟主设备发送更多数据(或者在主设备尝试将数据写出之前请求更多的时间来准备数据)。这被称为“时钟伸展”。 以下是不同Arduino板的引脚:
我们有两种模式 - 主代码和从代码 - 使用I2C连接两个Arduino板。它们是:
让我们现在看看什么是主发送器和从接收器。 主发射器 以下函数用于初始化Wire库,并将I2C总线作为主器件或从器件加入。这通常只被调用一次。
使用以下函数:
|
||
|
||
只有小组成员才能发言,加入小组>>
2421 浏览 0 评论
968浏览 2评论
594浏览 1评论
357浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-29 05:17 , Processed in 1.255741 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号