查看: 120383|回复: 120

软串口通信——SoftwareSerial库的使用

  [复制链接]

该用户从未签到

发表于 2017-7-2 02:19 | 显示全部楼层 |阅读模式
本教程节选自《Arduino程序设计基础》


软件模拟串口通信——SoftwareSerial库的使用
除HardwareSerial外,Arduino还提供了SoftwareSerial类库,它可以将你的其他数字引脚通过程序模拟成串口通信引脚。
通常我们将Arduino UNO上自带的串口称为硬件串口,而使用SoftwareSerial类库模拟成的串口,称为软件模拟串口(简称软串口)。
在Arduino UNO上,提供了0(RX)、1(TX)一组硬件串口,可与外围串口设备通信,如果要连接更多的串口设备,可以使用软串口。
软串口是由程序模拟实现的,使用方法类似硬件串口,但有一定局限性:在Arduino UNO MEGA上部分引脚不能被作为软串口接收引脚,且软串口接收引脚波特率建议不要超过57600。



SoftwareSerial类成员函数
软串口类库并非Arduino UNO核心类库,因此使用前你需要先声明包含SoftwareSerial.h头文件。
其中定义的成员函数与硬件串口类似,available()、begin()、read()、write()、print()、println()、peek() 等用法相同,这里便不一一列举。
此外软串口后还有如下成员函数:

SoftwareSerial()
SoftwareSerial类的构造函数,通过它可指定软串口RX、TX引脚。
语法:
SoftwareSerial mySerial= SoftwareSerial(rxPin, txPin)
SoftwareSerial mySerial(rxPin, txPin)
参数:
mySerial:用户自定义软件串口对象
rxPin:软串口接收引脚
txPin:软串口发送引脚

listen()
开启软串口监听状态。
Arduino UNO在同一时间仅能监听一个软串口,当你需要监听某一软串口时,需要该对象调用这个函数开启监听功能。
语法:
mySerial.listen()
参数:
mySerial:用户自定义的软件串口对象
返回值:



isListening()
监测软串口是否正在监听状态。
语法:
mySerial.isListening()
参数:
mySerial:用户自定义的软件串口对象
返回值:
Boolean型
True:正在监听
False:没有监听

end()
停止监听软串口。
语法:
mySerial. end()
参数:
mySerial:用户自定义的软件串口对象
返回值:
Boolean型
True:关闭监听成功
False:关闭监听失败

overflow()
检测缓冲区是否溢出。
语法:
mySerial.overflow()
参数:
mySerial:用户自定义的软件串口对象
返回值:
Boolean型
True:溢出
False:没有溢出

建立软串口通信
SoftwareSerial类库是Arduino IDE默认提供的一个第三方类库,和硬件串口不同,其声明并没有包含在Arduino核心库中,因此要建立软串口通信,首先需要声明包含SoftwareSerial.h头文件,然后即可使用该类库中的构造函数,初始化一个软串口实例。如:
SoftwareSerial mySerial(2, 3);
即是新建一个名为mySerial的软串口,并将2号引脚作为RX端,3号引脚作为TX端。完整示例如下:
        
[mw_shl_code=arduino,true]/*
Arduino UNO软串口通信
*/

#include <SoftwareSerial.h>
//实例化软串口
SoftwareSerial mySerial(2, 3); // RX, TX

void setup()
{
  Serial.begin(115200);
  while (!Serial) {
  }

  Serial.println("Goodnight moon!");

  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop()
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}[/mw_shl_code]

在实际使用中,你可能还会用到其他串口设备,如串口无线透传模块、串口传感器等,只要是标准串口设备,其程序的编写方法都基本相同。

同时使用多个软串口
当需要连接多个串口设备时,可以建立多个软串口,但限于软串口的实现原理,Arduino UNO只能同时监听一个软串口,当存在多个软串口设备时,你需要使用listen() 函数指定需要监听的设备。如程序中存在portOne、portTwo两个软串口对象时,你欲监听portOne,便需要使用portOne.listen() 语句,要切换监听port2,便使用portTwo.listen() 语句。
示例程序如下:
  1. /*
  2. Arduino UNO软串口通信
  3. 通过listen()切换监听软串口
  4. */

  5. #include <SoftwareSerial.h>
  6. SoftwareSerial portOne(10, 11);
  7. SoftwareSerial portTwo(8, 9);

  8. void setup() {
  9.   Serial.begin(9600);
  10.   while (!Serial) {
  11.   }

  12.   portOne.begin(9600);
  13.   portTwo.begin(9600);
  14. }

  15. void loop() {
  16. //监听1号软串口
  17.   portOne.listen();

  18.   Serial.println("Data from port one:");
  19.   while (portOne.available() > 0) {
  20.     char inByte = portOne.read();
  21.     Serial.write(inByte);
  22.   }

  23.   Serial.println();
  24. //监听2号软串口
  25.   portTwo.listen();

  26.   Serial.println("Data from port two:");
  27.   while (portTwo.available() > 0) {
  28.     char inByte = portTwo.read();
  29.     Serial.write(inByte);
  30.   }

  31.   Serial.println();
  32. }
复制代码





该用户从未签到

发表于 2019-8-23 00:16 | 显示全部楼层
linzs 发表于 2018-5-20 15:44
哎,国内做的东西都这样,没头没尾,好歹是硬件,拍个视频做个电路都懒的。。。 ...

真正的电子爱好者,应该是抱着感激之心,去阅读他人的文章和产品介绍,并从中找到自己需要的东西,打算要现成的东西,还经常埋怨他人,是不能提高自己的,和爱好者初衷背道而驰。不理解的可以多问,别人可能搭理你,也可能不理你,多浏览就是了,记着自己成功了,要分享过程和关键点

该用户从未签到

 楼主| 发表于 2018-5-20 23:40 | 显示全部楼层
linzs 发表于 2018-5-20 15:44
哎,国内做的东西都这样,没头没尾,好歹是硬件,拍个视频做个电路都懒的。。。 ...

这是教程。。。能写给你看我觉得我已经很尽力了,不强求你看

该用户从未签到

发表于 2019-10-23 12:16 | 显示全部楼层
linzs 发表于 2018-5-20 15:44
哎,国内做的东西都这样,没头没尾,好歹是硬件,拍个视频做个电路都懒的。。。 ...

您的帖子数2,积分12,人家楼主帖子数6048,积分2万。如果大家都是只知道索取不懂回报还要埋怨,就没有人愿意分享了。劣币驱逐良币的过程

该用户从未签到

 楼主| 发表于 2019-9-7 13:29 | 显示全部楼层
花生日记8IVBZDO 发表于 2019-9-7 10:21
软串口 往哪里输出啊“”开发板在 null 不可用“”连接硬件还要软串口有什么意义呢 ...

硬串口通常用来和PC通信,UNO串口不够,要连接其他串口设备,需要软件模拟出串口

该用户从未签到

发表于 2019-12-26 16:49 | 显示全部楼层
绀青嘎啦鸡 发表于 2019-8-29 10:06
这里面的while语句为什么是括号里的条件是假它才执行?还有一个问题就是,这个while语句是相当于C语言里的w ...

串口初始化的时候,while后面一直为真,说明没有初始化成功,所以不向后执行,初始化成功后,while后面的表达式为假,则向后继续

该用户从未签到

发表于 2019-12-26 16:53 | 显示全部楼层
蜕变吧胖子君 发表于 2019-8-16 17:12
void setup()
{
  Serial.begin(115200);

9600是mySerial对应的串口的波特率,不是电脑的

该用户从未签到

发表于 2017-7-2 10:25 | 显示全部楼层
很有用,但楼主说的函数可以用在UNO板上么?

点评

可以  详情 回复 发表于 2017-7-2 22:56

该用户从未签到

 楼主| 发表于 2017-7-2 22:56 | 显示全部楼层
ac-dc 发表于 2017-7-2 10:25
很有用,但楼主说的函数可以用在UNO板上么?

可以

该用户从未签到

发表于 2017-7-12 12:46 | 显示全部楼层
有softwareserial库的链接吗?求助

点评

自带的  详情 回复 发表于 2017-7-12 12:50

该用户从未签到

 楼主| 发表于 2017-7-12 12:50 | 显示全部楼层
lililililizhan 发表于 2017-7-12 12:46
有softwareserial库的链接吗?求助

自带的

该用户从未签到

发表于 2017-8-2 01:06 来自手机 | 显示全部楼层
软串口和硬串口波特率不同不会乱码?我之前试过是会的

点评

理论不会,了能你的硬件有干扰  详情 回复 发表于 2017-8-2 20:08

该用户从未签到

 楼主| 发表于 2017-8-2 20:08 | 显示全部楼层
puppy_hui 发表于 2017-8-2 01:06
软串口和硬串口波特率不同不会乱码?我之前试过是会的

理论不会,了能你的硬件有干扰

该用户从未签到

发表于 2017-9-27 18:40 | 显示全部楼层
这个例程在atmega8  开发板下编译报错,部分变量未定义。不知道需要怎么修改下库还是怎么弄呢?

点评

可能是你使用的引脚不支持PCINT造成的,贴报错看看  详情 回复 发表于 2017-9-27 20:05

该用户从未签到

 楼主| 发表于 2017-9-27 20:05 | 显示全部楼层
NikolaT 发表于 2017-9-27 18:40
这个例程在atmega8  开发板下编译报错,部分变量未定义。不知道需要怎么修改下库还是怎么弄呢? ...

可能是你使用的引脚不支持PCINT造成的,贴报错看看

该用户从未签到

发表于 2017-9-28 10:13 | 显示全部楼层
奈何col 发表于 2017-9-27 20:05
可能是你使用的引脚不支持PCINT造成的,贴报错看看

Arduino:1.8.1 (Windows 7), 开发板:"ATmega8-noxtal @8MHz"

D:\softwareinstallation\arduino\arduino-builder -dump-prefs -logger=machine -hardware D:\softwareinstallation\arduino\hardware -tools D:\softwareinstallation\arduino\tools-builder -tools D:\softwareinstallation\arduino\hardware\tools\avr -built-in-libraries D:\softwareinstallation\arduino\libraries -libraries C:\Users\jack\Documents\Arduino\libraries -fqbn=arduino:avr:atmega8noxtal -ide-version=10801 -build-path C:\Users\jack\AppData\Local\Temp\arduino_build_7708 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=D:\softwareinstallation\arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=D:\softwareinstallation\arduino\hardware\tools\avr -verbose D:\桌面\项目\Arduino--add\softuart0.04\softuart0.04.ino
D:\softwareinstallation\arduino\arduino-builder -compile -logger=machine -hardware D:\softwareinstallation\arduino\hardware -tools D:\softwareinstallation\arduino\tools-builder -tools D:\softwareinstallation\arduino\hardware\tools\avr -built-in-libraries D:\softwareinstallation\arduino\libraries -libraries C:\Users\jack\Documents\Arduino\libraries -fqbn=arduino:avr:atmega8noxtal -ide-version=10801 -build-path C:\Users\jack\AppData\Local\Temp\arduino_build_7708 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=D:\softwareinstallation\arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=D:\softwareinstallation\arduino\hardware\tools\avr -verbose D:\桌面\项目\Arduino--add\softuart0.04\softuart0.04.ino
Using board 'atmega8noxtal' from platform in folder: D:\softwareinstallation\arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: D:\softwareinstallation\arduino\hardware\arduino\avr
Warning: Board arduino:avr:atmega8noxtal doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA8NOXTAL
Detecting libraries used...
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\sketch\softuart0.04.ino.cpp" -o "nul"
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\sketch\softuart0.04.ino.cpp" -o "nul"
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp" -o "nul"
Generating function prototypes...
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\sketch\softuart0.04.ino.cpp" -o "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\preproc\ctags_target_for_gcc_minus_e.cpp"
"D:\softwareinstallation\arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\preproc\ctags_target_for_gcc_minus_e.cpp"
正在编译项目...
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\sketch\softuart0.04.ino.cpp" -o "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\sketch\softuart0.04.ino.cpp.o"
Compiling libraries...
Compiling library "SoftwareSerial"
"D:\softwareinstallation\arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega8 -DF_CPU=8000000L -DARDUINO=10801 -DARDUINO_AVR_ATMEGA8NOXTAL -DARDUINO_ARCH_AVR   "-ID:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard" "-ID:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp" -o "C:\Users\jack\AppData\Local\Temp\arduino_build_7708\libraries\SoftwareSerial\SoftwareSerial.cpp.o"
In file included from D:\softwareinstallation\arduino\hardware\arduino\avr\cores\arduino/Arduino.h:249:0,

                 from D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:43:

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp: In member function 'void SoftwareSerial::begin(long int)':

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:56:42: warning: comparison is always true due to limited range of data type [-Wtype-limits]

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

                                          ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:319:7: note: in expansion of macro 'digitalPinToPCICR'

   if (digitalPinToPCICR(_receivePin)) {

       ^

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:56:62: error: 'PCICR' was not declared in this scope

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

                                                              ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:319:7: note: in expansion of macro 'digitalPinToPCICR'

   if (digitalPinToPCICR(_receivePin)) {

       ^

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:56:42: warning: comparison is always true due to limited range of data type [-Wtype-limits]

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

                                          ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:360:6: note: in expansion of macro 'digitalPinToPCICR'

     *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));

      ^

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:58:49: error: 'PCMSK2' was not declared in this scope

#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))

                                                 ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:363:22: note: in expansion of macro 'digitalPinToPCMSK'

     _pcint_maskreg = digitalPinToPCMSK(_receivePin);

                      ^

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:58:76: error: 'PCMSK0' was not declared in this scope

#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))

                                                                            ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:363:22: note: in expansion of macro 'digitalPinToPCMSK'

     _pcint_maskreg = digitalPinToPCMSK(_receivePin);

                      ^

D:\softwareinstallation\arduino\hardware\arduino\avr\variants\standard/pins_arduino.h:58:103: error: 'PCMSK1' was not declared in this scope

#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))

                                                                                                       ^

D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.cpp:363:22: note: in expansion of macro 'digitalPinToPCMSK'

     _pcint_maskreg = digitalPinToPCMSK(_receivePin);

                      ^

使用 1.0  版本的库 SoftwareSerial 在文件夹: D:\softwareinstallation\arduino\hardware\arduino\avr\libraries\SoftwareSerial
exit status 1
为开发板 ATmega8-noxtal @8MHz 编译时出错。

只包含了一个头文件

只包含了一个头文件

点评

那只有自己修改库了,查查mega8的PCINT引脚有哪些吧  详情 回复 发表于 2017-9-28 10:29
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

Arduino16进制字符串转ASCII(下)
Arduino16进制字符串转ASC
在Arduino16进制字符串转ASCII(上)(简称:上文)基础上,举一反三,超越自我,提高
OLED 128*64自制可达10000000个选项的菜单(已更新)
OLED 128*64自制可达10000
OLED 128*64自制可达10000000个选项的菜单 温馨提示: 建议占个楼再食用本帖子
ps2遥控小车——uno实现
ps2遥控小车——uno实现
前几天在阁楼发现了好久以前3d打印,激光切割的底盘,于是决定做这个东西 正好手上又
.h .cpp源代码转.ino草图
.h .cpp源代码转.ino草图
在Github上下载了源码,是.h 和.cpp文件,请问一下,如何才可以转成可以在arduinoIDE
Atmega8/16等AVR单片机改装成Arduino板子
Atmega8/16等AVR单片机改
Atmega8/16改装Arduino板子想把AVR单片机改装成arduino板的,可以通过一下开源库来支
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表