第2章端口、内存I/O与位运算哈尔滨工业大学《C语言在测量与控制中的应用》系列课件2.1端口输入/输出函数计算机的CPU要与外设间传递信息,必须通过硬件的接口电路来进行。接口电路通常包含一些寄存器,如数据寄存器、状态寄存器、控制寄存器等。一般称这些寄存器为I/O(输入/输出)端口。PC系列微机用10条地址线对端口寻址寻址范围为0x00~0x3ffC语言为了控制端口的输入/输出扩展了一些非标准的系统函数8位端口输入函数inportb()函数原型:unsignedcharinportb(intportid);功能:从地址为portid的8位端口输入一个字节(8位),所读的值是该函数的返回值,由头文件dos.h说明。用法:#includedos.hunsignedcharb;…b=inportb(端口地址);8位端口输出函数outportb()函数原型:voidoutportb(intportid,unsignedcharvalue);功能:向地址为portid的8位端口输出一个字节(8位),其值为value,由头文件dos.h说明。用法:#includedos.h…outportb(端口地址,无符号字符型数据或变量);16位端口输入函数inport()函数原型:intinport(intportid);功能:从地址为portid的16位端口输入一个字(16位),所读的值是该函数的返回值,由头文件dos.h说明。用法:#includedos.hintw;…w=inport(端口地址);16位端口输出函数outport()函数原型:voidoutport(intportid,intvalue);功能:向地址为portid的16位端口输出一个字(16位),其值为value,由头文件dos.h说明。用法:#includedos.h…outport(端口地址,整型数据或变量);2.2位运算位运算是直接对操作数的二进制位(bit)进行操作。按二进制位的逻辑运算对控制计算机硬件非常有用。C语言的位运算符有:按位与&,按位或|,按位异或^,按位取反~,左移,右移。位运算符只能用于有符号或无符号的字符型、整型、长整型数据的运算,不能用于浮点数和双精度数据的运算。(1)按位与运算符&运算规则:0&0=0,0&1=0,1&0=0,1&1=1若a=0x55,b=0xf0a&b=?01010101(a=0x55)&)11110000(b=0xf0)01010000(c=0x50)规律:跟1相与不变,跟0相与清零用途:按位的与运算可使某些位清0,其它位不变.(2)按位或运算符|运算规则:0|0=0,0|1=1,1|0=1,1|1=1若a=0x55,b=0xf0c=a|b=?01010101(a=0x55)|)11110000(b=0xf0)11110101(c=0xf5)规律:跟1相或置1,跟0相或不变用途:按位的或运算可使某些位置1,其它位不变.(3)按位异或运算符^运算规则:0^0=0,0^1=1,1^0=1,1^1=0相同为0,不同为1若a=0x55,b=0xf0,c=a^b=?01010101(a=0x55)^)11110000(b=0xf0)10100101(c=0xa5)规律:跟1相异或取反,跟0相异或不变用途:按位异或运算可使某些位取反,其它位不变(4)按位非运算符~按位非运算也叫按位反运算,他将操作数的每个二进制位都取反,即0变成1,1变成0。若a=0x55对应的二进制数为01010101则~a=0xaa对应的二进制数为10101010(5)按位左移运算符按位左移运算符用于将变量的每一位向左移动左移运算的一般表达式为:被移位变量名左移的位数左移后右端的空位补001011001左移一位结果为:10110010左移一位相当乘2,左移运算常用于快速的乘法(6)位右移运算符按位左移运算符用于将变量的每一位向右移动右移运算的一般表达式为:被移位变量名右移的位数无符号数右移后左端的空位补0。有符号数左端最高位(MSB)是符号位,右移后补充符号位,以保持符号不变。右移一位相当除2,右移运算常用于快速的除法2.4内存单元读/写函数C语言可直接访问内存单元的物理地址。86系列CPU微机的内存地址是分段表示的,包括一个16位的段地址和一个16位的段内偏移地址。地址通常用16进制数表示。(1)peekb()函数函数的格式为:charpeekb(intsegment,unsignedoffset);该函数返回由segment(段地址)和offset(偏移地址)指定地址的一个内存单元中的值(8位),由dos.h说明。程序举例:#includedos.hmain(){charb;b=peekb(0xf000,0xfffe);printf(“%x\n”,(unsignedchar)b);}(2)peek()函数函数的格式为:intpeek(intsegment,unsignedoffset);该函数返回由segment(段地址)和offset(偏移地址)指定首地址的两个相邻内存单元中的值(16位),由dos.h说明。(3)pokeb()函数函数的格式为:voidpokeb(intsegment,unsignedoffset,charvalue);该函将一个字节的值value,存到由segment(段地址)和offset(偏移地址)所指定的内存单元中,由dos.h说明。程序举例:#includedos.hmain(){pokeb(0x0040,0x0017,1);}(4)poke()函数该函将一个字的值value,存到由segment(段地址)和offset(偏移地址)所指定首地址的两个连续内存单元中,由dos.h说明。函数的格式为:voidpoke(intsegment,unsignedoffset,intvalue);