【嵌入式-51单片机】常见位运算和数据类型以及sbit使用

51单片机中
数据类型如下:
在这里插入图片描述

位运算符如下:
在这里插入图片描述
按位左移<<:低位补零,高位移出
按位右移>>:高位补零,低位移出
按位与&:对应位上的值必须同时为1才为1,可以用来对指定位置的寄存器重置处理。比如P2寄存器为1010 1011(0xAB),此时如果0xAB & 0xFE,此时相当于对第0位作置0处理,结果为0xAA。
按位或|:对应位上的值有一个为1那么值就为1。可以用来对指定位置的寄存器置为高电平处理。比如P2寄存器为1010 1010(0xAA),此时如果0xAA | 0x01,此时相当于对第0位作置1处理,结果为0xAB。
按位异或^:对应位上的值必须相反则为1,否则为0。这个可能具有保持值不变的功能,不太常用把, 比如P2寄存器为1010 1010(0xAA),此时0xAA ^ 0xFF 得到的值为0101 0101,相当于按位取反啦。
按位取反~:对应位上的值按位取反。。。比如1111 1110(0xFE)按位取反就是0000 0001(0x01),在做流水灯测试时发现居然还能这么用。。。。0xFE = ~(0x01 << 0),然后可以将这种对流水灯的流转转换为对每一位的左右移。很精彩!这里可以用来对某位进行清零操作。比如IR_Data[0] &= ~(0x01 << IR_pData);这里可以看到,IR_Data[0]的第IR_pData位进行清零操作。很秀啊~~
逻辑取反!:注意区分按位取反和逻辑取反

在51单片机中,有一个神奇的关键字,叫sbit,这个关键字能直接取到寄存器的某一位。比如寄存器名为P1,8位,如果想直接将其中的第三位当作变量使用,可以直接使用P1_3,这个P1_3就代表了P1寄存器第三位的bit值,正如名字所描述的一样,它应该只能取0和1。比如P1_3=0;将P1第三位置为低电平。如果使用按位与,需要写成P1 = P1 & 0xFB;这样显得有点麻烦。哈哈哈,我算这个1111 1011转为0xFB还要花几秒呢。所以尽量sbit来简化吧~(另外使用PX_X这种寄存器位需要导入#include <REGX52.H>哦~)

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是一个简单的51单片机计算器程序,可以进行加、减、乘、除四则运算,且支持5位数运算: ``` #include <reg51.h> sbit KEY_ADD = P1^0; sbit KEY_SUB = P1^1; sbit KEY_MUL = P1^2; sbit KEY_DIV = P1^3; sbit KEY_EQ = P1^4; sbit KEY_CLR = P1^5; void delay(unsigned int i) { while (i--); } void init() { TMOD = 0x01; //设置定时器0为模式1 TH0 = 0x3C; //设置定时器初值为0x3C TL0 = 0xB0; //设置定时器初值为0xB0 TR0 = 1; //启动定时器 ET0 = 1; //打开定时器0中断 EA = 1; //打开总中断 } void putc(unsigned char c) { SBUF = c; while (!TI); TI = 0; } void print(unsigned int n) { unsigned char i; unsigned char buf[5]; buf[0] = n / 10000 + '0'; buf[1] = n / 1000 % 10 + '0'; buf[2] = n / 100 % 10 + '0'; buf[3] = n / 10 % 10 + '0'; buf[4] = n % 10 + '0'; for (i = 0; i < 5; i++) { putc(buf[i]); } } void main() { unsigned char op = 0; unsigned int a = 0, b = 0; unsigned int result = 0; init(); while (1) { if (KEY_ADD == 0) { delay(1000); if (KEY_ADD == 0) { op = '+'; } } else if (KEY_SUB == 0) { delay(1000); if (KEY_SUB == 0) { op = '-'; } } else if (KEY_MUL == 0) { delay(1000); if (KEY_MUL == 0) { op = '*'; } } else if (KEY_DIV == 0) { delay(1000); if (KEY_DIV == 0) { op = '/'; } } else if (KEY_EQ == 0) { delay(1000); if (KEY_EQ == 0) { switch (op) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': result = a / b; break; } print(result); } } else if (KEY_CLR == 0) { delay(1000); if (KEY_CLR == 0) { op = 0; a = 0; b = 0; result = 0; } } else { if (op == 0) { a = a * 10 + P0; print(a); } else { b = b * 10 + P0; print(b); } } } } void timer0_isr() interrupt 1 { TH0 = 0x3C; //重新设置定时器初值为0x3C TL0 = 0xB0; //重新设置定时器初值为0xB0 P0 = 0xFF; //设置P0口为输入 } ``` 在程序中,我们使用51单片机的定时器0来实现按键消抖功能,使用了串口通信来输出结果。程序的基本思路是通过按键输入数字和操作符,然后进行计算并输出结果。 需要注意的是,本程序中只考虑了正整数的四则运算,没有进行异常处理,比如除数为0等情况。在实际开发中,还需要根据实际情况进行修改和完善。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值