940 likes | 1.09k Views
开关量输入输出通道 与顺序控制. (8 学时 ). 训练目的. 1. 了解计算机如何采集工业系统中的开关量运行状态。 2. 了解计算机如何输出开关信号控制工业系统运行。. 设备与器材. IPC-610 工业控制计算机 数据采集控制板卡( PCL-812PG) PCLD-880 REV. A1 端子板 20 芯扁平电缆 自制 DI/DO 通道电路板 各色导线若干 螺丝刀. 工业控制系统的一种构建方式 —— 工控机+采集卡 + 端子板. 人 - 机界面. 机 - 机界面. 工 业 系 统. 数据通道. 端子板 (电气连接). 采集卡.
E N D
开关量输入输出通道与顺序控制 (8学时)
训练目的 • 1.了解计算机如何采集工业系统中的开关量运行状态。 • 2.了解计算机如何输出开关信号控制工业系统运行。
设备与器材 • IPC-610工业控制计算机 • 数据采集控制板卡(PCL-812PG) • PCLD-880 REV. A1端子板 • 20芯扁平电缆 • 自制DI/DO通道电路板 • 各色导线若干 • 螺丝刀
工业控制系统的一种构建方式——工控机+采集卡+端子板工业控制系统的一种构建方式——工控机+采集卡+端子板 人-机界面 机-机界面 工 业 系 统 数据通道 端子板 (电气连接) 采集卡 人和计算机能相互交换信息
数据通道 工业系统 数据总线 数据通道的分类
ACL-8112PG数据采集卡介绍 • 16路开关量输入通道DI(digital input) • 16路开关量输出通道DO(digital output) • 16路单端模拟输入通道A/D(analog to digital) • 2路模拟输出通道D/A(digital to analog) • 12位数据采集卡
ACL-8112PG采集卡在工控机中的安装 (AD/DA) (DO) • CN1:开关量输出 • CN2:开关量输入 • CN3:模拟量单端输入与输出 (DI)
端子板 PCLD-880端子板
端子板介绍 • 作用: 1. 是采集卡与每一个信号调理电路或驱动装置之间的电气连接部件; 2. 可以对每路信号实现简单的调理(如:经电阻衰减、分流、或经过RC低通滤波等) • 选用原则: 能够与所选采集卡的信号位数和通道数目配合使用。
ACL-8112PG采集卡和端子板对应关系 至采集卡CN2 ( DI ) 至采集卡CN1 ( DO )
数据采集卡 接口 20芯扁平线
寻址方式 • 计算机按地址访问各个外部设备的端口(I/O port) • 采集卡:集多通道于一体,具有多个端口,每个端口都有各自的端口地址。 • 板卡端口地址=基地址 +偏移量 • 本板卡基地址=0x220 (由板卡跳线所决定) • 偏移量地址:由所用的寄存器决定 Base offset
寻址方式说明: 3 基地址 楼栋编号 523 ? 偏移地址 房屋编号 3523 寻址的地址 门牌号 楼栋编号 房屋编号
开关量输入输出寄存器 DI: 16个开关输入量的低高字节分别占用输入通道地址Base+6和Base+7 数据格式如下: DO: 16个开关输出量的低高字节分别占用输出通道地址Base+13和Base+14 数据格式如下:
电源 DO 接线端 红色发光二极管对应DO通道输出 DI 接线端 光电对管控制绿灯状态,对应DI通道输入 DI/DO电路板
训练内容—开关量通道演示 1、 运行演示程序 (桌面test.exe演示程序) 说明: • 演示程序位置:桌面→test.exe • 进入“开关量通道” • DI:遮挡光电对管,观察接收的输入状态 • DO:置0或1控制输出,观察红色发光二极管的亮暗状态 • 体会DI和DO通道的意义和作用
训练内容接线示意图 Warning: 关机状态下接线! 仔细检查无误后再开机! 六线 六线
注意事项 • 在关机状态下,正确连接工控机、端子板、DI/DO电路板之间的电缆和导线! • 正确调节DI/DO电路板的电源电压!(用直流稳压电源供电时)
采集板卡数据输入/输出说明 Outportb(地址,数值) Inportb(地址)
训练2、简单例程的运行 例1 开关量的输入: int BASE_ADDRESS=0x220; main() { int DI_in; DI_in =inportb(BASE_ADDRESS+6); printf(“\n%d”, DI_in ); } 例2 开关量的输出: int BASE_ADDRESS=0x220; main() { int DO_out; DO_out =10; outportb(BASE_ADDRESS+13, DO_out); }
作业 • 阅读并注释附录4的例程;
开关量输入输出通道与顺序控制 第二讲
本次课的主要内容 • 上次课主要知识点的回顾; • 进一步熟悉控制系统中常用的几个函数; • DI、DO范例讲解; • 补充知识:C语言程序调试过程; • 上机训练,单步运行例程,熟悉调试过程,进一步理解I/O端口输入输出函数。
数据通道 工业系统 数据总线 回顾:数据通道的分类
回顾:寻址方式 • 计算机按地址访问各个外部设备的端口(I/O port) • 采集卡:集多通道于一体,具有多个端口,每个端口都有各自的端口地址。 • 板卡端口地址=基地址 +偏移量 • 本板卡基地址=0x220 (由板卡跳线所决定) • 偏移量地址:由所用的寄存器决定 Base offset
Turbo c的输入、输出函数 • 格式输入输出函数: • 格式输入函数:scanf(格式控制,地址列表) 例: scanf(“%d,%d”,&n,&m); • 格式输出函数: printf(格式控制,输出列表) 例:printf(“This’s a test!\n %d”, n); • I/O 端口读写: • 输入函数: inportb(端口地址) /*读端口(寄存器)*/ 例:DI_in=inportb(0x220+6); • 输出函数: outportb(端口地址,变量名) /*写端口(寄存器)*/ 例:outportb(0x220+13,out);
键盘控制 bioskey(int cmd)它在bios.h头文件中进行了说明该函数实际上调用了BIOS的INT16H中断,参数用来确定bioskey()如何操作
DI通道程序 int BASE_ADDRESS=0x220; int creat_DI(int *DI_NUM, int num) { int i=0; for(i=0;i<6;i++) DI_NUM[i]=(num>>i)&0x01; return; } 指针变量
DI通道程序 int BASE_ADDRESS=0x220; /*设置板卡基地址*/ int creat_DI(int *DI_NUM, int num) { int i=0; for(i=0;i<6;i++) DI_NUM[i]=(num>>i)&0x01; /*取第i位数*/ return; /*返回到调用函数*/ } /*DI子函数,目的是把字节中的每一位取出,放入数组*/ 指针变量
creat_DI子函数说明1 Num=14 右移一位 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 i=1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 与 与 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 i=0 DI_NUM[0]=0 DI_NUM[1]=1
creat_DI子函数说明2 0 0 0 0 1 1 1 0 i=2 右移2位 右移5位 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 i=5 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 与 与 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 DI_NUM[2]=1 DI_NUM[5]=0
Num=14 0 0 0 0 1 1 1 0 DI_NUM[0]=0DI_NUM[1]=1DI_NUM[2]=1DI_NUM[3]=1 DI_NUM[4]=0DI_NUM[5]=0 creat_DI子程序说明 int BASE=0x220; int creat_DI(int *DI_NUM, int num) { int i=0; for(i=0;i<6;i++) DI_NUM[i]=(num>>i)&0x01; return; } creat_DI子函数功能:获取整数的位值
DI通道程序(续) main() { int DI[6]={0}; int DI_out; char c; clrscr(); while(1) { DI_out=inportb(BASE_ADDRESS+6); creat_DI(DI,DI_out); printf(“\n%d,%d,%d,%d,%d,%d\n”,DI[0],DI[1],DI[2],DI[3], DI[4],DI[5]); printf("\n Press n to next and other key to quit!\n"); c=bioskey(0); if(c=='n'||c=='N') continue; else return; } }
DI通道程序(续) main() /*DI主函数*/ { int DI[6]={0}; int DI_out; char c; /*定义数组和变量*/ clrscr(); /*清屏*/ while(1) { DI_out=inportb(BASE_ADDRESS+6); /*读DI低字节*/ creat_DI(DI,DI_out); /*调用子函数*/ /*把DI低字节寄存器中每一个输入的开关量取出放入数组*/ printf(“\n%d,%d,%d,%d,%d,%d\n”,DI[0],DI[1],DI[2],DI[3], DI[4],DI[5]); /*显示输入的开关量*/ printf("\nPress n to next and other key to quit!\n"); c=bioskey(0); /*BIOS接口调用函数,返回从键盘上输入的字符*/ if(c=='n'||c=='N') continue; /*结束本次循环,继续下次循环*/ else return; /*退出*/ } }
DO通道程序 int BASE_ADDRESS=0x220; int creat_DO(int *DO_NUM) { int temp=0; int i=0; for(i=5;i>0;i--) { temp=(temp+DO_NUM[i])*2; } return temp+DO_NUM[0]; }
DO通道程序 int BASE_ADDRESS=0x220; /*设置板卡基地址*/ int creat_DO(int *DO_NUM) { int temp=0; int i=0; for(i=5;i>0;i--) { temp=(temp+DO_NUM[i])*2; /*每次左移一位*/ } return temp+DO_NUM[0]; } /*DO子函数,目的是把存于数组中的位合成字节*/
解码 a5 a4 a3 a2 a1 a0 25 24 23 22 21 20 25 *a5+ 24 *a4+ 23 *a3+ 22 *a2 + 21 *a1+20 *a0 (((((a5 *2+a4) *2+ a3 ) ) *2+a2 ) *2 +a1)*2+ a0 DO通道程序(续) int creat_DO(int *DO_NUM) { int temp=0; int i=0; for(i=5;i>0;i--) { temp=(temp+DO_NUM[i])*2; } return temp+DO_NUM[0]; } 将位输入变为整数 累加器
DO通道程序(续) main() { int DO[6]; int DO_out; char c; while(1) { printf("\nPlease set:eg.1,1,0,1,0,1\n"); scanf(“%d,%d,%d,%d,%d,%d”,&DO[0],&DO[1],&DO[2],&DO[3], &DO[4],&DO[5]); DO_out=creat_DO(DO); outportb(BASE_ADDRESS+13, DO_out); printf("\nPress n to next and other key to quit!\n"); c=bioskey(0); if(c==‘n’||c==‘N’) continue; else break; } outportb(BASE_ADDRESS+13,0); }
DO通道程序(续) main() /*DO主函数*/ { int DO[6]; int DO_out; char c; /*定义数组和变量*/ while(1) { printf("\nPlease set:eg.1,1,0,1,0,1\n"); scanf(“%d,%d,%d,%d,%d,%d”,&DO[0],&DO[1],&DO[2],&DO[3], &DO[4],&DO[5]); /*输入控制开关量*/ DO_out=creat_DO(DO); /*调用子函数*/ /*把6个控制开关量合成字节*/ outportb(BASE_ADDRESS+13, DO_out); /*写DO低字节*/ printf("\nPress n to next and other key to quit!\n"); c=bioskey(0); /*BIOS接口调用函数,返回从键盘上输入的字符*/ if(c==‘n’||c==‘N’) continue; /*结束本次循环,继续下次循环*/ else break; /*跳出本层循环*/ } outportb(BASE_ADDRESS+13,0); /*DO低字节清零*/ }
运行环境设置 • 第一次上机时,如果一个简单正确的程序却无法运行,需要检查一下运行环境是否设置正确。
窗口操作 • 在TC 界面下,屏幕上半部分是编辑窗口,下半部分是信息窗口。如果想把编辑窗口扩大到整屏,可按【F5】键,这时信息窗口将被遮住,再按【F5】键又可以恢复成上下两个窗口。因此【F5】键就象一个电源开关。如果编辑窗口被扩大到整屏,而又想看一下信息窗口,可使用【F6】进行窗口切换。如果在程序执行时又开了观察窗口,【F6】可以对三个窗口进行切换,切换过程是按一个方向循环。 • 在Windows 中运行TC,所打开的窗口往往较小,边框线也不对。按【Alt】+【Enter】键可以使窗口最大化,成为仿真Dos 界面。再按【Alt】+【Enter】又会恢复较小窗口。
程序调试 ①让程序执行到中途暂停以便观察阶段性结果: 方法一:使程序执行到光标所在的那一行暂停。 (1)把光标移动到需暂停的行上; (2)按【F4】或执行菜单Run 中的“Go to Cursor”操作。当程序执行到该行将会暂停。如果把光标移动到后面的某个位置,再按【F4】,程序将从当前的暂停点继续执行到新的光标位置,第二次暂停。 方法二:把光标所在的那一行设置成断点,然后按【Ctrl】+【F9】执行,当程序执行到该行将会暂停。设置断点的步骤为: (1)把光标移动到需暂停的行上; (2)按【Ctrl】+【F8】或执行菜单“Break/watch”中的“Toggle breakpoint”操作。 注意:不管是通过光标位置还是断点设置,其所在的程序行必须是程序执行的必经之路,亦即不应该是分支结构中的语句,因为该语句在程序执行中受到条件判断的限制,有可能因条件的不满足而不被执行。这时程序将一直执行到结束位置或下一个断点位置。
程序调试 (续) ②设置需观察的结果变量 按照上面的操作,可使程序执行到指定位置时暂停,其目的是为了查看有关的中间结果。按【Ctrl】+【F7】或菜单“Break/watch”中的“Add watch”操作,屏幕上将会弹出小窗口供输入查看变量,如下图所示,我们输入了变量i 进行查看。
程序调试 (续) ③ 单步执行 当程序执行到某个位置时发现结果已经不正确了,说明在此之前肯定有错误存在。如果能确定一小段程序可能有错,先按上面步骤暂停在该小段程序的头一行,再输入若干个查看变量,然后单步执行,即一次执行一行语句,逐行检查下来,看看到底是哪一行造成结果出现错误,从而能确定错误的语句并予以纠正。 单步执行按【F8】或执行菜单Run 中的“Step over”操作。如果遇到自定义函数调用,想进入函数进行单步执行,可按【F7】或执行菜单Run 中的“Trace into”操作。对不是函数调用的语句来说,【F7】与【F8】作用相同。但一般对系统函数不要使用【F7】。