附录D:编程基础
D.1 引言
本附录介绍了编程基础及其在底层(机器级和汇编级)的方法,以访问输入– 输出(I/O)模块中的各个寄存器,实现数据采集与控制。
D.2 底层编程
较低级别的编程方法使用机器语言和汇编语言,这将在后续章节中讨论。
D.2.1 机器级
编程的起点是机器级。这需要充分了解处理器架构及其指令集。在机器级进行编码主要是使用由0和1组成的组合。程序和数据的加载是手动完成的。这种方法不适合大型程序,但曾用于输入小型引导程序,以启动机器并将控制权移交给交互式终端。为了便于实现,计算机配备了带有开关的交互式控制台(硬连线),通过开关将由0和1组成的组合输入到指定的内存地址,并通过控制台指示灯显示指定地址位置的内容。此后,这种方法已被存储在计算机非易失性存储器中的引导程序所取代,该引导程序在机器开机时自动激活。
D.2.2 汇编级
由于使用0和1进行编码既不方便又容易出错,因此汇编级编程取代了机器级编程。汇编级编程同样需要全面了解处理器架构及其指令集。唯一的区别是在编写程序时使用助记符来缩写各种指令、地址、标签和数据。汇编器是由数据采集控制单元(DACU)供应商提供的程序,可将汇编级程序转换为其等效的机器可执行代码。在此过程中,汇编级程序中的每一行都转换为一条机器级指令(一一对应)。汇编器程序在开发系统程序方面非常有效,因为它们能够充分利用处理器的架构。
D.3 编程示例
在以下示例中,假设内存中的前 256 个存储位置(地址从 000000₈ 到 000377₈)分配给用户程序(指令),接下来的 256 个存储位置(地址从 001000₈ 到 002777₈)保留用于用户数据。此外,处理器在 powering-on 时会自动从位置 0 (000000₈) 开始执行程序。
当处理器需要读取或写入功能模块中的内存地址或寄存器以执行指令时,地址便成为指令的一部分。由于地址为16位,因此会与指令一起以2字节(先低字节后高字节)的形式连续存储,如下列编程示例所示。这些程序同时展示了机器级及其对应的汇编语言。
本附录中讨论的编程示例采用以下步骤:
- 从输入模块的寄存器中读取的输入数据在内存的输入映像缓冲区中形成输入图像(数据采集)。
- 程序对输入映像缓冲区中的最新可用数据进行操作,并将结果存储在内存中的输出映像缓冲区(OPIB)中。
- OPIB的内容被写入输出模块的寄存器,以实现过程控制。
通过这些配置,I/O模块中的寄存器与程序相互分离。换句话说,程序始终与输入图像和输出图像缓冲区进行接口交互。以下是采用此方法处理过程数据采集、数据分析与决策、过程控制以及通信的编程示例。
此外,在所有程序中,在输入输出扫描之前,会检查I/O模块的状态,如果发现模块存在故障,则激活看门狗。看门狗模块的原理图和地址分配如图 D.1 所示。
这在所有后续的编程示例中都很常见。
D.3.1 数字输入-输出编程
问题:从过程获取离散输入,并在操作面板的指示灯上显示
这是一个使用数字输入(DI)模块读取过程中的离散输入状态,并使用数字输出(DO)模块驱动操作面板上指示灯的示例。
表D.1 显示了汇编级别的程序及其对应的机器码。
| 内存地址 | 汇编级指令 | 内容 | 标签 | 指令 | 备注 | 程序区域 |
|---|---|---|---|---|---|---|
| 000000 | 001 | STR | LDA DIR0 | 读取状态寄存器 DIR0 | 程序区域 | |
| 000001 | 000 | |||||
| 000002 | 170 | |||||
| 000003 | 010 | ANA XXX | 提取 DIR0 中的位 7(诊断位) | |||
| 000004 | 400 | |||||
| 000005 | 000 | |||||
| 000006 | 031 | JNZ WDG | 如果模块故障,跳转以激活看门狗 | |||
| 000007 | 060 | |||||
| 000010 | 000 | |||||
| 000011 | 001 | LDA DOR0 | 读取状态寄存器 DOR0 | |||
| 000012 | 010 | |||||
| 000013 | 360 | |||||
| 000014 | 010 | ANA XXX | 提取 DOR0 中的位 7(诊断位)来自 DOR0 | |||
| 000015 | 000 | |||||
| 000016 | 001 | |||||
| 000017 | 031 | JNZ WDG | 如果模块故障,跳转以激活看门狗 | |||
| 000020 | 060 | |||||
| 000021 | 000 | |||||
| 000022 | 001 | LDA DIR0 | 读取状态寄存器 DIR0 | |||
| 000023 | 000 | |||||
| 000024 | 360 | |||||
| 000025 | 010 | ANA YYY | 检查新数据 | |||
| 000026 | 201 | |||||
| 000027 | 001 | |||||
| 000030 | 032 | JMZ STR | 若无新数据则返回开始 data | |||
| 000031 | 000 | |||||
| 000032 | 000 | |||||
| 000033 | 001 | LDA DIR1 | 读取输入数据寄存器 DIR1 | |||
| 000034 | 000 | |||||
| 000035 | 361 | |||||
| 000036 | 002 | STA IPIB‐DIR1 | 存储到输入图像缓冲区 | |||
| 000037 | 100 | |||||
| 000040 | 001 | |||||
| 000041 | 001 | LDA IPIB‐DIR1 | 从输入读取图像缓冲区 | |||
| 000042 | 101 | |||||
| 000043 | 001 | |||||
| 000044 | 002 | STA OPIB‐DOR1 | 存储到输出图像缓冲区 | |||
| 000045 | 100 | |||||
| 000046 | 001 | |||||
| 000047 | 001 | LDA OPIB‐DOR1 | 读取图像输出缓冲区 | |||
| 000050 | 100 | |||||
| 000051 | 001 | |||||
| 000052 | 002 | STA DOR1 | 存储到数据输出 DOR1 寄存器 | |||
| 000053 | 011 | |||||
| 000054 | 360 | |||||
| 000055 | 030 | JMP STR | 重复程序 | |||
| 000056 | 000 | |||||
| 000057 | 000 | |||||
| 000060 | 001 | WDG | LDA ZZZ | 用于提取的加载掩码看门狗位的提取看门狗位 | ||
| 000061 | 002 | |||||
| 000062 | 000 | |||||
| 000063 | 002 | STA WDR1 | 驱动看门狗 | |||
| 000064 | 111 | |||||
| 000065 | 111 | |||||
| 000066 | 030 | JMP STR | 重复程序 | |||
| 000067 | 000 | |||||
| 000070 | 000 |
数据区域
| 地址 | 内容 | 标签 | 说明 |
|---|---|---|---|
| 000400 | 200 | XXX | 用于提取诊断位 |
| 000401 | 010 | YYY | 用于提取新的数据位 |
| 000402 | 002 | ZZZ | 用于驱动看门狗 bit |
| 000500 | IPIB‐DIR1 | ||
| 000501 | OPIB‐DOR1 |
a地址表示程序区域中的程序计数器。
表D.1 机器/汇编级程序用于数字输入‐输出——续
D.3.2 模拟输入-输出编程
问题:从过程获取一个连续输入,并在操作面板的仪表上显示
这是一个通过模拟输入模块(通道0)从过程中读取连续参数值,并通过模拟输出模块(通道0)将其驱动到操作面板上显示仪表的示例。图D.4 描述了该原理图,图D.5 显示了流程图,而表D.2 展示了其汇编级语言程序。
编程:原理图和地址分配)
模块编程)
| 汇编级指令 | 标签 | 指令 | 备注 | 程序区域 |
|---|---|---|---|---|
| STR | LDA AIR0 | 加载状态寄存器AIR0 | 程序区域 | |
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,跳转到执行‐ 激活看门狗 | |||
| LDA AOR0 | 加载状态寄存器AOR0 | |||
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,跳转到执行‐ 激活看门狗 | |||
| LDA AIR1 | 加载数据输入寄存器AIR1 | |||
| STA IPIB‐AIR1 | 存储到输入映像缓冲区 | |||
| IPIB‐AIR1 | LDA IPIB‐AIR1 | 读取输入映像缓冲区 IPIB‐AIR1 | ||
| IPIB‐AIR1 | STA 输出图像缓冲区 AOR1 | 存储到输出图像缓冲区 | ||
| 输出图像缓冲区AOR1 | LDA 输出图像缓冲区 AOR1 | 加载输出图像缓冲区 输出图像缓冲区AOR1 | ||
| 输出图像缓冲区AOR1 | STA AOR1 | 存储到数据输出寄存器AOR1 | ||
| JMP STR | 重复程序 | |||
| WDG | LDA YYY | 用于提取的加载掩码 看门狗位 | ||
| STA WDR1 | 驱动看门狗 | |||
| JMP STR | 重复程序 |
数据区域
| 标签 | 内容 | 说明 |
|---|---|---|
| XXX | ‘ 200’ | 诊断提取掩码 bit |
| YYY | ‘ 002’ | 驱动看门狗位的掩码 |
| IPIB‐AIR1 | 输入图像 | |
| 输出图像缓冲区 AOR1 | 输出图像 | |
| ## D.3.3 脉冲输入-输出编程 |
问题:从过程获取一个脉冲输入,并在操作面板的计数器上显示
这是一个使用脉冲输入模块(通道0)读取过程中的脉冲,并通过脉冲输出模块(通道0)将脉冲驱动到操作面板上的显示计数器的示例。图D.6 描述了原理图,图D.7 展示了流程图,而表D.3 显示了其汇编级语言程序。
| 汇编级指令 | 标签 | 指令 | 注释 | 程序区域 |
|---|---|---|---|---|
| STR | LDA PIR0 | 加载状态寄存器PIR0 | 程序区域 | |
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,则跳转到activate 看门狗 | |||
| LDA POR0 | 加载状态寄存器PIR0 | |||
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,则跳转到 activate 看门狗 | |||
| 循环1 | LDA PIR0 | 加载状态寄存器PIR0 | ||
| AND YYY1 | 检查计数器是否满 | |||
| JZ 循环1 | 如果计数器未满, wait | |||
| LDA PIR1 | 加载输入数据寄存器PIR1 | |||
| STA IPIB‐PIR1 | 存储到输入映像缓冲区 | |||
| IPIB‐PIR1 | LDA IPIB‐PIR1 | 加载输入图像缓冲区 IPIB‐PIR1 | ||
| IPIB‐PIR1 | STA OPIB‐POR1 | 存储到输出图像缓冲区 OPIB‐POR1 | ||
| LOOP2 | LDA POR0 | 加载状态寄存器 POR0 | ||
| ANA YYY2 | 检查计数器是否为空 | |||
| JZ LOOP2 | 如果计数器不为空,则等待 | |||
| LDA OPIB‐POR1 | 加载输出映像缓冲区 OPIB‐POR1 | |||
| STA POR1 | 存储到数据输出寄存器 POR1 | |||
| JMP STR | 重复程序 | |||
| WDG | LDA ZZZ | 用于提取的加载掩码 看门狗位 | ||
| STA WDR1 | 驱动看门狗 | |||
| JMP STR | 重复程序 |
数据区域
| 标签 | 内容 | 说明 |
|---|---|---|
| XXX | ‘ 200’ | 诊断提取掩码 bit |
| YYY1 | ‘002’ | 计数器满遮罩 |
| YYY2 | ‘002’ | 计数器空遮罩 |
| ZZZ | ‘ 002’ | 驱动看门狗位的掩码 |
| IPIB‐PIR1 | 输入图像 | |
| OPIB‐POR1 | 输出图像 |
D.3.4 通信编程
问题:从介质1接收消息并发送到介质2
这是使用通信模块1从介质1读取传入消息,并通过通信模块2将其发送到介质2的示例。图D.8展示了原理图,图D.9显示了流程图,以及表D.4展示了其在机器和汇编级语言中的程序。
| 汇编级指令 | 标签 | 指令 | 备注 | 程序区域 |
|---|---|---|---|---|
| STR | LDA CMR0‐2 | 加载状态寄存器CMR0‐1 | 程序区域 | |
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,则跳转到 激活看门狗 | |||
| LDA CMR0‐2 | 加载状态寄存器CMR0‐2 | |||
| ANA XXX | 提取第7位(诊断位) | |||
| JNZ WDG | 如果模块故障,则跳转到 激活看门狗 | |||
| LOOP1 | LDA CMR0‐1 | 加载状态寄存器CMR0‐1 | ||
| AND YYY1 | 检查缓冲区是否满 | |||
| JZ 循环1 | 如果消息未满,等待 | |||
| LDA CMR1‐1 | 加载输入数据寄存器 CMR1‐1 | |||
| STA IPIB‐CMR1‐1 | 存储到输入映像缓冲区 | |||
| IPIB‐CMR1‐1 | LDA IPIB‐CMR1‐1 | 加载输入图像缓冲区 IPIB‐CMR1‐1 | ||
| IPIB‐CMR1‐1 | STA OPIB‐CMR2‐2 | 存储到输出图像缓冲区 OPIBCMR2‐2 | ||
| LOOP2 | LDA CMR0‐2 | 加载状态寄存器CMRO‐2 | ||
| ANA YYY2 | 检查缓冲区是否为空 | |||
| JZ LOOP2 | 如果计数器不为空,则等待 | |||
| LDA OPIB‐CMR2‐2 | 加载输出图像缓冲区 OPIB‐CMR2‐2 | |||
| STA CMR2‐2 | 存储到数据输出寄存器 CMR2‐2 | |||
| JMP STR | 重复程序 | |||
| WDG | LDA ZZZ | 用于提取的加载掩码 看门狗位 | ||
| STA WDR1 | 驱动看门狗 | |||
| JMP STR | 重复程序 |
数据区域
| 标签 | 内容 | 说明 |
|---|---|---|
| XXX | ‘ 200’ | 用于提取诊断位的掩码‐ 诊断位 |
| YYY1 | ‘010’ | 缓冲区满掩码 |
| YYY2 | ‘020’ | 缓冲区空掩码 |
| ZZZ | ‘ 002’ | 驱动看门狗位的掩码 |
| IPIB‐CMR1‐1 | 输入图像 | |
| OPIB‐CMR2‐2 | 输出图像 |
D.3.5 中断编程
问题:在过程报警发生时立即响应并启动看门狗(声光报警)
这类似于第一个示例,其中通过DI模块获取过程指示,并使用DO模块将信号发送到模拟面板上的指示灯;这是通过连续扫描新数据来实现的。唯一的区别是,使用了硬件中断装置,以便在满足条件时立即执行任务,前提是已启用DI模块以中断处理器。在中断编程中,会发生以下情况:
- 处理器使能数字输入模块以产生中断。
- 处理器继续执行当前程序。
- 数字输入模块在其任一输入状态发生变化时,会在其状态寄存器中设置一个新的数据位,并向处理器发出中断请求。
- 处理器在完成当前指令的执行后,会在执行当前程序的下一条指令之前,检查是否存在待处理的中断。
- 处理器在识别到中断后,暂停当前程序的进一步执行。
- 处理器自动将当前(被中断)程序的最新执行状态(程序计数器、累加器的内容)保存到内存中的先进后出堆栈中。
- 处理器跳转到通用中断服务程序,以确定中断源(在当前情况下为数字输入模块)。
- 处理器跳转到数字输入服务程序。
- 处理器读取DI模块的输入数据寄存器,并将其存储在内存中的输入映像缓冲区。
- 处理器从内存中的先进后出堆栈恢复被中断程序的状态,返回到被中断的程序(被中断程序的恢复)。
当出现故障时(通过设置其诊断位),也可以使用模块中断功能,以防止在先前的程序中检查模块故障。
| 汇编级指令 | 标签 | 指令 | 备注 |
|---|---|---|---|
| 主程序 | |||
| AAA | XXX | 第n‐2条指令 | |
| BBB | YYY | 第n‐1条指令 | |
| 中断 | CCC | ZZZ | 指令 n 保存被中断的程序 状态在堆栈中且跳转到中断服务程序 |
| DDD | PPP | 指令 n+1 | |
| EEE | QQQ | 指令 n+2 | |
| 中断服务程序 | |||
| ISR | 查找中断源的编程指令 | ||
| ............ | |||
| ............ | |||
| JMP DISR | 跳转到数字输入服务程序 | ||
| 数字输入中断服务程序 | |||
| DISR | LDA DIR0 | ||
| ANA XXX | 提取第7位(诊断位) | ||
| JNZ WDG | 如果模块故障,跳转以激活看门狗 | ||
| LDA DOR0 | 加载状态寄存器 DOR0 | ||
| ANA XXX | 提取位 7(诊断位) | ||
| JNZ WDG | 如果模块故障,跳转以激活看门狗 | ||
| LDA DIR1 | 加载数据输入寄存器 DIR1 | ||
| STA IPIB‐DIR1 | 存储到输入映像缓冲区 IPIB‐DIR1 | ||
| LDA IPIB‐DIR1 | 读取输入映像缓冲区IPIB‐DIR1 | ||
| STA OPIB‐DOR1 | 存储到输出图像缓冲区OPIB‐DOR1 | ||
| LDA OPIB‐DOR1 | 加载输出图像缓冲区OPIB‐DOR1 | ||
| STA DOR1 | 存储到数据输出寄存器DOR1 | ||
| RTS STR | 返回主程序 | ||
| WDG | LDA YYY | 加载用于提取看门狗位的掩码 | |
| STA WDR1 | 驱动看门狗 | ||
| RTS | 返回 恢复中断 从堆栈恢复程序状态 并返回到中断 程序 |
数据区域
| 标签 | 内容 | 说明 |
|---|---|---|
| XXX | ‘200’ | 诊断位提取掩码 |
| YYY | ‘ 002’ | 驱动看门狗位的掩码 |
| IPIB‐DIR1 | 输入图像 | |
| OPIB‐DOR1 | 输出图像 |
D.4 程序汇编
用汇编级语言编写(编码)的自动化程序需要转换为机器可执行代码,以便处理器执行。这一过程称为汇编,由DACU供应商提供的一个特殊程序——汇编器来完成。从技术上讲,此转换可以使用DACU本身在离线模式下进行,如图 D.11 所示。
然而,与通用计算机不同,DACU 专为实时执行自动化功能而优化。其编程环境资源有限,因此不用于汇编过程。该过程在离线情况下完成在主机中进行的这种操作称为交叉汇编,它使用由DACU供应商提供的交叉汇编器软件。
主机也称为编程设备或编程终端(通常为个人计算机或手持编程器)。供应商提供的针对DACU的交叉汇编程序在主机上运行,以生成适用于DACU的机器码。此处,DACU被称为目标机器。交叉汇编过程如图D.12所示。
除了帮助程序员编写程序外,主机或编程终端还将汇编级程序转换为机器可执行程序,并将生成的机器码下载到目标机器中。主机还为程序员提供以下附加功能:
- 编辑
- 调试
- 仿真与测试
- 故障排除
- 文档与报告
- 存储
基于计算机的手持编程器紧凑,更适合作为现场设备用于工厂或车间的故障排除。
D.5 高级编程
在汇编级别对自动化程序进行编码,会使该编码的自动化程序仅能在为其编写代码的特定DACU平台上执行,而无法在其他任何平台上运行。因此,使用高级语言进行机器编程,这些语言易于程序员理解,从而使程序具有可移植性,能够在其他机器和平台上使用,仅需最少的调整即可。
DACU的自动化功能编程通过使用国际电工委员会61,131‐3标准所涵盖的高级语言来实现,如第9章中所述。与汇编器程序类似,编译程序由平台供应商开发。它将高级语言程序转换为其可执行的机器代码等效形式,并将其下载到DACU(目标机器)中。与每行程序转换为一条机器指令的汇编器不同,编译器将每行程序转换为多条指令序列。编译过程不如汇编过程高效,因为前者未充分利用平台的硬件特性。编译、交叉编译和下载的过程与汇编过程相同,只是输入程序不同(汇编级别或更高级别)。
高级编程在第9章中讨论。
2803

被折叠的 条评论
为什么被折叠?



