关于移位操作的一点说明

我们有下面的测试代码:

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 int main()
 6 {
 7     int num1=7;
 8     cout<<"num1(7)<<2: "<<(num1<<2)<<endl;
 9     cout<<"num1(7)>>2: "<<(num1>>2)<<endl;
10     int num2=-7;
11     cout<<"num2(-7)<<2: "<<(num2<<2)<<endl;
12     cout<<"num2(-7)>>1: "<<(num2>>1)<<endl;
13     cout<<"num2(-7)>>2: "<<(num2>>2)<<endl;
14     return 0;
15 }
复制代码

 

 

对于正数的移位操作:

7的二进制码为0111    当左移2位时(右边补0):11100 十进制28

            当右移2位时(左边补0):001    十进制1

 

-7的二进制码1111     当左移两位时:111100(最高位为符号位) 十进制-28

 

当右移1位时 二进制码为1111 取反加一为补码 1001,再右移1位为0100 加上符号位为-4

当右移2位时  二进制码为1111 取反加一为补码 1001,再右移2位为0010 加上符号位为-2



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
所有的整数类型以二进制数字的变化及其宽度来表示。例如,byte 型42的二进制代码是00101010 ,其中每个置在此代表2的次方,在最右边的以20开始。向左下一个置将是21,或2,依次向左是22,或4,然后是8,16,32等等,依此类推。因此42在其置1,3,5的为1(从右边以0开始数);这样42是21+23+25的和,也即是2+8+32 。 所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用大家知道的2的补码(two's complement )这种编码来表示负数,也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加1。例如,-42就是通过将42的二进制代码的各个取反,即对00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要对一个负数解码,首先对其所有的取反,然后加1。例如-42,或11010110 取反后为00101001 ,或41,然后加1,这样就得到了42。 如果考虑到零的交叉(zero crossing )问题,你就容易理解Java (以及其他绝大多数语言)这样用2的补码的原因。假定byte 类型的零用00000000 代表。它的补码是仅仅将它的每一位取反,即生成11111111 ,它代表负零。但问题是负零在整数数学中是无效的。为了解决负零的问题,在使用2的补码代表负数的时,对其加1。即负零11111111 加1后为100000000 。但这样使1太靠左而不适合返回到byte 类型的,因此人们规定,-0和0的表示方法一样,-1的解码为11111111 。尽管我们在这个例子使用了byte 类型的,但同样的基本的原则也适用于所有Java 的整数类型。 因为Java 使用2的补码来存储负数,并且因为Java 中的所有整数都是有符号的,这样应用运算符可以容易地达到意想不到的结果。例如,不管你如何打算,Java 用高来代表负数。为避免这个讨厌的意外,请记住不管高的顺序如何,它决定一个整数的符号。 二 逻辑运算符 逻辑运算符有“与”(AND)、“或”(OR)、“异或(XOR )”、“非(NOT)”,分别用“&”、“|”、“^”、“~”表示,4-3 表显示了每个逻辑运算的结果。在继续讨论之前,请记住运算符应用于每个运算数内的每个单独的。 表4-3 逻辑运算符的结果 A 0 1 0 1 B 0 0 1 1 A | B 0 1 1 1 A & B 0 0 0 1 A ^ B 0 1 1 0 ~A 1 0 1 0 按非(NOT) 按非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。例如,数字42,它的二进制代码为: 00101010 经过按非运算成为 11010101 按与(AND) 按与运算符“&”,如果两个运算数都是1,则结果为1。其他情况下,结果均为零。看下面的例子: 00101010 42 &00001111 15 00001010 10 按或(OR) 按或运算符“|”,任何一个运算数为1,则结果为1。如下面的例子所示: 00101010 42 | 00001111 15 00101111 47 按异或(XOR) 按异或运算符“^”,只有在两个比较的不同时其结果是 1。否则,结果是零。下面的例子显示了“^”运算符的效果。这个例子也表明了XOR 运算符的一个有用的属性。注意第二个运算数有数字1的,42对应二进制代码的对应是如何被转换的。第二个运算数有数字0的,第一个运算数对应的数字不变。当对某些类型进行运算时,你将会看到这个属性的用处。 00101010 42 ^ 00001111 15 00100101 37 逻辑运算符的应用 下面的例子说明逻辑运算符: // Demonstrate the bitwise logical operators. class BitLogic { public static void main(String args[]) { String binary[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; int a = 3; // 0 + 2 + 1 or 0011 in binary int b = 6; // 4 + 2 + 0 or 0110 in binary int c = a | b; int d = a & b; int e = a ^ b; int f = (~a & b) | (a & ~b); int g = ~a & 0x0f; System.out.println(" a = " + binary[a]); System.out.println(" b = " + binary[b]); System.out.println(" a|b = " + binary[c]); System.out.println(" a&b = " + binary[d]); System.out.println(" a^b = " + binary[e]); System.out.println("~a&b|a&~b = " + binary[f]); System.out.println(" ~a = " + binary[g]); } } 在本例中,变量a与b对应的组合代表了二进制数所有的 4 种组合模式:0-0,0-1,1-0 ,和1-1 。“|”运算符和“&”运算符分别对变量a与b各个对应的运算得到了变量c和变量d的。对变量e和f的赋说明了“^”运算符的功能。字符串数组binary 代表了0到15 对应的二进制的。在本例中,数组各元素的排列顺序显示了变量对应的二进制代码。数组之所以这样构造是因为变量的n对应的二进制代码可以被正确的存储在数组对应元素binary[n] 中。例如变量a的为3,则它的二进制代码对应地存储在数组元素binary[3] 中。~a的与数字0x0f (对应二进制为0000 1111 )进行按与运算的目的是减小~a的,保证变量g的结果小于16。因此该程序的运行结果可以用数组binary 对应的元素来表示。该程序的输出如下: a = 0011 b = 0110 a|b = 0111 a&b = 0010 a^b = 0101 ~a&b|a&~b = 0101 ~a = 1100 三 左运算符 左运算符<<使指定的所有都左规定的次数。它的通用格式如下所示: value << num 这里,num 指定要移位value 动的数。也就是,左运算符<<使指定的所有都左num。每左一个,高阶都被移出(并且丢弃),并用0填充右边。这意味着当左的运算数是int 类型时,每动1它的第31就要被移出并且丢弃;当左的运算数是long 类型时,每动1它的第63就要被移出并且丢弃。 在对byte 和short类型的进行移位运算时,你必须小心。因为你知道Java 在对表达式求时,将自动把这些类型扩大为 int 型,而且,表达式的也是int 型。对byte 和short类型的进行移位运算的结果是int 型,而且如果左不超过31,原来对应各也不会丢弃。但是,如果你对一个负的byte 或者short类型的进行移位运算,它被扩大为int 型后,它的符号也被扩展。这样,整数结果的高就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高。这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点: // Left shifting a byte value. class ByteShift { public static void main(String args[]) { byte a = 64, b; int i; i = a << 2; b = (byte) (a << 2); System.out.println("Original value of a: " + a); System.out.println("i and b: " + i + " " + b); } } 该程序产生的输出下所示: Original value of a: 64 i and b: 256 0 因变量a在赋表达式中,故被扩大为int 型,64(0100 0000 )被左两次生成256 (10000 0000 )被赋给变量i。然而,经过左后,变量b中惟一的1被移出,低全部成了0,因此b的也变成了0。 既然每次左都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1进高阶(31或63),那么该将变为负。下面的程序说明了这一点: // Left shifting as a quick way to multiply by 2. class MultByTwo { public static void main(String args[]) { int i; int num = 0xFFFFFFE; for(i=0; i<4; i++) { num = num << 1; System.out.println(num); } } 这里,num 指定要移位value 动的数。也就是,左运算符<<使指定的所有都左num。每左一个,高阶都被移出(并且丢弃),并用0填充右边。这意味着当左的运算数是int 类型时,每动1它的第31就要被移出并且丢弃;当左的运算数是long 类型时,每动1它的第63就要被移出并且丢弃。 在对byte 和short类型的进行移位运算时,你必须小心。因为你知道Java 在对表达式求时,将自动把这些类型扩大为 int 型,而且,表达式的也是int 型。对byte 和short类型的进行移位运算的结果是int 型,而且如果左不超过31,原来对应各也不会丢弃。但是,如果你对一个负的byte 或者short类型的进行移位运算,它被扩大为int 型后,它的符号也被扩展。这样,整数结果的高就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高。这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点: // Left shifting a byte value. class ByteShift { public static void main(String args[]) { byte a = 64, b; int i; i = a << 2; b = (byte) (a << 2); System.out.println("Original value of a: " + a); System.out.println("i and b: " + i + " " + b); } } 该程序产生的输出下所示: Original value of a: 64 i and b: 256 0 因变量a在赋表达式中,故被扩大为int 型,64(0100 0000 )被左两次生成256 (10000 0000 )被赋给变量i。然而,经过左后,变量b中惟一的1被移出,低全部成了0,因此b的也变成了0。 既然每次左都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1进高阶(31或63),那么该将变为负。下面的程序说明了这一点: // Left shifting as a quick way to multiply by 2. class MultByTwo { public static void main(String args[]) { int i; int num = 0xFFFFFFE; for(i=0; i<4; i++) { num = num << 1; System.out.println(num); } } } 该程序的输出如下所示: 536870908 1073741816 2147483632 -32 初经过仔细选择,以便在左 4 后,它会产生-32。正如你看到的,当1被进31 时,数字被解释为负。 四 右运算符 右运算符>>使指定的所有都右规定的次数。它的通用格式如下所示: value >> num 这里,num 指定要移位value 动的数。也就是,右运算符>>使指定的所有都右num。下面的程序片段将32右2次,将结果8赋给变量a: int a = 32; a = a >> 2; // a now contains 8 当中的某些被“移出”时,这些将丢弃。例如,下面的程序片段将35右2 次,它的2个低移出丢弃,也将结果8赋给变量a: int a = 35; a = a >> 2; // a still contains 8 用二进制表示该过程可以更清楚地看到程序的运行过程: 00100011 35 >> 2 00001000 8 将每右一次,就相当于将该除以2并且舍弃了余数。你可以利用这个特点将一个整数进行快速的2的除法。当然,你一定要确保你不会将该数原有的任何一位移出。 右时,被走的最高(最左边的)由原来最高的数字补充。例如,如果要走的为负数,每一次右都在左边补1,如果要走的为正数,每一次右都在左边补0,这叫做符号扩展(保留符号)(sign extension ),在进行右操作时用来保持负数的符号。例如,–8 >> 1 是–4,用二进制表示如下: 11111000 –8 >>1 11111100 –4 一个要注意的有趣问题是,由于符号扩展(保留符号)每次都会在高补1,因此-1右的结果总是–1。有时你不希望在右时保留符号。例如,下面的例子将一个byte 型的转换为用十六 进制表示。注意右后的与0x0f进行按与运算,这样可以舍弃任何的符号扩展,以便得到的可以作为定义数组的下标,从而得到对应数组元素代表的十六进制字符。 // Masking sign extension. class HexByte { static public void main(String args[]) { char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'' }; byte b = (byte) 0xf1; System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);}} 该程序的输出如下: b = 0xf1 五 无符号右 正如上面刚刚看到的,每一次右,>>运算符总是自动地用它的先前最高的内容补它的最高。这样做保留了原的符号。但有时这并不是我们想要的。例如,如果你进行移位操作的运算数不是数字,你就不希望进行符号扩展(保留符号)。当你处理像素或图形时,这种情况是相当普遍的。在这种情况下,不管运算数的初是什么,你希望移位后总是在高(最左边)补0。这就是人们所说的无符号动(unsigned shift )。这时你可以使用Java 的无符号右运算符>>> ,它总是在左边补0。 下面的程序段说明了无符号右运算符>>> 。在本例中,变量a被赋为-1,用二进制表示就是32全是1。这个然后被无符号右24,当然它忽略了符号扩展,在它的左边总是补0。这样得到的255被赋给变量a。 int a = -1; a = a >>> 24; 下面用二进制形式进一步说明该操作: 11111111 11111111 11111111 11111111 int型-1的二进制代码>>> 24 无符号右2400000000 00000000 00000000 11111111 int型255的二进制代码 由于无符号右运算符>>> 只是对32和64有意义,所以它并不像你想象的那样有用。因为你要记住,在表达式中过小的总是被自动扩大为int 型。这意味着符号扩展和动总是发生在32而不是8或16。这样,对第7以0开始的byte 型的进行无符号动是不可能的,因为在实际动运算时,是对扩大后的32进行操作。下面的例子说明了这一点: // Unsigned shifting a byte value. class ByteUShift { static public void main(String args[]) { int b = 2; int c = 3; a |= 4; b >>= 1; c <<= 1; a ^= c; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); } } 该程序的输出如下所示: a = 3 b = 1 c = 6 还不清楚,移位运算有多大的用处,可是面试时经常会考。现在重温一下子。 原文地址:(http://www.ddvip.net/program/java/index1/28.htm)
作  者:吴向军 等 著 丛 书 名:普通高等教育“十一五”国家级规划教材 出 版 社:高等教育出版社 ISBN:9787040279498 出版时间:2009-11-01 版  次:2 页  数:386 装  帧:平装 开  本:16开 内容简介   《汇编语言程序设计(第2版)》以16/32Intel CPU为介绍对象,以并行推进的方式介绍这两类CPU的指令系统,以达到相互参考、对照的效果。另外,本书还介绍了常用的编程环境和调试工具的使用方法。   在内容组织上,把学习高级语言的习惯和汇编语言的特点相结合,按“硬件资源—变量定义一指令系统—编程”的顺序安排相应的内容。结合MASM V6.1x的编程环境,使汇编语言源程序具有一定的高级语言特点和结构。书中用一章来介绍浮点数的表示、浮点运算指令和编程方法,使读者对高级语言中的各种数据类型与低层实现之间的联系有一个更清晰的认识。还用一章介绍了用汇编语言编写Windows应用程序的基本方法,为拓宽汇编语言的应用领域做一点尝试。   书中附有一些基本的编程辅助信息,这些信息包括各种按键的码和显示颜色信息等。在Windows应用程序的编写部分,附录中给出了编程中所用到的一些常量列表和函数功能的说明。这些辅助信息可为编程带来一定的方便,也可作为常用手册以待查阅。   《汇编语言程序设计(第2版)》可作为计算机学科的本科生、大专生及相近专业学生的教材,也可作为相关工程技术人员的学习资料或参考书。 目录 第一章 预备知识 1.1 汇编语言的由来及其特点 1.1.1 机器语言 1.1.2 汇编语言 1.1.3 汇编程序 1.1.4 汇编语言程序的主要特点 1.1.5 汇编语言的应用领域 1.2 数据的表示和类型 1.2.1 数数据的表示 1.2.2 非数数据的表示 1.2.3 基本数据类型 习题 第二章 CPU资源和存储器 2.1 寄存器组 2.1.1 寄存器组 2.1.2 通用寄存器 2.1.3 段寄存器 2.1.4 专用寄存器 2.2 存储器的管理模式 2.2.1 16微机的内存管理模式 2.2.2 32微机的内存管理模式 习题 第三章 操作数的寻址方式 3.1 立即寻址方式 3.2 寄存器寻址方式 3.3 直接寻址方式 3.4 寄存器间接寻址方式 3.5 寄存器相对寻址方式 3.6 基址加变址寻址方式 3.7 相对基址加变址寻址方式 3.8 32地址的寻址方式 习题 第四章 标识符和表达式 4.1 标识符 4.2 简单内存变量的定义 4.2.1 内存变量定义的一般形式 4.2.2 字节变量 4.2.3 字变量 4.2.4 双字变量 4.2.5 六字节变量 4.2.6 八字节变量 4.2.7 十字节变量 4.2.8 浮点类型变量 4.3 调整偏量伪指令 4.3.1 偶对齐伪指令EVEN 4.3.2 对齐伪指令ALIGN 4.3.3 调整偏量伪指令ORG 4.3.4 偏量计数器的 4.4 复合内存变量的定义 4.4.1 重复说明符DUP 4.4.2 结构类型的定义 4.4.3 联合类型的定义 4.4.4 记录类型的定义 4.4.5 数据类型的自定义 4.5 标号 4.6 内存变量和标号的属性 4.6.1 段属性操作符 4.6.2 偏量属性操作符 4.6.3 类型属性操作符 4.6.4 长度屑性操作符 4.6.5 容量属性操作符 4.6.6 强制属性操作符 4.6.7 存储单元别名操作符 4.7 表达式 4.7.1 进制伪指令RADIX 4.7.2 数表达式 4.7.3 地址表达式 4.8 符号定义语句 4.8.1 等价语句 4.8.2 等号语句 4.8.3 符号名定义语句 习题 第五章 微机CPU的指令系统 5.1 汇编语言指令格式 5.1.1 指令格式 5.1.2 指令的几个属性 5.2 指令系统 5.2.1 数据传送指令 5.2.2 标志位操作指令 5.2.3 算术运算指令 5.2.4 逻辑运算指令 5.2.5 移位操作指令 5.2.6 位操作指令 5.2.7 比较运算指令 5.2.8 循环指令 5.2.9 转指令 5.2.10 条件设置字节指令 5.2.11 字符串操作指令 5.2.12 ASCⅡ-BCD码运算调整指令 5.2.13 处理器指令 习题 第六章 程序的基本结构 6.1 源程序的基本组成 6.1.1 段的定义 6.1.2 段寄存器的说明语句 6.1.3 堆栈段的说明 6.1.4 源程序的结构 6.2 程序的基本结构 6.2.1 顺序结构 6.2.2 分支结构 6.2.3 循环结构 6.3 段的基本属性 6.3.1 对齐类型(ALIGN) 6.3.2 组合类型(COMBINE) 6.3.3 类别(CLASS) 6.3.4 段组(GROUP) 6.4 简化的段定义 6.4.1 存储模式说明伪指令 6.4.2 简化段定义伪指令 6.4.3 简化段段名的引用 6.5 源程序的辅助说明伪指令 习题 第七章、子程序和库 7.1 子程序的定义 7.2 子程序的调用和返回指令 7.2.1 调用指令 7.2.2 返回指令 7.3 子程序的参数传递 7.3.1 寄存器传递参数 7.3.2 约定存储单元传递参数 7.3.3 堆栈传递参数 7.4 寄存器的保护与恢复 7.5 子程序的完全定义 7.5.1 子程序完全定义格式 7.5.2 子程序的距 7.5.3 子程序的语言类型 7.5.4 子程序的可见性 7.5.5 子程序的“起始”和“结束”操作 7.5.6 寄存器的保护和恢复 7.5.7 子程序的参数传递 7.5.8 子程序的原型说明 7.5.9 子程序的调用伪指令 7.5.10 局部变量的定义 7.6 子程序库 7.6.1 建立库文件命令 7.6.2 建立库文件举例 7.6.3 库文件的应用 7.6.4库文件的好处 习题 第八章 输入输出和中断 8.1 输入输出的基本概念 8.1.1 I/O端口地址 8.1.2 I/O指令 8.2 中断 8.2.1 中断的基本概念 8.2.2 中断指令 8.2.3 中断返回指令 8.2.4 中断和子程序调用 8.3 中断功能的分类 8.3.1 键盘输入的中断功能 8.3.2 屏幕显示的中断功能 8.3.3 打印输出的中断功能 8.3.4 串行通信口的中断功能 8.3.5 鼠标的中断功能 8.3.6 目录和文件的中断功能 8.3.7 内存管理的中断功能 8.3.8 读取/设置中断向量 习题 第九章 宏 9.1 宏的定义和引用 9.1.1 宏的定义 9.1.2 宏的引用 9.1.3 宏的参数传递方式 9.1.4 宏的嵌套定义 9.1.5 宏与子程序的区别 9.2 宏参数的特殊运算符 9.2.1 连接运算符 9.2.2 字符串整体传递运算符 9.2.3 字符转义运算符 9.2.4 计算表达式运算符 9.3 与宏有关的伪指令 9.4 重复汇编伪指令 9.4.1 伪指令REPT 9.4.2 伪指令IRP 9.4.3 伪指令IRPC 9.5 条件汇编伪指令 9.5.1 条件汇编伪指令的功能 9.5.2 条件汇编伪指令的举例 9.6 宏的扩充 9.6.1 宏定义形式 9.6.2 重复伪指令REPEAT 9.6.3 循环伪指令WHILE 9.6.4 循环伪指令FOR 9.6.5 循环伪指令FORC 9.6.6 转伪指令GOTO 9.6.7 宏扩充的举例 9.6.8 系统定义的宏 习题 第十章 应用程序设计 10.1 字符串的处理程序 10.2 数据的分类统计程序 10.3 数据转换程序 10.4 文件操作程序 10.5 动态数据的编程 10.6 COM文件的编程 10.7 驻留程序 10.8 程序段前缀及其应用 10.8.1 程序段前缀的字段含义 10.8.2 程序段前缀的应用 习题 第十一章 数运算协处理器 11.1 协处理器的数据格式 11.1.1 有符号整数 11.1.2 BCD码数据 11.1.3 浮点数 11.2 协处理器的结构 11.2.1 协处理器的内部结构 11.2.2 状态寄存器 11.2.3 控制寄存器 11.2.4 标记寄存器 11.3 协处理器的指令系统 11.3.1 指令操作符的命名规则 11.3.2 数据传送指令 11.3.3 数学运算指令 11.3.4 比较运算指令 11.3.5 超越函数运算指令 11.3.6 常数操作指令 11.3.7 协处理器控制指令 11.4 协处理器的编程举例 习题 第十二章 汇编语言和C语言的混合编程 12.1 汇编指令的嵌入 12.2 C语言源程序的汇编输出 习题 第十三章 Windows应用程序的编程 13.1 消息框 13.2 编程伪指令 13.2.1 多路分支语句 13.2.2 调试语句 13.3 Windows程序的结构 13.3.1 Windows程序的基本结构 13.3.2 程序的初始化阶段 13.3.3 窗口的准备阶段 13.3.4 消息循环阶段 13.3.5 消息处理阶段 13.4 Windows应用程序 13.4.1 按钮控件的应用 13.4.2 对话框的定义 13.4.3 对话框和控件的应用 13.4.4 绘画和图像的应用 13.4.5 命令行参数的处理 习题 第十四章 汇编语言编程环境和调试工具 14.1 汇编语言编程环境 14.1.1 MASM 6.1x 14.1.2 Turbo Assembler 14.1.3 MASM32 14.2 调试工具 14.2.1 Debug 14.2.2 CodeView 14.2.3 Turbo Debugger 14.2.4 VKdebug 附录 附录一 键盘按键的各种编码对照表 附录二 显示地址及其显示属性 附录三 Windows中各类预定义常量 附录四 Windows应用程序中部分API函数 参考文献
二 一四~二 一五学年第 二 学期 信息科学与工程学院 电子技术综合设计(一) 课程设计报告 班 级: 姓 名: 学 号: 指导教师: 二 一五年六月十八日 一、设计任务 温度测量显示系统设计 在Proteus软件下,利用AT89C51系列单片机、A/D芯片ADC0831、OP07高精度单片运 算放大器、TCK温度传感器、LED等设计一个温度测量显示报警系统,外接至少4个LED数 码管,将当前测量温度显示在LED上。 根据系统的设计要求,温度传感器TCK输出信号经信号差动放大到0—5V,放大器的输 出送ADC80C51进行A/D转换,A/D转换结果送单片机进行处理,最后将所测的温度在LED数 码管上显示。 仿真时可在TCK温度传感器上手动修改输入当前环境温度。 设计要求 1) 测量范围为0 ~+120 ,精度为1 。 2) 利用温度传感器测量某一点环境温度。 3) 利用A/D转换将温度信号转换成电压信号,在LED数码管上显示。 4) 设置一个开关,当开关断开时LED显示个人学号的后4数字,当开关闭合时工作在 测温报警显示状态,LED显示温度。 5) 设置2个指示LED灯,当温度低于80°时,绿灯亮,当温度高于80°时,红灯亮报警。 6) 扩展功能:语音报警。 7) 所有单片机程序代码都用C语言编写。 8) 用Proteus软件进行仿真。 报告要求: 1). 在报告中应对系统的设计思想、设计方法用文字详细说明,有总体电路框图和 Proteus连接图的截图。 2). 有程序者在报告中应有完整的程序清单 (必需加注释)。 3). 有程序者在报告中应有完整的程序流程框图。 4). 谈谈自己通过这次设计实践的收获和体会。 课程考核方式 考查 要求:提交课程设计报告,设计报告内容包括设计任务,设计要求,软硬件设计,程序 结果描述。 1)每人独立完成题目的基本功能。包括设计报告、电路图和程序清单(带注释),运行结 果及有关运行说明。 2)程序检查。分优、良、中、及格、不及格,如为不及格,需下一学年进行重修; 3) 课程设计报告,正规书写打印,否则不计成绩; 4) 验收时每同学现场演示仿真结果,指导老师随时针对电路设计、程序调试、代码功能 等各个方面进行提问。 5) 设计报告若雷同或超过50%雷同,则以作弊论,作弊者本课程均计零分。本课程无补考, 只能下一学年进行重修。 各部分电路设计 1)温度测量电路设计 度测量电路要实现的目标是:将0~120度通过传感器测量,运算放大器放大的0~ 5V的电压信号。 温度传感器选用Pa- t传感器,放大器采用OP07E放大器,温度信号输入采用差动放大形式,放大器输出为: 即放大倍数为100倍。 在Proteus中实测放大器输出数据为: 温度 "0 "10 "20 "30 "40 "50 "60 "70 "80 "90 "100 "110 "120 " "电压 "0.00 "0.43 "0.83 "1.24 "1.66 "2.07 "2.49 "2.91 "3.33 "3.75 "4.17 "4.58 "5.00 " "从测试数据来看,本设计符合0~120对应输出0~5V电压要求。 温度测量电路 A/D转换器的设计 A/D转换的目标是将模拟量转化成数字量,选用ADC0831串行A/D转换芯片做为温度测试系 统的A/D转换芯片,设计电路如图所示: LED显示电路设计 LED显示电路 报警电路设计 当温度低于80度时,绿灯亮;当温度高于80度时,红灯亮。 报警电路 系统整体硬件电路设计 Proteus仿真调试及结果 1) 温度显示结果 2) 学号显示 五、电路设计代码 #include<reg52.h> //52单片机头文件 #include<intrins.h> //特殊移位操作函数的头文件 #define uchar unsigned char //宏定义用来随后定义变量的时候简单定义 #define uint unsigned int //宏定义用来随后定义变量的时候简单定义 sbit CS=P3^7; //adc0831片选信号控制端 sbit CLK=P3^6; //adc0831时钟信号输入端 sbit DO=P3^5;//数据输出口 sbit led_red=P3^4;//报警灯信号控制 sbit led_green=P3^0;//绿灯信号控制端 sbit swi=P3^2;//读状态 uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39};//0- 9数字编码 uchar code du[]={0xfe,0xfd,0xfb,0xf7};//段选控制 uchar peng[]={4,0,5,2};

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值