#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--); } }