51单片机学习笔记 STC89CRC (02)流水灯

发布时间 2023-04-19 21:06:11作者: 沉默的王さん
#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--);
	}
}