第一步: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. Java语言的词法分析器的Java实现

    一.实验目的 1. 学会针对DFA转换图实现相应的高级语言源程序. 2. 深刻领会状态转换图的含义,逐步理解有限自动机. 3. 掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理. 二.实验内 ...

  2. ONNX Runtime 源码阅读:Graph::SetGraphInputsOutputs() 函数

    目录 前言 正文 总结 前言 为了深入理解ONNX Runtime的底层机制,本文将对 Graph::SetGraphInputsOutputs() 的代码逐行分析. 正文 首先判断Graph是否从O ...

  3. fxksmdb.exe 是什么进程?

    今天打开电脑应用进程发现fxksmdb.exe.fxksmpl.exe.fxksmW.exe三个进程,经过查看文件路径发现原来是施乐打印机的驱动程序自带的应用,平时都没注意到这个,这下放心了. 我这里 ...

  4. 手摸手,带你实现移动端H5瀑布流布局

    移动端瀑布流布局是一种比较流行的网页布局方式,视觉上来看就是一种像瀑布一样垂直落下的排版.每张图片并不是显示的正正方方的,而是有的长有的短,呈现出一种不规则的形状.但是它们的宽度通常都是相同的 因为移 ...

  5. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

  6. 让服务调用更简单 - Caller.HttpClient

    前言 绝大多数项目都离不开服务调用,服务的调用方式通常是基于Http.RPC协议的调用,需要获取到对应服务的域名或者ip地址以及详细的控制器方法后才能进行调用,如果项目需要支持分布式部署,则需要借助服 ...

  7. zabbix 添加监控交换机温度item

    首先需要获取到交换机温度对应的OID,可以官方文档进行查询(多为私有OID),以盛科为例 官方文档查询到温度节点对于的OID为 10.0.3.102 1.3.6.1.4.1.27975.37.1.3. ...

  8. zabbix-agent python脚本侦听服务器异常登录,并告警

    py脚本 import re,subprocess,time,datetime #gpasswd -a zabbix adm def ftime(a): a = a.replace('Jan','01 ...

  9. 重新认识 MSBuild - 1

    前言 很多人一谈到 MSBuild,脑子里就会出现 "XML"."只能用 VS 的属性框图形界面操作"."可定制性和扩展性差" 和 &quo ...

  10. Element UI DatePicker 时间跨度限制在同一个月内

    <el-date-picker :picker-options="pickerOptions" v-model="rangeTime" type=&quo ...