第一步:Linux中启用串口设备。【以树莓派4B为例】

树莓派4B有6个串口,参考上一篇《》,在 /boot/config.txt 中添加一行,开启 uart2 功能:

  dtoverlay=uart2

重启后,查看是否有多出来一个 /dev/AMA1 设备:

$ ls -l  /dev/tty*
crw-rw---- 1 root dialout 204, 64 Jul 20 11:52 /dev/ttyAMA0
crw-rw---- 1 root dialout 204, 65 Jul 20 11:59 /dev/ttyAMA1
crw------- 1 root root 5, 3 Jul 20 11:52 /dev/ttyprintk
crw--w---- 1 root tty 4, 64 Jul 20 11:52 /dev/ttyS0

也可以config.txt 中添加多行(uart2,uart3,uart4,uart5)启动多个串口功能 (对应 ttyAMA1,ttyAMA2,ttyAMA3 和 ttyAMA4).

可以用下面命令查看 uart2 对应的GPIO针脚映射:

# dtoverlay -h  uart2 

Name:   uart2

Info:   Enable uart 2 on GPIOs 0-3. BCM2711 only.

Usage:  dtoverlay=uart2,<param>

Params: ctsrts                  Enable CTS/RTS on GPIOs 2-3 (default off)

从输出可见,GPIO针脚为0-3, 其中针脚0和1分别为TxD和RxD,针脚2-3为流控 CTS/RTS.  此处针脚0-1为BCM编码号物理引脚号为27-28.

第二步: 使用python代码,测试 uart2 功能是否正确

硬件接线: 将 GPIO引脚0 和 1 短接,实现自发自收

软件测试:python控制台中,执行如下代码测试

>>> import serial
>>> ted = serial.Serial(port="/dev/ttyAMA1", baudrate=9600)
>>> ted.write("Hello World".encode("gbk"))
11
>>> ted.read(11)
b'Hello World'
>>>

能收到字串‘Hello World’表示 uart2 功能和接线均一切正常。

第三步:编辑 CodeSys 配置文件,映射 /dev/ttyAMA* 到 COMx 端口号。

在老版本的CodeSys 中,需要编辑 "/ect/CODESYSControl.cfg" 末尾添加:

[SysCom]
Linux.Devicefile = /dev/ttyUSB
portnum := COM.SysCom.SYS_COMPORT1;

这样,在codesys中指定串口号1,代表使用的设备为 /dev/ttyUSB0, 非常不直观。

从codesys v3.5 SP15 起(据说),改为在文件 /etc/CODESYSControl_User.cfg 里这么设置:

[SysCom]
Linux.Devicefile.1=/dev/ttyS0
Linux.Devicefile.2=/dev/ttyAMA1
Linux.Devicefile.4=/dev/ttyUSB0

这样, Com1 即为 ttyS0, Com2即为 ttyAMA1, Com4 即为 ttyUSB0,依次类推。支持多个串口,方便多了。

如上面设置,映射关系 uart2 --> ttyAMA1 --->  Com2, 所以codesys中指定端口号为 2 (即Com2)即可。

第四步: CodeSys中编程实现串口收发功能

     参考 youtube 上的学习视频: https://www.youtube.com/watch?v=NFREG2U07Rg

      只需参考codesys编程部分即可,代码我在他基础上又做了修改完善,

(1)程序块导入3个库: Memory, Serial Communication, Util

(2)定义部分

PROGRAM SerialPort
VAR
(*打开端口部分*)
Open_0: COM.Open;
Open_xExecute: BOOL := TRUE; //默认打开端口
aParams : ARRAY [1..7] OF COM.PARAMETER := [
(udiParameterId := COM.CAA_Parameter_Constants.udiPort, udiValue := 2),
(udiParameterId := COM.CAA_Parameter_Constants.udiBaudrate, udiValue := 9600),
(udiParameterId := COM.CAA_Parameter_Constants.udiParity, udiValue := INT_TO_UDINT(COM.PARITY.NONE) ),
(udiParameterId := COM.CAA_Parameter_Constants.udiStopBits, udiValue := INT_TO_UDINT(COM.STOPBIT.ONESTOPBIT) ),
(udiParameterId := COM.CAA_Parameter_Constants.udiTimeout, udiValue := 0),
(udiParameterId := COM.CAA_Parameter_Constants.udiByteSize, udiValue := 8),
(udiParameterId := COM.CAA_Parameter_Constants.udiBinary, udiValue := 0)
];
hCom: CAA.HANDLE; (* read模块 *)
BLINK0: BLINK;
Read_0: COM.Read;
bReadData : ARRAY[1..80] OF BYTE;
read_szSize: CAA.SIZE; sReadData : STRING; (* write模块 *)
Write_0: COM.Write;
write_xExecute: BOOL; //执行write操作
bWriteData : ARRAY[1..80] OF BYTE;
sWriteData : STRING;
sWriteDataLast : STRING; //上一次 Write值
END_VAR

(3)梯形图部分

先要 打开串口 (串口参数在定义部分已预设定):

注意此处,参数 xExecute 需始终为 True,否则 会关闭串口 hCom=0 !

读串口部分的代码:

使用 blink 定期读取,读出的内容放到数组 bReadData 中,读出长度为 read_szSize.

为了防止读入空(读出为空是常态,有内容 是少数)时 覆盖掉前面值,非空时才拷贝和更新到某个string,代码如下:

这样,仅在有新内容读出时,才更新值到 sReadData 中。末尾的 MEM.MemFill() 用于写入 string 的结束字符 '\0' .

下面到了 写串口 的部分。基本思路也是差不多,字符串中有新值时,才将 字符串内容 拷贝到 数组中用于写出,并使能一次写动作,代码如下:

之后开始真正的 串口写 动作:

代码后半行,如果写成功,就把此次内容保存到 sWriteDataLast 字串里,用于下一次比较,内容不同时才触发一次 COM.Write() 写动作。

需要注意的是,若写动作发生error,会一直卡住 不更新 sWriteDataLast,所以加上并联条件 Write_0.xError , 不管成功/Error失败 均结束此次写动作!就算写失败,想再一次尝试,也必须将 sWriteData 改为其他才能再次触发 写动作。

(4)CodeSys中测试串口读写功能

若串口正确打开, 则 hCom 的值非空,否则 hCom=0 表示失败。

blink产生的信号定时读一遍数据,有新内容显示在字串 sReadData 中;

字串 sWriteData 中的内容会通过串口写出去,只有更新 sWriteData 值的瞬间才会触发一次写操作,不管是否写出成功。

以上代码,使用 树莓派4B, Codesys 3.5.18.2 ,Codesys Control for Linux ARM64 SL 测试通过。

使用树莓派 自带的 uart2 (ttyAMA1)和  usb转ttl串口(ttyUSB0) 均测试通过。

2022年7月21日

CodeSys中编程实现串口通讯的更多相关文章

  1. 树莓派中QT实现串口通讯

    树莓派中QT实现串口通讯 开发平台为QT 此博客QT使用的为WiringPi驱动 我使用的串口调试助手为 cutecom 先简单说一些开发过程中需要注意的问题 Linux 下设备为 tty ,对应在 ...

  2. 用SPCOMM 在 Delphi中实现串口通讯 转

      用Delphi 实现串口通讯,常用的几种方法为:使用控件如MSCOMM和SPCOMM,使用API函数或者在Delphi 中调用其它串口通讯程序.利用API编写串口通信程序较为复杂,需要掌握大量通信 ...

  3. C# 16进制与字符串、字节数组之间的转换(串口通讯中)

    1.c#中如何将十进制数的字符串转化成十六进制数的字符串//十进制转二进制 Console.WriteLine("十进制166的二进制表示: "+Convert.ToString( ...

  4. VS编程,C#串口通讯,通过串口读取数据的一种方法

    一.可能需要的软件:1.虚拟串口vspd(Virtual Serial Port Driver,用来在电脑上虚拟出一对串口,模拟通讯. 2.友善串口调试助手,用来发送.读取数据. 二.思路1.查询本机 ...

  5. 引用kernel32.dll中的API来进行串口通讯

    串口通讯可以引出kernel32.dll中的API来操作,相关源码如下:using System;using System.Runtime.InteropServices; namespace Tel ...

  6. .Net串口通讯中的若干问题(C#多串口硬件识别、热插拔、Close方法报错问题、IsOpen的可靠性问题)

    一.需求场景 最近有时间静下心来研究SDK,串口通讯的.要求实现识别cp210x和cp2303驱动的两款硬件,并且2303的优先级高,即有2303识别之,没有再识别210x:要求实现热插拔,拔掉自动断 ...

  7. C#中的WinFrom技术实现串口通讯助手(附源码)

    C#中的WinFrom技术实现串口通讯助手(附源码)   实现的功能: 1.实现自动加载可用串口. 2.打开串口,并且使用C#状态栏显示串口的状态. 3.实现了串口的接收数据和发送数据功能. 4.串口 ...

  8. 西门子plc串口通讯方式

    西门子plc串口通讯的三种方式 时间:2015-10-25 14:31:55编辑:电工栏目:西门子plc 导读:西门子plc串口通讯的三种方式,分为RS485 串口通信.PPI 通信.MPI 通信,自 ...

  9. 教程-Delphi MSComm 实时串口通讯

    Delphi  MSComm 实时串口通讯 MSComm控件具有丰富的与串口通信密切相关的属性,提供了对串口进行的多种操作,进而使串行通信变得十分简便.MSComm的控件属性较多,常用的属性如下:1) ...

随机推荐

  1. 利用expect批量修改Linux服务器密码

    一个执着于技术的公众号 背景 修改Linux系统密码,执行passwd即可更改密码.可如果有成千上百台服务器呢,通过ssh的方式逐一进行修改,对我们来说,工作量是非常大,且效率非常低下.因此采用批量修 ...

  2. WSL与Windows环境共享

    Reference 更多cmd.exe帮助参考 cmd_helps WSL备份及windows Docker安装 WSL安装维护 在使用wsl时,总是需要执行windows的cmd,但是windows ...

  3. redis 2 主从和哨兵

    主从: 概念:将一台redis服务器数据复制到其他redis服务器,前者是master,后者是slave.数据复制是单向,从主节点复制到从节点.master以写为主,slave以读为主一个zhu主节点 ...

  4. JavaScript中if语句优化和部分语法糖小技巧推荐

    前言 在前端日常开发过程中,if else判断语句使用的次数应该是比较频繁的了,一些较为复杂的场景,可能会用到很多判断,在某个代码块使用很多if else时,代码会显得较为冗余,阅读起来不够清晰. 除 ...

  5. 抽象数据类型(ADT)

    抽象数据类型(Abstract Data Type,ADT)是指一个数学模型以及定义在这个模型上的一组操作.抽象数据类型的定义仅仅取决于它的一组逻辑特性,而与它在计算机中的表示和实现无关. 例如,in ...

  6. 06vim --- gcc库的制作及使用

    VIM 命令模式下的操作 保存退出 快捷键 操作 ZZ 保存退出 代码格式化 快捷键 操作 gg=G 代码的格式化 光标移动(键盘上下左右键课代替) 快捷键 操作 h 光标左移 j 光标下移 k 光标 ...

  7. python将test01文件夹中的文件剪切到test02文件夹中

    将test01文件夹中的文件剪切到test02文件夹中 import shutil import os def remove_file(old_path, new_path): print(old_p ...

  8. 关于Dotween旋转以及OnValidate函数的解读

    在DoTween中可以选择do旋转.但是旋转模式分成四种,且又有DoLocalRotate和DoRotate的区别,所以在此记录一下. DoLocalRotate和DoRotate的区别在于,前者是基 ...

  9. 记一次前端CryptoJS AES解密

    1.背景 业务需求,需要联动多个平台,涉及到各平台的模拟登录. 已知加密前明文且正常登录.(无验证码要求) 某平台验证验证方式为.\login接口POST一串json字符串 { "accou ...

  10. CSS 技术

    浏览本篇文章前可以先看之前的前端网页介绍和html常用标签以便更容易理解 本文目录: 目录 CSS 技术介绍 CSS 语法规则 CSS 和 HTML 的结合方式 第一种: 第二种 第三种 CSS 选择 ...