Arduino 基本函数

数字I/O

pinMode()
void pinMode (uint8_t pin, uint8_t mode)

设置引脚模式

配置引脚为输出或输出模式.

参数:
pin 引脚编号
mode: INPUT, OUTPUT, 或 INPUT_PULLUP.

例子:

int ledPin = 13; // LED connected to digital pin

void setup()
{
 pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
 digitalWrite(ledPin, HIGH); // sets the LED on
 delay(1000); // waits for a second
 digitalWrite(ledPin, LOW); // sets the LED off
 delay(1000); // waits for a second
}

注解:
模拟引脚也可以当作数字引脚使用, 编号为14(对应模拟引脚0)到19(对应模拟引脚5).


digitalWrite()
void digitalWrite (uint8_t pin, uint8_t value)

写数字引脚
写数字引脚, 对应引脚的高低电平. 在写引脚之前, 需要将引脚设置为OUTPUT模式.

参数:
pin 引脚编号
value HIGH 或 LOW

用法:

int ledPin = 13; // LED connected to digital pin
void setup()
{
 pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
 digitalWrite(ledPin, HIGH); // 点亮LED
 delay(1000); // 等待1秒
 digitalWrite(ledPin, LOW); // 关
 delay(1000); // waits for a second
}

注解:
模拟引脚也可以当作数字引脚使用, 编号为14(对应模拟引脚0)到19(对应模拟引脚5).


digitalRead()
int digitalRead (uint8_t pin)   

读数字引脚
读数字引脚, 返回引脚的高低电平. 在读引脚之前, 需要将引脚设置为INPUT模式.

参数:
pin 引脚编号

返回:
HIGH或LOW

int ledPin = 13; // LED connected to digital pin
int inPin = 7; // pushbutton connected to digital pin 7
int val = 0; // variable to store the read value

void setup()
{
 pinMode(ledPin, OUTPUT); // sets the digital pin as output
 pinMode(inPin, INPUT); // sets the digital pin 7 as input
}

void loop()
{
 val = digitalRead(inPin); // read the input pin
 digitalWrite(ledPin, val); // sets the LED to the buton's value
}

注解:
如果引脚没有链接到任何地方, 那么将随机返回 HIGH 或 LOW.


模拟I/O

analogReference()
void analogReference (uint8_t type)

配置参考电压
配置模式引脚的参考电压. 函数 analogRead 在读取模拟值之后, 将根据参考电压将拟值转换到[0,10]区间.

有以下类型:
DEFAULT : 默认5V.
INTERNAL: 低功耗模式.
ATmega168和ATmega8对应1.1V到2.56V.
EXTERNAL: 扩展模式.
通过AREF引脚获取参考电压.

参数:
type 参考类型(DEFAULT/INTERNAL/EXTERNAL)


analogRead()
int analogRead (uint8_t pin)  

读模拟引脚
读模拟引脚, 返回[0-10]之间的值. 每读一次需要花1微妙的时间.

参数:
pin 引脚编号

返回:
0到10之间的值

例子:

int analogPin = 3; // potentiometer wiper (middle terminal) connected to analog pin 3
 // outside leads to ground and +5V
int val = 0; // variable to store the value read
void setup()
{
 Serial.begin(9600); // setup serial
}
void loop()
{
 val = analogRead(analogPin); // read the input pin
 Serial.println(val); // debug value
}

analogWrite()
void analogWrite (uint8_t pin, int value)   

写模拟引脚

参数:
pin 引脚编号
value 0到255之间的值, 0对应off, 255对应on

写一个模拟值(PWM)到引脚. 可以用来控制LED的亮度, 或者控制电机的转速. 在执行该操作后, 应该等待一定时间后才能对该引脚进行下一次的读或写操作. PWM的频率大约为490Hz.

在一些基于ATmega168的新的Arduino控制板(如Mini 和BT)中, 该函数支持以下引脚: 3, 5, 6, 9, 10。 在基于ATmega8的型号中支持9, 10引脚.

例子:

int ledPin = 9; // LED connected to digital pin 9
int analogPin = 3; // potentiometer connected to analog pin 3
int val = 0; // variable to store the read value
void setup()
{
 pinMode(ledPin, OUTPUT); // sets the pin as output
}
void loop()
{
 val = analogRead(analogPin); // read the input pin
 analogWrite(ledPin, val / 4); // analogRead values go from 0 to 10, analogWrite values from 0 to 255
}

高级I/O

shiftOut()
void shiftOut (uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val)   

位移输出函数

输入value数据后Arduino会自动把数据移动分配到8个并行输出端. 其中dataPin为连接DS的引脚号, clockPin为连接SH_CP的引脚号, bitOrder为设置数据位移顺序, 分别为高位先入MSBFIRST或者低位先入LSBFIRST.

参数:
dataPin 数据引脚
clockPin 时钟引脚
bitOrder 移位顺序 ( MSBFIRST 或 LSBFIRST)
val 数据

// Do this for MSBFIRST serial
int data = 500;

// shift out highbyte
shiftOut(dataPin, clock, MSBFIRST, (data >> 8)); 

// shift out lowbyte
shiftOut(dataPin, clock, MSBFIRST, data);

// Or do this for LSBFIRST serial
data = 500;

// shift out lowbyte
shiftOut(dataPin, clock, LSBFIRST, data); 

// shift out highbyte
shiftOut(dataPin, clock, LSBFIRST, (data >> 8));

pulseIn()

unsigned long pulseIn (uint8_t pin, uint8_t state, unsigned long timeout)           

读脉冲

读引脚的脉冲, 脉冲可以是 HIGH 或 LOW. 如果是 HIGH, 函数将先等引脚变为高电平, 然后 开始计时, 一直到变为低电平为止. 返回脉冲持续的时间长短, 单位为毫秒. 如果超时还没有 读到的话, 将返回0.

参数:
1 pin 引脚编号
2 state 脉冲状态
3 timeout 超时时间

下面的例子演示了统计高电平的继续时间:

int pin = 7;
unsigned long duration;
void setup()
{
 pinMode(pin, INPUT);
}
void loop()
{
  duration = pulseIn(pin, HIGH);
}

时间

millis()
unsigned long millis (void)

毫秒时间
获取机器运行的时间长度, 单位毫秒. 系统最长的记录时间为9小时分, 如果超出时间将从0开始. 警告:时间为 unsigned long类型, 如果用 int 保存时间将得到错误结果。

delay(ms)
void delay (unsigned long ms)  

延时(毫秒)
延时, 单位毫秒(1秒有1000毫秒).

警告: 参数为unsigned long, 因此在延时参数超过767(int型最大值)时, 需要用"UL"后缀表示为无符号 长整型, 例如: delay(60000UL);. 同样在参数表达式, 切表达式中有int类型时, 需要强制转换为 unsigned long类型, 例如: delay((unsigned long)tdelay * 100UL);.

例子设置
引脚对应的LED等以1秒频率闪烁:

int ledPin = 13; // LED connected to digital pin

void setup()
{
 pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
 digitalWrite(ledPin, HIGH); // sets the LED on
 delay(1000); // waits for a second
 digitalWrite(ledPin, LOW); // sets the LED off
 delay(1000); // waits for a second
}

delayMicroseconds(us)
void delayMicroseconds (unsigned int us)  

延时(微秒)
延时, 单位为微妙(1毫秒有1000微妙). 如果延时的时间有几千微妙, 那么建议使用 delay 函数. 目前参数最大支持16383微妙(不过以后的版本中可能会变化).

以下代码向第8号引脚发送脉冲, 每次脉冲持续50微妙的时间.

int outPin = 8; // digital pin 8
void setup()
{
 pinMode(outPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
 digitalWrite(outPin, HIGH); // sets the pin on
 delayMicroseconds(50); // pauses for 50 microseconds
 digitalWrite(outPin, LOW); // sets the pin off
 delayMicroseconds(50); // pauses for 50 microseconds
}

数学库

min()
#define min(a, b) ((a)<(b)?(a):(b))

最小值
取两者之间最小值. 例如:

sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100
 // ensuring that it never gets above 100.

max()
#define max(a, b) ((a)>(b)?(a):(b))

最大值
取两者之间最大值. 例如:

sensVal = max(senVal, 20); // assigns sensVal to the larger of sensVal or 20
 // (effectively ensuring that it is at least 20)
abs()
abs(x) ((x)>0?(x):-(x))

求绝对值


constrain()

#define constrain(amt, low, high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

调整到区间

如果值 amt 小于 low, 则返回 low; 如果 amt 大于 high, 则返回 high; 否则, 返回 amt . 一般可以用于将值归一化到某个区间.

例如:

sensVal = constrain(sensVal, 10, 150);
// limits range of sensor values to between 10 and 150

map()
long map ( long x, long in_min, long in_max, long out_min, long out_max)   

等比映射
将位于[in_min, in_max]之间的x映射到[out_min, out_max].

参数:
x 要映射的值
in_min 映射前区间
in_max 映射前区间
out_min 映射后区间
out_max 映射后区间

例如下面的代码中用 map 将模拟量从[0,10]映射到[0,255]区间:

// Map an analog value to 8 bits (0 to 255)
void setup() {}
void loop()
{
 int val = analogRead(0);
 val = map(val, 0, 10, 0, 255);
 analogWrite(9, val);
}

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

pow()
double pow (float base, float exponent)

指数函数


sqrt()
double sqrt (double x)

//开平方


三角函数

sin(),cos(),tan()
float sin (float rad);//正弦函数

float cos (float rad);//余弦函数

float tan (float rad);//正切函数

随机数

randomSeed()
void randomSeed ( unsigned int seed )  

设置随机种子
可以用当前时间作为随机种子. 随机种子的设置对产生的随机序列有影响.

参数:
seed 随机种子


random()
long random (long howbig)  

生成随机数
生成[0, howbig-1]范围的随机数.

参数:
howbig 最大值

long random (long howsmall, long howbig)   

生成随机数

生成[howsmall, howbig-1]范围的随机数.

参数:
howsmall 最小值
howbig 最大值


位操作

位操作

#define lowByte(w) ((w) & 0xff)  //取低字节
#define highByte(w) ((w) >> 8)  //取高字节
#define bitRead(value, bit) (((value) >> (bit)) & 0x01) //读一个bit
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) //写一个bit
#define bitSet(value, bit)   ((value) |= (1UL << (bit))) //设置一个bit
#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) //清空一个bit
#define bit(b) (1 << (b)) //生成相应bit 

设置中断函数

achInterrupt()
void achInterrupt (uint8_t interruptNum, void(*)(void)userFunc, int mode)

设置中断
指定中断函数. 外部中断有0和1两种, 一般对应2号和3号数字引脚.

参数:
interrupt 中断类型, 0或1
fun 对应函数 mode 触发方式. 有以下几种:

  • LOW 低电平触发中断
  • CHANGE 变化时触发中断
  • RISING 低电平变为高电平触发中断
  • FALLING 高电平变为低电平触发中断

注解: 在中断函数中 delay 函数不能使用, millis 始终返回进入中断前的值. 读串口数据的话, 可能会丢失. 中断函数中使用的变量需要定义为 volatile 类型. 下面的例子如果通过外部引脚触发中断函数, 然后控制LED的闪烁.

int pin = 13;
volatile int state = LOW;

void setup()
{
 pinMode(pin, OUTPUT);
 achInterrupt(0, blink, CHANGE);
}

void loop()
{
 digitalWrite(pin, state);
}

void blink()
{
 state = !state;
}

detachInterrupt()
void detachInterrupt (uint8_t interruptNum)

取消中断
取消指定类型的中断.

参数:
interrupt 中断的类型.


interrupts()
#define interrupts() sei()

开中断

例子:

void setup() {}
void loop()
{
 noInterrupts();
 // critical, time-sensitive code here
 interrupts();
 // other code here
}

noInterrupts()
#define noInterrupts() cli()

关中断

例子:

void setup() {}
void loop()
{
 noInterrupts();
 // critical, time-sensitive code here
 interrupts();
 // other code here
}

串口通讯

void begin (long) 打开串口
uint8_t available (void) 有串口数据返回真
int read (void) //读串口
void flush (void) //刷新串口数据
virtual void write (uint8_t) //写串口 </pre>
begin()
void HardwareSerial::begin (long speed)  

打开串口

参数:
speed 波特率


available()

获取串口上可读取的数据的字节数。该数据是指已经到达并存储在接收缓存(共有64字节)中。available()继承自Stream实用类。

语法:

Serial.available()
Arduino Mega only: Serial1.available() Serial2.available() Serial3.available()

参数: 无

返回值:
返回可读取的字节数

示例:

int incomingByte = 0; // for incoming serial data
void setup() {
 Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
 // send data only when you receive data:
 if (Serial.available() > 0) {
 // read the incoming byte:
 incomingByte = Serial.read();
 // say what you got:
 Serial.print("I received: ");
 Serial.println(incomingByte, DEC);
 }
}

Arduino Mega example:

void setup() {
 Serial.begin(9600);
 Serial1.begin(9600);
}
void loop() {
 // read from port 0, send to port 1:
 if (Serial.available()) {
 int inByte = Serial.read();
 Serial1.print(inByte, BYTE);
 }
 // read from port 1, send to port 0:
 if (Serial1.available()) {
 int inByte = Serial1.read();
 Serial.print(inByte, BYTE);
 }
}

read()

读串口数据,read()继承自Stream实用类。

语法:

Serial.read()
Arduino Mega only: Serial1.read() Serial2.read() Serial3.read()

参数: 无

返回值: 串口上第一个可读取的字节(如果没有可读取的数据则返回-1)- int型。

示例:

int incomingByte = 0; // 用于存储从串口读到的数据
void setup() {
 Serial.begin(9600); // 打开串吕,设置速率为9600 bps
}
void loop() {
 // 只在收到数据时发送数据
 if (Serial.available() > 0) {
 // 读取传入的字节
 incomingByte = Serial.read();
 // 指示你收到的数据
 Serial.print("I received: ");
 Serial.println(incomingByte, DEC);
 }
}

flush()

刷新串口数据


print()

往串口发数据,无换行描述 以人类可读的ASCII码形式向串口发送数据,该函数有多种格式。整数的每一数位将以ASCII码形式发送。浮点数同样以ASCII码形式发送,默认保留小数点后两位。字节型数据将以单个字符形式发送。字符和字符串会以其相应的形式发送。

例如:

 Serial.print(78) 发送 "78"
 Serial.print(1.456) 发送 "1.456"
 Serial.print('N') 发送 "N"
 Serial.print("Hello world.") 发送 "Hello world."

可选的第二个参数用于指定数据的格式。允许的值为:BIN (binary二进制), OCT (octal八进制), DEC (decimal十进制), HEX (hexadecimal十六进制)。对于浮点数,该参数指定小数点的位数。

例如:

 Serial.print(78, BIN) gives "1000"
 Serial.print(78, OCT) gives "6"
 Serial.print(78, DEC) gives "78"
 Serial.print(78, HEX) gives "4E"
 Serial.println(1.456, 0) gives "1"
 Serial.println(1.456, 2) gives "1.46"
 Serial.println(1.456, 4) gives "1.4560"

你可以用F()把待发送的字符串包装到flash存储器。例如:

 Serial.print(F(“Hello World”))

要发送单个字节数据,请使用Serial.write()。

语法:

Serial.print(val)
Serial.print(val, format)

参数:
val: 要发送的数据(任何数据类型)
format: 指定数字的基数(用于整型数)或者小数的位数(用于浮点数)。

返回值:
size_t (long): print()返回发送的字节数(可丢弃该返回值)。

示例:

/*
Uses a FOR loop for data and prints a number in various formats.
*/
int x = 0; // variable
void setup() {
 Serial.begin(9600); // open the serial port at 9600 bps:
}
void loop() { 
 // print labels
 Serial.print("NO FORMAT"); // prints a label
 Serial.print("\t"); // prints a tab
 Serial.print("DEC");
 Serial.print("\t");
 Serial.print("HEX");
 Serial.print("\t");
 Serial.print("OCT");
 Serial.print("\t");
 Serial.print("BIN");
 Serial.print("\t");
 for(x=0; x< 64; x++){ // only part of the ASCII chart, change to suit
 // print it out in many formats:
 Serial.print(x); // print as an ASCII-encoded decimal - same as "DEC"
 Serial.print("\t"); // prints a tab
 Serial.print(x, DEC); // print as an ASCII-encoded decimal
 Serial.print("\t"); // prints a tab
 Serial.print(x, HEX); // print as an ASCII-encoded hexadecimal
 Serial.print("\t"); // prints a tab
 Serial.print(x, OCT); // print as an ASCII-encoded octal
 Serial.print("\t"); // prints a tab
 Serial.println(x, BIN); // print as an ASCII-encoded binary
 // then adds the carriage return with "println"
 delay(200); // delay 200 milliseconds
 }
 Serial.println(""); // prints another carriage return
}

编程技巧: 在版本1.0时,串口传输是异步的,Serial.print()会在数据发送完成前返回。


println()

往串口发数据,类似Serial.print(),但有换行


write()

写二进制数据到串口,数据是一个字节一个字节地发送的,若以字符形式发送数字请使用print()代替。

语法:

Serial.write(val)
Serial.write(str)
Serial.write(buf, len)
Arduino Mega也支持:Serial1, Serial2, Serial3(在Serial的位置)

参数:

val: 作为单个字节发送的数据
str: 由一系列字节组成的字符串
buf: 同一系列字节组成的数组
len: 要发送的数组的长度

返回:
byte

write()会返回发送的字节数,所以读取该返回值是可选的。

示例:

void setup(){
 Serial.begin(9600);
}
void loop(){
 Serial.write(45); //以二进制形式发送数字45
 int bytesSent = Serial.write(“hello”); //发送字符串“hello”  并返回该字符串的长度。
}

peak()

描述: 返回收到的串口数据的下一个字节(字符),但是并不把该数据从串口数据缓存中清除。就是说,每次成功调用peak()将返回相同的字符。与read()一样,peak()继承自Stream实用类。

语法: 可参照Serail.read()


serialEvent()

描述: 当串口有数据到达时调用该函数(然后使用Serial.read()捕获该数据)。
注意:目前serialEvent()并不兼容于Esplora, Leonardo, 或 Micro。

语法:

void serialEvent(){
//statements
}
//Arduino Mega only:
void serialEven(){
//statements
}
void serialEven(){
//statements
}
void serialEven(){
//statements
}

statements可以是任何有效的语句。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容