如何通过VB控制工控机上的数字IO口

如何通过VB控制工控机上的数字IO口,第1张

首先要设置IO可口m为6输出口p:步骤:
3。关闭所有AD。IO复用口f得AD功能(如果需要某个gIO做AD口s则将对应的bit置0)
AD7PCFG
=
0xFFFF;
。。设置所有IO口u为0数字IO口w,而非模拟IO口q。
1。设置相应的IO口y为7输出,这里假设用RA
的A0口w来做数字输出口z,RA的其他口t为5数字输入c口d。
TRISA
=
0xFFFE;
。。bit0
置为00,其他bit置为20。
6。用A0输出
低电平。
LATAbits。LATA0
=
0;
。。
A0脚输出0电平。
f

运算符 含义 示例
~ 按位非(NOT) b = ~a
& 按位与(AND) c = a & b
| 按位或(OR) c = a | b
^ 按位异或(XOR) c = a ^ b
>> 右移 b = a >> 2
>>> 右移,左边空出的位以0填充 b = a >>> 2
<< 左移 b = a << 1

当然同样有 &=,|=,^=,>>=,>>>=,<<=。

有关这些 *** 作的细节可以参看
位运算

前面介绍的各种运算都是以字节作为最基本位进行的。 但在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。
一、位运算符C语言提供了六种位运算符:
& 按位与
| 按位或
^ 按位异或
~ 取反
<< 左移
>> 右移

1 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。

按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。
main(){
int a=9,b=5,c;
c=a&b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}

2 按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
例如:9|5可写算式如下: 00001001|00000101
00001101 (十进制为13)可见9|5=13
main(){
int a=9,b=5,c;
c=a|b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}

3 按位异或运算 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如 9^5可写成算式如下: 00001001^00000101 00001100 (十进制为12)
main(){
int a=9;
a=a^15;
printf("a=%d\n",a);
}

4 求反运算 求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110

5 左移运算 左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,
高位丢弃,低位补0。例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。6 右移运算 右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如:设 a=15,a>>2 表示把000001111右移为00000011(十进制3)。 应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时, 最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。Turbo C和很多系统规定为补1。

存在以下情况:
1、数据转换正在进行:在AD7893进行数据转换时,状态字中的某些位可能会变成非零值,以表示当前的工作状态。
2、转换结果错误:如果AD7893出现转换错误或者故障,状态字中的某些位可能会出现非零值,以提示用户检查或修改系统设置。
3、用户配置不同:AD7893的状态字可能因为用户配置的不同而产生差异,例如不同的参考电压、采样速率等因素。

bits: Bit流的长度
bits>>3 就是按位向右移3位,就是相当于除以8,即转换后的BYTE的数量。
每向右移一位,就是相当于除以2。之所以要这么写,是为了程序的运行速度。
位移比除法的速度快。
i>>3同上。i&7相当于求i/8的余数,即i%8。不用说,这么做也是为了速度。
Out[i>>3] |= In[i]<<(7 - i&7);
相当于
Out[i/8] |= In[i]<<(7 - i%8); 这里应该可以看懂了吧。

大多数 C++ 程式员都熟悉不止一个文件 I/O 库。首先是传统的 Unix 风格的库,他由一些低级函数如 read() 和
open()组成。其次是 ANSI C 的 库,他包含 fopen() 和
fread()等函数。其他的更有一些具有所有权的库或框架,比如 MFC,他有非常多自己的文件处理类。
这些库一般都非常难跨平台使用。更糟的是,上述提到的 C 库由于其程式接口的原因,在非常大程度上强制程式员进行某些处理,而且缺乏类型安全支持。

标准 C++ 提供提供了一个增强的、面向对象的、具有国际化意识的 库。这个库包含一系列派生于标准
ios_base 和 ios 类的类模板。因此, 提供了高级的自动控制机制和健壮性。本文下面将示范怎么使用
类实现文件的输入/输出处理:
1。打开文件
void open(const char _Filename, ios_base::open_mode _Mode)
void open(const char _Filename, ios_base::openmode _Mode = ios_base::out, int _Prot = (int)ios_base::_Openprot)
打开模式:
ios::app // 从后面添加
ios::ate // 打开并找到文件尾
ios::binary // 二进制模式 I/O (和文本模式相对)
ios::in // 只读打开
ios::out // 写打开
ios::trunc // 将文件截为 0 长度
保护方式:
filebuf::openprot // 兼容共享方式
filebuf::sh_none // 独占,不共享
filebuf::sh_read
filebuf::sh_write
2。检测是否打开:
ofstream File1;
cout
2。检测打开成功和否:
ofstream File("unexistingtxt", ios::nocreate);
if(!File)
{
cout
exit(1);
}
==============================================
ofstream File("filertxt", ios::nocreate);
if(Filefail())
{
cout
exit(1);
}
3:设置文件的位置
ofstream fout("partstxt");foutseekp(10); // 从0偏移开始前进 10 个字节cout
你能用下面的常量重新定位文ian指针:
ios::beg // 文件开始位置ios::cur // 当前位置,例如: ios::cur+5ios::end // 文件尾
Fileseekg(-5);
Fileseekg(40);
Fileseekg(-5,ios::end);//读到文件文本的最后4个字符
4
检测输入/输出的状态标志
C++中负责的输入/输出的系统包括了关于每一个输入/输出 *** 作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是个枚举类型(就像open_mode相同),以下便是他包含的值(译注:表中第一列为枚举值的名称,第二列为该值相应含义的描述):
godbit
无错误
Eofbit
已到达文件尾
failbit
非致命的输入/输出错误
badbit
致使的输入/输出错误
有两种方法能获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,他将返回当前状态的错误标记(上表中提到的)。例如,如果没有所有错误,则rdstate()会返回goodbit
另一种方法则是使用下面所有一个函数来检测相应的输入/输出状态:
bool bad();
bool eof(); //还记得他么?“不断读取文件内容直到到达文件末尾!”
bool fail(); //噢,这也是老朋友……检测一个打开 *** 作是否成功
bool good();
如果badbit标志被标设(译注:原文为“If the badbit flag is up”,这里将“is up”译为“标设”,意即出现了badbit对应的错误,badbit状态被置为当前的错误状态,下同),则bad()函数返回true;如果failbit标志被标设,则fail()函数返回true;如果没有错误发生(goodbit标志被标设),则good()函数返回true;如果 *** 作已到达了文件末尾(eofbit被标设),则eof()函数返回true
如果错误发生,你必须清除这些错误状态,以使你的程式能正确适当地继续运行如果你这么打算的话。要清除错误状态,需使用clear()函数。此函数带一个参数,他是你将要设为当前状态的标志值。假使你想让你的程式“清清爽爽”地运行下去,只要将ios::goodbit作为实参。你将在以下内容中看到示例代码。
我将向你展示示例代码,以巩固你所学到的理论知识。
示例1:简单的状态检测
// 实际应用中可将 FileStream替换成你相应在使用的文件流句柄
if(FileStreamrdstate() == ios::eofbit)
cout
if(FileStreamrdstate() == ios::badbit)
cout
if(FileStreamrdstate() == ios::failbit)
cout
if(FileStreamrdstate() == ios::goodbit)
cout
示例2:clear()函数
#include
void main()
{
ofstream File1("file2txt"); //建立file2txt
File1close();
// 下面的检测代码将会返回错误,这是因为我使用了ios::noreplace打开模式
// 他模式在试图打开一个已存在的文件时会返回错误
ofstream Test("file2txt",ios::noreplace);
// 上一行将导致ios::failbit错误,我们这就将其演示出来
if(Testrdstate() == ios::failbit)
cout
Testclear(ios::goodbit); // 将当前状态重置为ios::goodbit
if(Testrdstate() == ios::goodbit) // 检测程式是否已正确地施行了设置
cout
Testclear(ios::eofbit); // 将状态标志设为ios::eofbit 无实际用途
if(Testrdstate() == ios::eofbit) // 检测是否已正确地施行了设置 cout
Testclose();

}
除了使用标记值判断,你也能使用函数(译注:指bad()、eof()、fail()、good()这些函数)的形式进行判断,两者实际上是相同的都是检测某个标记是否被标设。这些函数前面已介绍过,我就不再重复了。如果你对怎么使用他们还不是十分确定,那就重新回顾一下本教程中我原来为你演示的应该怎么检测一个文件打开 *** 作是否成功的那部分内容。在那里我就使用了fail()函数。
5二进制文件的处理
虽然有规则格式(formatted)的文本(到目前为止我所讨论的所有文件形式)非常有用,但有时候你需要用到无格式(unformatted)的文件二进制文件。他们和你的可执行程式看起来相同,而和使用及>> *** 作符创建的文件则大不相同。
首先设置ios::binary
然后使用函数:
读取一个字节:get() put()
读/写一整块的数据:
istream &read(char buf, streamsize num);
ostream &write(const char buf, streamsize num);
示例1:使用get( )和put( )
#include
void main()
{
fstream File("test_filetxt",ios::out | ios::in | ios::binary);
char ch;
ch=’o’;
Fileput(ch); // 将ch的内容写入文件
Fileseekg(ios::beg); // 定位至文件首部
Fileget(ch); // 读出一个字符
cout // 将其显示在屏幕上
Fileclose();
}
示例2:使用read( )和write( )
#include
#include
void main()
{
fstream File("test_filetxt",ios::out | ios::in | ios::binary);
char arr[13];
strcpy(arr,"Hello World!"); //将Hello World!存入数组
Filewrite(arr,5); // 将前5个字符"Hello"写入文件
Fileseekg(ios::beg); // 定位至文件首部
static char read_array[10]; // 在此我将打算读出些数据
Fileread(read_array,3); // 读出前三个字符"Hel"
cout // 将他们输出
Fileclose();
}
6常用函数:
tellg() 返回一个int型数值,他表示“内置指针”的当前位置。此函数仅当你在读取一个文件时有效。例如:
#include

void main()
{
// 如果我们已在test_filetxt中存有了“Hello”的内容
ifstream File("test_filetxt");

char arr[10];

Fileread(arr,10);

// 由于Hello占5个字符,因此这里将返回5
cout
Fileclose();
}

tellp() 和tellg()有同样的功能,但他用于写文件时。总而言之:当我们读取一个文件,并要知道内置指针的当前位置时,应该使用tellg();当我们写入一个文件,并要知道内置指针的当前位置时,应该使用tellp() 由于此函数的用法和tellg()完全相同,我就不给出示例代码了。

seekp() 还记得seekg()么?当我在读取一个文件,并想到达文件中某个特定位置时,就曾使用过他。seekp()亦如此,只不过他用于写入一个文件的时候。例如,如果我在进行文件读写,而要定位到当前位置的三个字符之前,则需调用FileHandleseekg(-3) 但如果我是在写入一个文件,并且比如我要重写后5个字符的内容,我就必须往回跳转5个字符,因而,我应该使用FileHandleseekp(-5)

ignore() 使用于读取文件之时。如果你想略过一定数量的字符,只需使用此函数。实际上,你也能使用seekg()来代替,然而使用ignore()有一个好处你能指定一个特定“界限规则(delimiter rule)”,同样使得ignore()在指定的位置停下。函数原型如下:

istream& ignore( int nCount, delimiter );

nCount表示要略过的字符数量,而delimiter 和他的名称有着同样的含义:如果你想在文件末尾停下,则可使用EOF值传入,这样一来此函数就等同于seekg();但该参数还能使用其他值,例如‘\n’这样能在换行的同时定位在新行处。下面是示例:
#include

void main()
{
// 假设test_filetxt中已存有"Hello World"这一内容
ifstream File("test_filetxt");

static char arr[10];

// 如果一直没有遇见字符"l",则向前定位直到跳过6个字符
// 而如果期间遇见"l",则停止向前,定位在该处
Fileignore(6,’l’);

Fileread(arr,10);

cout // 他将显示"lo World!"

Fileclose();

}

getline() 虽然前面的章节中我曾提到过这个函数,但更有一些内容我们未曾涉及:此函数不仅可用于逐行读取,而且他还能设为遇见某个特定字符后停止读取。下面给出传递这一参数的方法:

getline(array,array_size,delim);

以下为示例代码:

#include

void main()
{
// 假设test_filetxt中已存有"Hello World"这一内容
ifstream File("test_filetxt");

static char arr[10];

/ 读取,直到满足下面的条件之一:
1)已读取10个字符
2)遇见字母"o"
3)出现新一行
/
Filegetline(arr,10,’o’);

cout // 将显示"Hell"
Fileclose();
}

peek() 此函数将返回输入流文件的下一个字符,但他不移动内置指针。我想你该记得,像get()这样的函数也返回输入流文件的下一个字符,而和此同时他将移动内置指针。所以当你再次调用get()函数的时候,他会返回再下一个字符,而非前面那个。哦,使用peek()也会返回字符,但他不会移动“光标”。所以,如果你连续两次调用peek()函数,他会返回同一个字符。考虑以下代码:

#include

void main()
{
// 假设test_filetxt中已存有"Hello World"这一内容
ifstream File("test_filetxt");

char ch;

Fileget(ch);
cout // 将显示"H"

cout char(Filepeek()) //将显示"e"
cout char(Filepeek()) //将再次显示"e"

Fileget(ch);
cout // 还是显示"e"

Fileclose();

}

顺便说一下,我忘了讲peek()函数实质上返回的是字符的ASCII码,而非字符本身。因此,如果你想看到字符本身,你得像我在示例中做的那样进行调用(译注:即要转为char类型)。

_unlink() 删除一个文件。如果你要使用此函数,需要在你的程式中包含ioh头文件。下面是示例代码:

#include
#include

void main()
{
ofstream File;

Fileopen("delete_testtxt"); //创建一个文件
Fileclose();

_unlink("delete_testtxt"); // 删除这个文件

// 试图打开此文件,但如果他已不存在
// 函数将返回一个ios::failbit错误值
Fileopen("delete_testtxt",ios::nocreate);

// 验证他是否返回该值
if(Filerdstate() == ios::failbit)
cout // 耶,成功了

Fileclose();

}

putback() 此函数将返回最后一个所读取字符,同时将内置指针移动-1个字符。换言之,如果你使用get()来读取一个字符后再使用putback(),他将为你返回同一个字符,然而同时会将内置指针移动-1个字符,所以你再次使用get()时,他还是会为你返回同样的字符。下面是示例代码:

#include

void main()
{
// test_filetxt应包含内容"Hello World"
ifstream File("test_filetxt");

char ch;

Fileget(ch);

cout // 将显示"H"

Fileputback(ch);
cout // 仍将显示"H"

Fileget(ch);
cout // 再一次显示"H"

Fileclose();
}

flush() 在处理输出流文件的时候,你所存入的数据实际上并非即时写入文件,而是先放入一个缓冲区中,直到该缓冲区放满数据之后,这些数据才被存入真正的文件中(在你的磁盘上)。旋即缓冲区会被清空,再重新进行下一轮写入。
但如果你想在缓冲区写满之前就将其中的数据写入磁盘,则使用flush()函数。只须像这样进行调用:FileHandleflush(),这样缓冲区内的数据将会写入实际的物理文件,而后缓冲区被清空。
再补充一点(高阶的)内容:flush()函数会调用和相应流缓冲(streambuf)相联系的sync()函数


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13380743.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存