Modbus ASCII是Modbus的一种消息帧,相比RTU,ASCII的传输是按照문자传的,传输的데이터量会比RTU更多,所以데이터量大的时候一般使用的RTU,데이터量小的时候才会用ASCII,然后ASCII프로토콜帧里面추가了시작和종료,更换了체크섬算法,下面详细介绍ASCII프로토콜
帧형식
Modbus ASCII 모드下的通讯帧형식如下:
| 名称 | 길이 (바이트) | 설명 |
|---|---|---|
| Start | 1 | 以콜론 : 开头,ASCII 16진수值为 3A |
| 주소 | 2 | 16진수节点주소,문자表示 |
| 기능 | 2 | 16진수기능 코드,문자表示 |
| 데이터 | n x 2 | n 是데이터바이트数,它取决于기능 코드 |
| LRC | 2 | LRC冗余检验码 |
| End | 2 | CR / LF |
注:주소、功能、데이터和 LRC 都是表示 8 位值 (0-255) 的大写16진수可读문자对;即:在 Modbus ASCII 中,每个데이터바이트被分割成表示16진수值中的两个 ASCII 문자的两个바이트。
| 组件 | 설명 | 문자数 | ASCII表示 |
|---|---|---|---|
| Start | 消息开始 | 1 CHAR | : |
| 주소 | 节点주소(16진수表示) | 2 CHARS | |
| 기능 | 기능 코드(16진수表示) | 2 CHARS | |
| 데이터 | 데이터(根据기능 코드变化,16진수表示) | n CHARS | |
| LRC CHECK | 纵向冗余检验码(LRC) | 2 CHARS | |
| END | 消息종료,줄바꿈(CRLF) | 2 CHARS | CRLF |
在 ASCII 모드下,Modbus 消息的每个部分都以特定的문자数和형식出现,如下所示:
:AA BB CC...DD EE<CRLF>
:- 消息的开始符号。AA- 节点주소,16진수表示。BB- 기능 코드,16진수表示。CC...DD- 데이터필드,根据기능 코드和需要传输的데이터길이变化。EE- LRC 체크섬,用于错误检测。<CRLF>- 消息的종료符号,代表回车和换行(Carriage Return Line Feed)。

ASCII帧的传输状态

上面状态图可以得到的信息:
1)“空闲” 态是没有보내기和수신프레임要处理的正常状态。
2)每次수신到 ":" 문자表示新的프레임的开始。如果在一个프레임的수신过程中收到该문자,则当前地프레임被认为不完整并被丢弃。而一个新的수신缓冲区被重新分配。
3)检测到帧종료后,完成 LRC 계산和检验。然后,分析주소域以确定帧是否发往此设备,如果不是,则丢弃此帧。 为了减少수신处理时间,주소域可以在一接到就分析,而不需要等到整个帧종료。
ASCII帧的프레임传输
由于ASCII프레임帧与RTU프레임帧有着很大的不同,ASCII프레임帧是有시작和종료标识符的,而RTU帧没有这样的标识。所以ASCII프레임帧的수신就简单方便多了,也不需要什么t3.5的帧间隔时间。
但是呢,为了保证수신的프레임帧连续,还是可以约定문자间的传输时间的。一般认为,프레임中的문자时间间隔可以达到一秒,如果超过了这个时间间隔,就认为发生了错误,要废弃掉这一帧프레임데이터,重新开始수신。
기능 코드
ASCII 모드下最常用的功能代码与 RTU 모드下的功能代码定义相同。以下是一些基本的기능 코드及其설명:
| 访问주소 | 映射주소 | 설명 | 功能 | R/W |
|---|---|---|---|---|
| 1 ~ 10000 | 주소-1 | Coils | 01/05/15 | R/W |
| 10001 ~ 20000 | 주소-10001 | Discrete Inputs | 02 | R |
| 30001 ~ 40000 | 주소-30001 | Input 회원가입s | 04 | R |
| 40001 ~ 50000 | 주소-40001 | Holding 회원가입s | 03/06/16 | R/W |
ASCII传输예제
例如,要읽기주소 0x20C1 的两个레지스터,需要보내기以下 ASCII 消息:
:010420C1000218<CRLF>
请求:
:- 消息开始 - 0x3A01- 슬레이브 주소 - 0x0104- 기능 코드 (입력 레지스터 읽기 (FC04)) - 0x0420C1- 要읽기的레지스터주소 - 0x20C10002- 要읽기的레지스터길이 (必须是 2) - 0x000218- LRC 체크섬<CRLF>- 消息종료,줄바꿈(CRLF) - 0x0D0A
响应:
:01040400001234B1<CRLF>
响应:
:- 消息开始 - 0x3A01- 슬레이브 주소 - 0x0104- 기능 코드 (입력 레지스터 읽기 (FC04)) - 0x0404- 읽기데이터길이 (4 바이트) - 0x0400001234- 从 VAR1 읽기的值 - 0x00001234B1- LRC 체크섬<CRLF>- 消息종료,줄바꿈(CRLF) - 0x0D0A
常用기능 코드操作
以下是 Modbus 的常用기능 코드及其请求和响应예제:
功能 01(01H)读코일
- 请求:읽기从机中코일的 ON/OFF 状态。

- 响应:코일 상태响应消息被打包为데이터필드的每比特表示一个코일。

功能 02(02H)读이산 입력
- 请求:읽기从机中이산 입력的 ON/OFF 状态。

- 响应:이산 입력状态响应消息的构造与코일 상태相同。

功能 03(03H)读유지 레지스터
- 请求:읽기从机中유지 레지스터的2진수콘텐츠。

- 响应:유지 레지스터데이터在每个레지스터中打包为两个바이트。

功能 04(04H)读입력 레지스터
- 请求:읽기从机中입력 레지스터的2진수콘텐츠。

- 响应:读입력 레지스터데이터的响应消息的构造与유지 레지스터 읽기 (FC03)相同。

功能 05(05H)写单코일
- 请求:将单个코일쓰기 ON 或 OFF。

- 响应:正常的响应是请求的回显。

功能 06(06H)写单个유지 레지스터
- 请求将一个值쓰기单个유지 레지스터中。当广播时,该函数在所有附加的从机上设置相同的레지스터引用。请求消息指定要쓰기的레지스터引用(指定주소和数值)。

- 响应

功能 15(0FH)写多个코일
- 请求:将一个코일시퀀스中的每个코일쓰기 ON 或 OFF。

- 响应:正常响应返回从주소、功能代码、시작주소和쓰기的코일 수량。

功能 16(10H)写多个유지 레지스터
- 请求:将值쓰기到一个유지 레지스터시퀀스中。

- 响应:正常响应返回从주소、功能代码、시작주소和쓰기的레지스터 수량。

LRC체크섬
LRC 체크섬的계산方法如下:
unsigned char ucMBLRC( unsigned char * pucFrame, unsigned short usLen )
{
unsigned char ucLRC = 0; /* LRC char initialized */
while( usLen-- )
{
ucLRC += *pucFrame++; /* Add buffer byte without carry */
}
/* Return twos complement */
ucLRC = ( UCHAR ) ( -( ( CHAR ) ucLRC ) );
return ucLRC;
}
답글 작성