Arduino与LabVIEW开发实战
上QQ阅读APP看书,第一时间看更新

1.5 串口通信

一条信息的各位数据逐位按顺序传送的通信方式称为串口通信。串口通信的特点是:数据位传送,即数据传送按位顺序进行,最少只需一根传输线即可完成,成本低但传送速度慢。

Arduino Uno控制板除了有14个数字接口和6个模拟接口外,还有1个更为常用的串口。在实际应用中,串口以只需要少量的几根线就能和其他串口设备通信的优势而被广泛应用。

所有的Arduino控制板至少都有一个串口,可以用于Arduino控制板与计算机或其他Arduino控制板等设备之间的通信。一般Arduino控制板上的数字引脚0(RX)和1(TX)都默认通过USB/串口转换芯片连接至板载的USB端口,通过USB线将其连接至计算机的USB端口,就可以实现Arduino控制板与计算机的串口通信。

Arduino Mega有三个额外的串口:Serial 1使用19(RX)和18(TX),Serial 2使用17(RX)和16(TX),Serial3使用15(RX)和14(TX)。

Arduino Leonardo控制板使用Serial 1通过0(RX)和1(TX)实现串口通信。Serial已预留给鼠标与键盘模拟库,以实现USB CDC通信。

若要使用Arduino Mega上的另外三个串口与个人电脑通信,你需要一个额外的USB转串口适配器,因为这三个串口没有连接到Mega上的USB转串口适配器。若要用它们来与外部的TTL串口设备进行通信,将TX引脚连接到串口设备的RX引脚,将RX引脚连接到串口设备的TX引脚,将GND连接到串口设备的GND。(不要将这些引脚直接连接到RS-232串口,RS-232串口的工作电压为±12V,可能会损坏Arduino控制板。)

1.5.1 串口函数库的使用

1.Serial.begin(speed)

功能:串口通信初始化。

语法:Serial.begin(speed)

参数:

speed:波特率。

详细说明:

将串行数据传输速率设置为位每秒(波特率)。常用的波特率有300、1200、2400、4800、9600、14400、19200、28800、38400、57600或115200。与计算机进行通信时,可以使用这些波特率,也可以指定其他波特率,需要说明的是,通信双方的波特率需要相同。

2.Serial.available()

功能:获取从串口读取有效的字节数(字符),这是已经传输并存储在串行接收缓冲区(最大能够存储64个字节)的数据。

语法:Serial.available()

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

详细说明:

一般情况下,Serial.available()用于读取串口数据时,用来判断串口缓冲区中是否有数据,常用的有if(Serial.available())>0)和while(Serial.available()>0)两种。

注意 Arduino在使用串口时,会在SRAM中开辟一段大小为64B的空间,串口接收到的数据都会暂时存储在这个空间中,这个存储空间称为串口缓冲区。当调用Serial.read()语句时,Arduino便会从串口缓冲区取出一个字节的数据,同时将被读取的数据从缓冲区内删除。

3.Serial.read()

功能:从串口缓冲区内读取一个字节的数据。

语法:Serial.read()

返回值:传入的串口数据的第一个字节(如果没有可用的数据,则返回-1)。

详细说明:

读取传入串口的数据,调用一次只能读取一个字节的数据,而且会将被取的数据从缓冲区内删除。

4.Serial.write()

功能:写入二进制数据到串口。

语法:Serial.write(val)、Serial.write(str)或Serial.write(buf,len)

参数:

val:以单个字节形式发送的值。

str:以一串字节的形式发送的字符串。

buf:以一串字节的形式发送的数组。

len:数组的长度。

返回值:

输出的字节数,但是否使用这个数字是可选的。

详细说明:

发送的数据以一个字节或者一系列的字节为单位。如果写入的数字为字符,需使用print()命令进行代替。

5.Serial.print()和Serial.println()

功能:以人们可读的ASCII文本形式输出数据到串口。Serial.println()除了输出人们可识别的ASCII码文本之外,还输出回车符(ASCII 13,或'\r')及换行符(ASCII 10,或'\n')。

语法:

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

参数:

val:输出的内容,任何数据类型都可以。

format:指定基数(整数数据类型)或小数位数(浮点类型)。

详细说明:

此命令可以采取多种形式,每个数字的输出使用的是ASCII字符;浮点类型同样输出的是ASCII字符,默认保留到小数点后两位;bytes类型则输出单个字符;字符和字符串原样输出。只是Serial.print()输出数据不换行,Serial.println()输出数据自动换行。

例如:

❏Serial.print(78)输出为"78"

❏Serial.print(1.23456)输出为"1.23"

❏Serial.print("N")输出为"N"

❏Serial.print("Hello world.")输出为"Hello world."

另外,还可以定义输出为几进制(格式),可以是BIN(二进制或以2为基数),OCT(八进制或以8为基数),DEC(十进制或以10为基数),HEX(十六进制或以16为基数)。

例如:

❏Serial.print(78,BIN)输出为"1001110"

❏Serial.print(78,OCT)输出为"116"

❏Serial.print(78,DEC)输出为"78"

❏Serial.print(78,HEX)输出为"4E"

对于浮点类型数字,可以指定输出的小数位数。

例如:

❏Serial.println(1.23456,0)输出为"1"

❏Serial.println(1.23456,2)输出为"1.23"

❏erial.println(1.23456,4)输出为"1.2345"

6.Serial.end()

功能:停止串行通信,使RX和TX引脚用于普通的输入/输出。

语法:

Serial.end()

说明:

当停止串口通信之后,若需要重新启用串行通信,则用Serial.begin()实现串口的初始化。一般情况下,使用Arduino串口通信时,串口不再用作其他功能。

1.5.2 实验:回音壁

1.实验目的

本实验通过Arduino Uno来实现一个回音壁。在计算机上通过串口助手或者Arduino IDE自带的串口监控串口,向Arduino Uno发送一个字符,Arduino Uno就会立即返回我们发送的数据,形成回音壁的效果。

2.硬件连接

此实验仅需要利用USB线将Arduino控制板与计算机的USB端口连接起来即可。

3.程序设计

通过串口字节数函数Serial.available()来判断是否有串口数据,如有数据则通过串口读取函数Serial.read()读出串口数据,并调用Serial.write(val)将读取的数据发送出去,程序如代码清单1-6所示。

代码清单1-6:回音壁程序代码

void setup() {
  // 初始化串口波特率为9600
  Serial.begin(9600);
}
void loop() { while(Serial.available()) // 判断串口缓冲区是否有数据 { char c = Serial.read(); // 从串口缓冲区读取一个字节的数据 Serial.write(c); // 将读取的数据通过串口发送 } }

1.5.3 实验:串口电压表

1.实验目的

本实验通过Arduino Uno模拟输入端口采集电压值,通过串口发送至计算机。在计算机上通过串口助手或者Arduino IDE自带的串口监控串口,可以看到当前所测量的电压值。

2.硬件连接

硬件连接图如图1-29所示。采用电位器实现0~5V电压的调节。电位器两端引脚分别接至+5V和GND,中间引脚接至Arduino Uno控制板的模拟输入端口A0。

图1-29 串口电压表硬件连接图

3.程序设计

通过模拟输入函数analogRead(pin)读取电位器的分压,并利用Serial.println(val)将分压值由串口发送出去,程序如代码清单1-7所示。

代码清单1-7:串口电压表程序代码

int sensorValue=0;                                                             // 定义变量,用于存放模数转换数字量
float float_sensorValue;                                                     // 定义变量,用于存放浮点类型电压值
void setup() { Serial.begin(9600); // 定义串口波特率为9600 } void loop() { sensorValue = analogRead(A0); // 读取A0端口电压值 float_sensorValue=(float)sensorValue/1023*5.00; // 换算为浮点类型电压值 Serial.println(float_sensorValue,2); // 保留两位小数发送数据 delay(1000); // 一秒刷新一次 }