700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 51单片机实现流水灯左移 右移 先左移后右移程序

51单片机实现流水灯左移 右移 先左移后右移程序

时间:2024-03-07 21:09:55

相关推荐

51单片机实现流水灯左移 右移 先左移后右移程序

知识点回顾

<<:左移符号

.>>:右移符号

~:取反符号

思路:

a = 0x01<<1;就是a的结果等于0x01左移一位。需要注意的是,左移是指二进制移位,移位后低位(或高位)是要补0的。举个左移流水灯的例子,要使流水灯向左依次流动,则有代码:

下面展示一些内联代码片

// 左移时流水灯P0口设置,cnt为从0开始逐渐递增的左移的位数,//等下会贴一整段代码P0 = ~(0x01 << cnt);

我们来解析一下这个代码的意思,先从括号里面看,0x01是十六位进制的数,化成二进制为:0000 0001,。当cnt = 1时,即左移一位后,变为000 0 0010,然后取反符号后其变为111 1 1101。根据低电平有效,等于0那个小灯亮了,及第二个小灯亮了。同理可得第三个小灯为:11 11 1011,后面以此类推。

左移代码:

//左移while(1){P0 = ~(0x01 << cnt); //0000 0001 左移后:000 0 0010 取反:111 1 1101 低电平亮for(i= 0; i<30000; i++);cnt++;if(cnt >=8){cnt = 0;}}

右移代码:

//右移while(1){P0 = ~(0x80 >> cnt); // 1000 0000 右移后: 01000 000 取反: 10111 111for(i=0; i<30000; i++);cnt++;if(cnt >=8){cnt = 0;}}

不精确时间的先左移后右移代码:

注:首先要先在前面定义flag: unsigned int flag = 0;

用除余的方法来先左后右。第一遍时flag = 0,除以2余等于0则进入左移的条件。第二遍时flag自加后等于1,除以2余不等于0,则进入右移条件。

while(1){if(flag %2 == 0){P0 = ~(0x01 << cnt); //流水灯左移}else{P0 = ~(0x80 >> cnt);//流水灯右移}for(i=0; i<30000;i++);//闪烁cnt++;//灯进行左(右)移if(cnt >= 8){cnt = 0;flag++;//第二遍后flag+1, 取余不是零,则变成右移方向;}}

用定时器精确时间的先左移后右移代码:

首先要先在前面打开定时器:

TMOD = 0;TH0 = 0xB8;TL0 = 0x00;TR0 = 1;

运行的程序代码为:

//用定时器来实现左右流水灯循环while(1){if(TF0 == 1){//判断T0是否溢出,溢出一次换算得0.02秒TF0 = 0; //定时器控制0.02秒TH0 = 0xB8;TL0 = 0x00;count++;//溢出次数if(count >= 50){//0.02乘以50等于1秒,每隔一秒点亮一个流水灯count = 0;if(flag %2 == 0){P0 = ~(0x01 << cnt);//进行左移}else{P0 = ~(0x80 >> cnt);//进行右移}cnt++;//左(右)移几个单位数if(cnt >= 8){cnt = 0;flag++;//第二遍后flag+1, 取余不是零,则变成右移方向;}} }}}

全部代码:

注:因上面只能看到某部分代码,某些定义没有给出,故放出整体代码,方便易于理解:

#include<reg52.h>sbit ENLED = P1^4; //使能74HC138sbit ADDR3 = P1^3;sbit ADDR2 = P1^2;sbit ADDR1 = P1^1;sbit ADDR0 = P1^0;void main(){unsigned int i = 0; unsigned int cnt = 0;unsigned int flag = 0;unsigned int count = 0;ENLED = 0; //使能ADDR3 = 1;ADDR2 = 1; //110 ,打开控制流水灯的三极管LEDS6,使其导通ADDR1 = 1;ADDR0 = 0;TMOD = 0;TH0 = 0xB8;TL0 = 0x00;TR0 = 1;//左移流水灯while(1){P0 = ~(0x01 << cnt); //0000 0001 左移后:000 0 0010 取反:111 1 1101 低电平亮for(i= 0; i<30000; i++);cnt++;if(cnt >=8){cnt = 0;}}//右移流水灯while(1){P0 = ~(0x80 >> cnt); // 1000 0000 右移后: 01000 000 取反: 10111 111for(i=0; i<30000; i++);cnt++;if(cnt >=8){cnt = 0;}}//先左移,后右移。左移时第一遍为0,除余后为0,则执行左移,第二遍时为1,除余后不是零则执行右移。同理可以继续下去while(1){if(flag %2 == 0){P0 = ~(0x01 << cnt); //流水灯左移}else{P0 = ~(0x80 >> cnt);//流水灯右移}for(i=0; i<30000;i++);//闪烁cnt++;//左(右)移if(cnt >= 8){cnt = 0;flag++;//第二遍后flag+1, 取余不是零,则变成右移方向;}}//用定时器来实现左右流水灯循环while(1){if(TF0 == 1){TF0 = 0; //定时器控制0.02秒TH0 = 0xB8;TL0 = 0x00;count++;if(count >= 50){//0.02乘以50等于1秒count = 0;if(flag %2 == 0){P0 = ~(0x01 << cnt);}else{P0 = ~(0x80 >> cnt);}cnt++;if(cnt >= 8){cnt = 0;flag++;//第二遍后flag+1, 取余不是零,则变成右移方向;}} }}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。