#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar temp;//LED灯相关变量
//延时函数,ms 毫秒
void delay(uint ms) {
uint x,y;
for(x = ms; x > 0; x--) {
for(y = 114; y > 0; y--);
}
}
void main() {
// 流水灯
temp = 0xfe;
P1 = temp;
while(1) {
temp = _crol_(temp, 1);
P1 = temp;
delay(50);
}
}
下面两个方法属于 头文件 #include <intrins.h> 里面的
字符型循环左移:_crol_
字符型循环右移:_cror_
它与二进制位移符(左移:<<; 右移:>>)的区别
// _crol_ 与 _cror_ 的一个例子
unsigned int temp;
temp = 0xFE; // 二进制为 1111 1110,0x为十六进制前缀,前面笔记有写
//_crol_("要位移的变量", "位移几位")
temp = _crol_(temp, 1);// 1111 1110 -> 1111 1101,就像贪吃蛇一样,从左边屏幕进去,从右边出来
而左移 << 和 右移 >> 我在之前的笔记里面有写,这里再举个例子
unsigned int temp;
temp = 0xFE; // 二进制为 1111 1110
temp = temp << 1;//1111 1110 -> 0001 1111 1100
//而一个 int 在 51 单片机下是 2 个字节,一个字节是8bit,所以它实际的二进制值是 0000 0000 1111 1110 -> 0000 0001 1111 1100,只不过前面的0省略了
//这时可能又有疑问了,那这个靠近左边的头一个 1 一直移动到最左边是不是和上面那个一样呢,当然不是的
temp = 0xFFFF;//此时二进制为 1111 1111 1111 1111,左移一位变成 1111 1111 1111 1110,超过16bit的舍去,右边补0,右移我前面的位运算符有写,这里就不举例了
以上就是字符循环 左/右 移和二进制位移符的区别
下面这个是单纯用运算符实现流水灯效果的代码
#include <reg52.h>
unsigned int i;
void main() {
// 流水灯
/*
二 十六
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 10
0010 0000 20
0100 0000 40
1000 0000 80
*/
unsigned short j = 0;
P1 = ~0x1; // 0x1 的 二进制 0000 0001,取反后为 1111 1110;
i = 65535;
while(i--);
for(;j < 7;j++){
P1 = ~(~P1 << 1);// 先取反成为二进制的1后进行左移,再取反使其只亮一个灯
i = 65535;
while(i--);
}
}