C51的左移右移
c51单片机的循环左移函数 _crol_ 源码
c51单片机的循环左移函数 _crol_ 源码1. 背景介绍c51单片机是一种广泛应用于嵌入式系统的微控制器,它采用的是哈佛结构的指令集架构,因此在开发过程中需要编写大量的汇编语言代码。
在c51单片机中,循环左移函数_crol_是一个非常常用的函数,它可以实现对一个字节或字的循环左移操作,是嵌入式系统开发中的基础函数之一。
2. 循环左移函数_crol_的功能循环左移函数_crol_的功能是将一个字节或字进行左移操作,并且在移动的过程中将最高位移到最低位,其他位依次向高位移动。
对于一个8位的二进制数xxx,经过一次循环左移后,变成xxx。
3. _crol_函数的源码在c51单片机中,_crol_函数的源码通常以汇编语言的形式编写,下面是一个常见的_crol_函数源码示例:```assembly_crol:mov a, r0 ; 将需要左移的字节或字存入累加器arlc a ; 累加器a的内容左移一位,并将最高位的值存入CY(进位标志位)mov r0, a ; 将左移后的结果存入r0ret ; 函数返回```4. _crol_函数源码解析以上是一个简单的_crol_函数的源码示例,下面对其进行解析:- 将需要左移的字节或字存入累加器a中;- 使用指令rlc a将累加器a的内容左移一位,并且最高位的值存入CY (进位标志位)中;- 将左移后的结果存入r0中;- 函数返回。
5. _crol_函数源码的优化上述的_crol_函数源码虽然可以实现循环左移的功能,但是在性能和效率上并不是最优的。
下面是对_crol_函数源码的一些优化建议:- 如果在c51单片机的开发中需要频繁使用循环左移操作,可以考虑将_crol_函数的源码嵌入到其他函数中,以减少函数调用的开销;- 通过使用位操作指令,可以进一步提高_crol_函数的执行效率,例如使用指令“rl a”来代替“rlc a”。
6. 总结在c51单片机的开发中,循环左移函数_crol_是一个非常基础且常用的函数,它可以帮助开发者实现对字节或字的循环左移操作。
51单片机位操作
C51单片机位操作方法[日期:2010-10-21 ] [来源:本站原创作者:佚名] [字体:大中小] (投递新闻)C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:运算符含义运算符含义&按位与~取反|按位或<<左移^按位异或>>右移1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1;如下例:a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe; //a=0b 11111110a=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a= 0b 01010100 2.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5; //a=0b 11110101result=a&0x08; //检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55; //a=0b 01010101a=a&0x0f; //将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
51单片机位操作
C51单片机位操作方法C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1;如下例:a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe; //a=0ba=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a= 0b2.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5; //a=0bresult=a&0x08; //检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55; //a=0ba=a&0x0f; //将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
即有‘1’为‘1’,全‘0’为‘0’。
0|0=0; 0|1=1; 1|0=1; 1|1=1;例如:a=0x30|0x0f; //a=(0b)|(0b)=(0b)=0x3f“按位或”运算最普遍的应用就是对一个变量的某些位置‘1’。
c51调汇编移位函数
C51调汇编移位函数详解引言在C51单片机编程中,移位操作是一种常见的操作。
移位操作可以将一个数的二进制表示在内部进行左移或右移,从而改变数的值。
C51提供了一些用于实现移位功能的汇编指令,如RL、RR、SL、SR等。
为了方便使用这些指令,可以编写一些特定函数来实现不同类型的移位操作。
本文将详细解释C51调汇编移位函数中的特定函数,包括函数的定义、用途和工作方式等。
函数定义在C语言中,可以使用__asm关键字来嵌入汇编代码。
通过嵌入汇编代码,可以直接调用C51提供的汇编指令。
下面是一个示例函数left_shift()的定义:void left_shift(unsigned char *data, unsigned char count) {__asmmov r0, dpl ; 将data指针中的值赋给r0寄存器mov r1, dph ; 将data指针中的高字节值赋给r1寄存器mov a, count ; 将count赋给累加器astart:rl a ; 左移累加器amovx @r0, a ; 将累加器a的值写入data指针所指向的内存inc r0 ; data指针自增1djnz r1, start ; 如果r1不为0,则跳转到start标签处继续执行__endasm;}函数用途left_shift()函数的作用是将一个字节的数据进行左移操作。
左移操作是指将一个数的二进制表示向左移动指定的位数,低位补零。
这种操作可以用来实现乘以2的幂次方运算。
例如,对于数据0b00001010,左移一位后得到0b00010100,等价于乘以2。
函数工作方式left_shift()函数使用了C51提供的汇编指令rl和movx来实现左移操作。
下面是函数工作方式的详细解释:1.将传入的指针data中存储的值分别赋给寄存器r0和r1。
寄存器r0用于访问data指针所指向的内存地址,寄存器r1用于保存data指针所指向内存地址的高字节。
2-1 移位操作资料
(1)左移。C51中操作符为“<<”,每执行一次左移指令,被操作的数将最高位 左移。 左移 移入单片机PSW寄存器的CY位.CY位中原来的数丢弃,最低位补0。
(2)右移 右移。C51中操作符为“>>”,每执行一次右移指令,被操作的数将最低位移 右移 入单片机PSW寄存器的CY位,CY位中原来的数丢弃。 如果变量为无符号数,则最高位补0;否则最高位补1(所补与符号位相同)。
循环移位:可调用“intrins.h”中的相关函数。 循环移位 /*-------------------------------------------------------------------------INTRINS.H --------------------------------------------------------------------------*/ #ifndef __INTRINS_H__ #define __INTRINS_H__ extern void extern bit extern unsigned char extern unsigned int extern unsigned long extern unsigned char extern unsigned int extern unsigned long extern unsigned char extern void extern void #endif _nop_ _testbit_ _cror_ _iror_ _lror_ _crol_ _irol_ _lrol_ _chkfloat_ _push_ _pop_ (void); (bit); (unsigned char, unsigned char); (unsigned int, unsigned char); (unsigned long, unsigned char); (unsigned char, unsigned char); (unsigned int, unsigned char); (unsigned long, unsigned char); (float); (unsigned char _sfr); (unsigned char _sfr);
C51中移位运算
在汇编中用RR RRC RL RLC就很容易实现移位,在c51中利用<<,>>就很容易的实现移出。
移入就显得比较麻烦,特别是右移入。
(1:)送数送两个单独字节的数据的程序,左送 &0x80(左移给数) ,从最高位-最低位顺序给数右送 &0x01 (右移给数),最低位-最高位给数bit out;out = low & 0x01;low >>= 1;low |= (high & 0x01)<<7;high >>= 1;( 2):取数(不管怎么移入,第一次操作之后获取的那一位数据必须在接受数据的最高位或者最低位上,从而选择是先取数还是先移位)a:如果是先接受高位后接受低位则先左移一位后接受一位数据(i2c总线)uchar i;uchar temp = 0;uchar date = 0x82;for (i = 0; i < 8; i++){temp <<= 1; //左移temp |= (bit)(date & 0x80);date <<= 1;}b:如果是先接受低位,后接受高位则先接受一位数据后循环右移一位(DS18B20)uchar i;uchar temp = 0;uchar date = 0x82;for (i = 0; i < 8; i ++){temp |= (bit)(date & 0x01);date >>= 1;temp = _cror_(temp,1);//循环右移,应用_cror_()需要包含头文件<intrins.h>}如果不用函数则for循环应该这样写for (i = 0; i < 8; i ++){temp >>= 1;temp |= (date & 0x01) << 7; date >>= 1;}(3.)任意一位的置位或者取反运算置位运算low |= 0x01; (置最低位为1)取反运算low |= ~low & 0x01;(4.)合并和拆分数据1:合并两个单字节数据为一个双字节数据 int len;uchar low;uchar high;Len |= high;Len <<= 8;Len |= low;2: 拆分一个双字节数据为两个单字节数据 int len;uchar low;uchar high;low |= len;high |= len >> 8;。
C51经典程序
经典程序1.广告灯的左移右移1.实验任务做单一灯的左移右移,硬件电路如图4.4.1所示,八个发光二极管L1-L8分别接在单片机的P1.0-P1.7接口上,输出“0”时,发光二极管亮,开始时P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0亮,重复循环。
2.电路原理图图4.4.13.系统板上硬件连线把“单片机系统”区域中的P1.0-P1.7用8芯排线连接到“八路发光二极管指示模块”区域中的L1-L8端口上,要求:P1.0对应着L1,P1.1对应着L2,……,P1.7对应着L8。
4.程序设计内容我们可以运用输出端口指令MOV P1,A或MOV P1,#DATA,只要给累加器值或常数值,然后执行上述的指令,即可达到输出控制的动作。
每次送出的数据是不同,具体的数据如下表1所示P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 说明L8 L7 L6 L5 L4 L3 L2 L11 1 1 1 1 1 1 0 L1亮1 1 1 1 1 1 0 1 L2亮1 1 1 1 1 0 1 1 L3亮1 1 1 1 0 1 1 1 L4亮1 1 1 0 1 1 1 1 L5亮1 1 0 1 1 1 1 1 L6亮1 0 1 1 1 1 1 1 L7亮0 1 1 1 1 1 1 1 L8亮表15.程序框图图4.4.26.C语言源程序#include <A T89X51.H>unsigned char i;unsigned char temp;unsigned char a,b;void delay(void)//延时0.1968s{unsigned char m,n,s;for(m=20;m>0;m--)for(n=20;n>0;n--)for(s=248;s>0;s--); 若改为249则为0.1976s}void main(void){while(1){temp=0xfe;P1=temp;delay();for(i=1;i<8;i++){a=temp<<i;b=temp>>(8-i);P1=a|b;delay();}for(i=1;i<8;i++){a=temp>>i;b=temp<<(8-i);P1=a|b;delay();}}}【电设资料】非常精确的C语言延时子程序表用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时很不好控制,我们常常很难知道一段延时程序它的精确延时到底是多少,这和汇编延时程序没法比。
51单片机流水灯左移右移控制程序
51单片机流水灯左移右移控制程序51单片机流水灯左移右移控制程序电路很简单 8位流水灯接在单片机的P1口.如下是源代码://===================================== ========== ==============//程序名:LLL22_4.C//程序功能:流水灯控制左移右移//===================================== ========== ===============#include;//头文件L_M(); //流水灯左移控制程序R_M(); //流水灯右移控制程序//===================================== ========== ================main() //主函数{while(1) //无限循环{L_M(); //调用左移程序R_M(); //调用右移程序}}//========左移控制程序====================================== ======== L_M() //左移主函数{unsigned char i,temp,a,b; //声明无符号字符型变量A,TEMP I,B unsigned int s; //声明无符号整型变量Stemp=0xfe; //左移初始值P1=temp; //P1输出信号点亮发光管for( s=0;s;>;(8-i) ; //数据右移(8-I)位P1=a|b ; //逻辑或运算,并输出到P1口for(s=0;s;>;i;b=temp<<(8-i); //数据右移(8-I)位P1=a|b; //逻辑或运算,并输出到P1口for(s=0;s<30000;s++); //延时程序}}//===================================== ==================================。
采用调用51自带的左移右移函数实现彩灯闪烁控制论
采用调用51自带的左移右移函数实现彩灯闪烁控制论彩灯闪烁控制,也称为跑马灯,是一种常见的照明应用。
在这个项目中,我们将使用51单片机的左移和右移函数来实现彩灯的跑马灯效果。
首先,我们需要知道51单片机的左移和右移操作。
在51单片机中,左移操作符<<表示将一些数的二进制表示向左移动n位,右边用0填充。
右移操作符>>表示将一些数的二进制表示向右移动n位,左边用符号位填充。
这两个操作都是逻辑操作,不会改变数的符号。
接下来,我们可以使用51单片机的GPIO口来控制彩灯的亮和暗。
假设我们使用8个LED灯,那么我们就需要8个GPIO口来控制每个LED的亮灭。
以下是利用左移和右移函数实现彩灯闪烁控制的基本步骤:1.设置51单片机的GPIO口为输出模式,用于控制LED灯。
2.初始化闪烁控制变量和计数器变量。
3.使用一个循环来不断更新LED灯的状态。
4.在循环中,通过调用左移和右移函数,根据计数器变量的值来更新LED灯的状态。
5.控制LED灯的亮和暗,可以使用51单片机的GPIO口的高电平和低电平来实现。
6.根据需要,可以调整闪烁速度和亮灭的模式。
下面是一个简单的示例程序:```c#include <reg51.h>sbit led1 = P1^0; // 假设P1口连接第一个LED灯sbit led2 = P1^1; // 假设P1口连接第二个LED灯//...//假设P1口连接第八个LED灯void delay(unsigned int count)unsigned int i, j;for(i = 0; i < count; i++)for(j = 0; j < 120; j++);void maiunsigned int count = 0;//初始化GPIO口led1 = 0;led2 = 0;//...//初始化其它LED灯while(1)//更新LED灯的状态led1 = count & 0x01;led2 = count & 0x02;//...//更新其它LED灯的状态//控制LED灯的亮和暗delay(1000); // 控制闪烁速度led1 = 0;led2 = 0;//...//控制其它LED灯的亮和暗//更新计数器变量count = (count << 1) , (count >> 7); // 控制左移和右移的位数和方向}```以上示例程序只是一个简单的跑马灯实现,具体的实现方式和效果可以根据实际需求进行调整。
c51单片机的循环左移函数_crol_源码
c51单片机的循环左移函数_crol_源码以下是C51单片机的循环左移函数_crol_的源码,源码使用C语言编写:```c#include <reg51.h>//函数声明unsigned char crol(unsigned char val, unsigned char n);void mainunsigned char val = 0xAA; // 初始值unsigned char n = 3; // 循环左移的位数unsigned char result;//调用循环左移函数result = crol(val, n);while (1)//程序持续运行}//循环左移函数unsigned char crol(unsigned char val, unsigned char n)unsigned char mask = 0x80; // 最高位掩码//循环左移while (n > 0)if (val & mask)//最高位为1,循环左移后最低位变为1val = (val << 1) , 0x01;}else//最高位为0,循环左移后最低位保持为0val = val << 1;}n--;}return val;```这段代码首先定义了一个名称为`crol`的函数,用于实现循环左移操作。
在主函数`main`中,初始化了一个初始值`val`为`0xAA`,循环左移的位数`n`为`3`。
然后调用`crol`函数进行循环左移操作,并将结果保存在`result`变量中。
`crol`函数中,使用了一个最高位掩码`mask`,初始化为`0x80`。
然后在循环中判断最高位是0还是1,根据最高位的值进行循环左移操作。
当最高位为1时,循环左移后的最低位应为1,所以将`val`左移1位,并通过逻辑或运算符将最低位置为1、当最高位为0时,循环左移后的最低位应保持为0,所以直接将`val`左移1位。
51单片机指令系统:逻辑运算及移位(7)
51单片机指令系统:逻辑运算及移位(7)51单片机指令系统:逻辑运算及移位(7)第二十五课:逻辑运算及移位指令分析逻辑运算和移位指令共有25条,有与、或、异或、求反、左右移位、清0等逻辑操作,有直接、寄存器和寄存器间址等寻址方式。
这类指令一般不影响程序状态字(PSW)标志。
[1]. 循环移位指令(4条)这4条指令的作用是将累加器中的内容循环左或右移一位,后两条指令是连同进位位CY一起移位。
RL A ;累加器A中的内容左移一位RR A ;累加器A中的内容右移一位RLC A ;累加器A中的内容连同进位位CY左移一位RRC A ;累加器A中的内容连同进位位CY右移一位[2]. 累加器半字节交换指令(1条)这条指令是将累加器中的内容高低半字节互换,这在上一节中内容已有介绍。
SWAP A ; 累加器中的内容高低半字节互换[3]. 求反指令(1条)这条指令将累加器中的内容按位取反。
CPL A ; 累加器中的内容按位取反[4]. 清零指令(1条)这条指令将累加器中的内容清0。
CLR A ; 0→(A),累加器中的内容清0[5]. 逻辑与操作指令(6条)这组指令的作用是将两个单元中的内容执行逻辑与操作。
如果直接地址是I/O地址,则为“读—修改—写”操作。
ANL A,data ;累加器A中的内容和直接地址单元中的内容执行与逻辑操作。
结果存在寄存器A中。
ANL data,#data ;直接地址单元中的内容和立即数执行与逻辑操作。
结果存在直接地址单元中。
ANL A,#data ;累加器A的内容和立即数执行与逻辑操作。
结果存在累加器A中。
ANL A,Rn ;累加器A的内容和寄存器Rn中的内容执行与逻辑操作。
结果存在累加器A中。
ANL data,A ;直接地址单元中的内容和累加器A的内容执行与逻辑操作。
结果存在直接地址单元中。
ANL A,@Ri ;累加器A的内容和工作寄存器Ri指向的地址单元中的内容执行与逻辑操作。
结果存在累加器A中。
C51的左移右移
C51的左移右移(转载)非天之光发表于 2006-4-4 8:10:10左移变量1 << 变量2将变量1的二进制位值向左移动由变量2所指定的位数。
例如:a = 0x8f; // 10001111a << 2; // 左端移出的值丢弃,右端补0结果:a = 0x3c (00111100)在keil c51中,内部函数库INTRINS.H中_crol_(m,n)表示将m循环左移n位,与m<<n的效果不同。
前者的低位移进高位移出的位,后者低位填入0右移变量1 >> 变量2将变量1的二进制位值向右移动由变量2所指定的位数。
例1:unsigned char a;a = 0x8f; // 10001111a >> 2; // 右端移出的值丢弃,左端补0结果:a = 0x23 (00100011)例2:char a;a = 0x8f; // 10001111a >> 2; // 右端移出的值丢弃,左端补入原来的符号位// 据说有些编译器采用逻辑右移,即左端补0结果:a = 0xe3 (11100011)例3:在 avr-gcc中,想读出PIND按位取反后将高4位移到低4位的值,然后用开关语句处理。
uint8_t k;k = ~PIND >> 4;switch(k){case 1: ...break;case 2: ...break;case 4: ...break;case 8: ...break;default: ...}没有取得预想效果。
改为如下语句,得到正确效果:uint8_t k;k = ((~PIND) >> 4)& 0x0f; // 左移高位不补零。
编译时,PIND作为了有符号数处理switch(k){case 1: ...break;case 2: ...break;case 4: ...break;case 8: ...break;default: ...}。
C51中左右移运算
C51中左右移运算C51中左右移运算汇编:1.对于51单⽚机:RLC A;即将累加器ACC中内容左移1位,最低位被CY原始值替代,最⽚位移⽚进位标志CY中,同理还有RRC A。
具体使⽚:MOV A,#0FFH;CLR C;RLC A;2.对于8086:(1)左移:SHL/SAL DST CNT 移位时操作数的最低位将移⽚0,最⽚位移⽚CF中,若左移若⽚位,则CF中只保留最后⽚次移出的内容。
(2) 右移:分为逻辑右移与算术右移。
逻辑右移即SHR,⽚法与SHL同;算术右移即SAR,移位时操作数的最⽚位移⽚的是它原来的值,即最⽚位保持不变,最低位同样移⽚CF,主要⽚于带符号数的右移。
(3)循环移位:ROR/ROL/RCR/RCL DST CNT 类似51的移位指令,不过可以⽚次操作多位移动。
C51:1.在C51中操作符为"<<",每执⽚⽚次左移指令,操作数最⽚位移⽚CY,CY中本来的数丢失,最低位补0,其他位依次向左移动1位。
右移指令类同。
2.循环左移:使⽚C51库函数⽚带的 unsigned char crol(unsigned char c,unsigned b);实现将字符C循环左移b位,跟8086汇编的循环移位类同,同样右移函数为_cror_;标准C:1.">>",C语⽚中的右移运算,⽚般情况下是⽚位补零,但在处理有符号数的时候会因计算机系统的不同⽚不同。
有符号数⽚位是零,则右移时⽚位补零;如果是负数即⽚位是1,那么有的系统会移⽚1(移动⽚位就补⽚个1),称算术右移(⽚部分系统),有的会移⽚0,称逻辑右移。
2."<<",C语⽚中的左移运算,⽚论是有符号数还是⽚符号数都是按照逻辑左移来操作,即向左移动若⽚位,低位补0即可。
C++:">>“和”<<"运算符如果没有被重载的情况下使⽚与标准C相同,如果被重载如输⽚输出流的操作,则变成输⽚输出操作符,如cout<<xxx; cin>>yyy; 当然也可以被重载为其他的操作。
C51知识
语句
if…else… for()
功能
条件语句 循环语句
while()
do…while() continue
循环语句
循环语句 结束本次循环语句
break
goto return
中止执行switch语句或循环语句
转向语句 从函数返回语句
switch…case 多分支选择语句
顺序结构
顺序结构是从前往后依次执行语句。从整体上看
for循环语句的一般格式为:
for(表达式1; 表达式2; 表达式3) 循环体语句
for循环语句的执行过程为:
求解表达式1。 求解表达式2。若其值为真,则执行循环体;
若其值为假,则循环语句结束,执行后续语句。 求解表达式3。并转到第2步继续执行,直至条 件为假时结束循环。
注意:若第一次求解表达式2,其值就不成 立,则循环体将一次都不执行。
C-51的包含的头文件
通常有:reg51.h reg52.h math.h ctype.h stdio.h stdlib.h absacc.h
常用有:reg51.h reg52.h (定义特殊功能寄存器和位寄存器); math.h (定义常用数学运算);
C-51的运算符
与C语言基本相同: + > == && >= != || ! * < / (加 减 乘 除) <= (大于 大于等于 小于 小于等于)
(测试等于 (逻辑与 测试不等于) 逻辑或 逻辑非 )
>>
& | ^ ~
<<
(位右移
(按位与 (按位异或
位左移)
按位或) 按位取反)
c51单片机的逻辑左移与溢出位的关系
c51单片机的逻辑左移与溢出位的关系C51单片机是一种常用的8位单片机,具有强大的处理能力和丰富的外设接口。
在C51单片机中,逻辑左移是一种常用的操作,可以通过移位运算符<<实现。
在逻辑左移操作中,涉及到一个重要的概念——溢出位。
溢出位是指在进行逻辑左移操作时,最高位的数值被移出后,所产生的新的最低位。
在C51单片机中,如果进行逻辑左移操作,溢出位将被丢弃,并且不会对其他位产生影响。
逻辑左移操作的实现方式是将待移位的数值向左移动指定的位数,并用0填充空出的位。
例如,对于一个8位的数值0x55(二进制表示为01010101),进行逻辑左移1位后,结果为0xAA(二进制表示为10101010)。
在进行逻辑左移操作时,溢出位的处理方式取决于具体的应用需求。
有些应用场景中,溢出位可能被忽略,而有些场景中,溢出位可能被用于后续的计算或判断。
在一些需要对数据进行循环移位操作的应用中,溢出位通常被用于判断移位操作的结束条件。
例如,对于一个8位的数值进行循环左移操作,可以通过判断溢出位是否为1来确定循环移位的结束。
在一些数据压缩或加密算法中,溢出位也可以被用于生成一些随机性或增加数据的复杂度。
通过在逻辑左移操作中使用溢出位,可以增加数据的扩散性,使得加密算法更加安全可靠。
需要注意的是,在进行逻辑左移操作时,若被移位的数值的最高位为1,那么溢出位将为1,否则溢出位为0。
这是因为逻辑左移操作只是简单地将每一位向左移动,并不会改变数值的符号位。
总结来说,C51单片机中的逻辑左移操作与溢出位是密切相关的。
逻辑左移操作通过将数值向左移动指定的位数,并用0填充空出的位,实现了对数据的位移动。
溢出位是在逻辑左移操作中,最高位的数值被移出后所产生的新的最低位。
溢出位的处理方式取决于具体的应用需求,可以被忽略或用于后续的计算或判断。
逻辑左移操作与溢出位的灵活运用,可以为各种应用场景提供更多的可能性和功能。
C51中的位操作
b=b&0xfe; //如果此时因子仍为 0xfe 的话,则结果就为 0b 0000 0000 0110 0110 即 0x0066,而与 0x6766 不相吻合
上例中的问题就是因为不同环境中的数据类型差异所造成的,即程序
的可移植性不好。对于这种情况可以采用如下方法来解决: a=0x67; //a=0b 0110 0111 a=a&~1; //在不同的环境中~1 将自动匹配运算因子,实现最后一位清零 a=0x66 其中~1 为 0b 11111110 b=0x6767; //a=0b 0110 0111 0110 0111 b=a&~1; //~1=0b 1111 1111 1111 1110,b=0b 0110 0111 0110 0110 ,即 0x6766
1.清零 “按位与”通常被用来使变量中的某一位清零。如下例:
a=0xfe; //a=0b 11111110
a=a&0x55; //使变量 a 的第 1 位、第 3 位、第 5 位、第 7 位清零 a= 0b 01010100 2.检测位 要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
c51循环移位的浅谈
c51循环移位的浅谈
如果学习单片机,最基本的考题就是流水灯了,呵呵,可是有时候一
个很厉害的工程师,还真是不好弄出来,当然,我不是工程师,可是学习51
单片机也有很长时间了,回想起当初学习51 的时候,一直都是没有自己的核
心的东西,今天就谈谈c51 循环移位的见解记得如果你打开intrins.h(51 自带的一个头文件),你会发现其中有关于定义_crol_()(字符循环左移函数)(一
般我们用的多的是这个,呵呵),还有一个是_cror_()(字符循环右移函数) 可是,如果你去面试的时候,这个时候,你难道还用它自带的循环函数么?当然不能了。
真是的(有时候我们自己小组出的笔试题就是流水灯,可是我却紧锁眉头,感觉很是窝囊。
咳,今天就把源程序写出来。
)这时候就要用到你
的c 语言知识了,呵呵。
假如说是共阴极数码管的话:
程序可以这样(只写主要算法):
while(1)
{
temp=0x01;
P1=temp;
delay(100); //延时100ms
for(i=1;i {
temp=temp P1=temp;
delay(100);
}
}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C51的左移右移(转载)
非天之光发表于 2006-4-4 8:10:10
左移
变量1 << 变量2
将变量1的二进制位值向左移动由变量2所指定的位数。
例如:
a = 0x8f; // 10001111
a << 2; // 左端移出的值丢弃,右端补0
结果:a = 0x3c (00111100)
在keil c51中,内部函数库INTRINS.H中_crol_(m,n)表示将m循环左移n位,
与m<<n的效果不同。
前者的低位移进高位移出的位,后者低位填入0
右移
变量1 >> 变量2
将变量1的二进制位值向右移动由变量2所指定的位数。
例1:
unsigned char a;
a = 0x8f; // 10001111
a >> 2; // 右端移出的值丢弃,左端补0
结果:a = 0x23 (00100011)
例2:
char a;
a = 0x8f; // 10001111
a >> 2; // 右端移出的值丢弃,左端补入原来的符号位
// 据说有些编译器采用逻辑右移,即左端补0
结果:a = 0xe3 (11100011)
例3:
在 avr-gcc中,想读出PIND按位取反后将高4位移到低4位的值,然后用开关语句处理。
uint8_t k;
k = ~PIND >> 4;
switch(k)
{
case 1: ...
break;
case 2: ...
break;
case 4: ...
break;
case 8: ...
break;
default: ...
}
没有取得预想效果。
改为如下语句,得到正确效果:
uint8_t k;
k = ((~PIND) >> 4)& 0x0f; // 左移高位不补零。
编译时,PIND作为了有符号数处理switch(k)
{
case 1: ...
break;
case 2: ...
break;
case 4: ...
break;
case 8: ...
break;
default: ...
}。