要求:循环点亮流水灯,再沿原路返回
原理图如下
方式1:数组字节操作实现
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
//前8个,后8个
uchar tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void delay()
{
uint i,j;
for(i=0;i<255;i++)
for(j=0;j<255;j++);
}
void main()
{
uchar k;
while(1)
{
for(k=0;k<16;k++)
{
P1=tab[k];//逐个移位
delay();//延时使灯亮能被人眼察觉
}
}
}
方式2:移位运算符实现:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
void main()
{
uchar i,temp;
while(1)
{
temp=0x01;//0000 0001
for(i=0; i<8; i++)
{
P1=~temp; //temp数值取反送回P1 1111 1110
delay();
temp=temp<<1;//左移 移过的位置补0 向高位
}
temp=0x80; //1000 0000
for(i=0; i<8; i++)
{
P1=~temp;//取反赋值变为 0111 1111
delay();
temp=temp>>1;//右移 移过的位置补0 向低位
}
}
}
方式3:左右移位实现
#include <reg51.h>
#include <intrins.h> //包含循环位移函数_crol_()的头文件
#define uchar unsigned char
#define uint unsigned int
void main()
{
uchar i,temp;
while(1)
{
temp=0xfe; //1111 1110
for(i=0; i<7; i++)
{
P1=temp;
delay();
temp=_crol_(temp,1);//循环左移
}
for(i=0; i<7; i++)
{
P1=temp;
delay();
temp=_cror_(temp,1);//循环右移
}
}
}
注意
移位与“>>”或“<<”与循环移位的区别:移位符“<<”与“>>”移过之处变为0,需要考虑边界,循环移位函数单位循环移动,不用考虑边界;
对I/O口的电平操作最好先赋予一个变量temp,对变量temp的操作结束后,再进行重新对I/O的赋值,不容易出错。