首页天道酬勤,

,

张世龙 05-13 01:49 44次浏览

文章目录开发板上LED灯相关电路图点亮LED闪烁LED流水灯其他效果照明二进制计数器高级版流水灯

关于开路板上的LED灯的电路图

这是与P2相关的7引脚电路图,默认情况下直接连接到VCC。 也就是说,默认值为高电平。

如您所见,8个LED指示灯分别与单片机上P20~P27的8个针脚相连。 也就是说,一端是VCC,另一端是单片机上的端口。 这样,只要将引脚端电平设为低电平,对应的LED就可以点亮。

点亮这里,首先试着从左向右点亮第一个LED灯。 从电路图来看,只要将P20端子的输出设为0 (即低电平)即可。 代码如下。

# includereg 52.hs位led=p2 ^ 0; int main () while ()1) ) { led=0; }代码说明:首先,需要部署包含许多寄存器地址的单片机头文件REG52.H。

sbit led=P2^0; 指定P2寄存器所在的位。 例如,这里指定P2寄存器的第一位。 然后,在main函数中将值设定为0时,第一个LED点亮。

指示灯闪烁。 首先设定延迟函数deley (。

voiddeley(u16x ) while(x-- ) }即,一直在这里执行x-操作。 在该模型的单片机运行速度下,大约一个基本语句的运行速度为10s,如果输入参数为x,则该函数可以延迟到10sx=x1 )0s10s*x=x*10

代码(闪烁约1s ) :

# includereg 52.htypedefunsignedintu 16; 类型无符号化char u8; sbit led=P2^0; voiddeley(u16x ) while ) x-- ) {}}int main ) (while )1) { led=0; 戴尔(50000; led=1; 戴尔(50000; }运行结果:

tips:推荐GIF创建网站。 https://www.tutieshi.com/video/,免费创建GIF,赞扬良心网站!

LED流水灯# includereg 52.h # includeintrins.htypedefunsignedintu 16; 类型无符号化char u8; #defineledp2voiddeley(u16x ) while(x-- ) {}}void defaultDeley () ) deley (50000 ); (}int main ) ) { u8 i=0; LED=0xfe; //1111 1110 defaultDeley (; wile(1) for ) I=0; i7; I ) { LED=LED 1; LED=1; defaultDeley (; //01111111for(I=0; i7; I ) { LED=1; LED=0x80; defaultDeley (; (0b1111 1110 ) )此处直接操作P2寄存器。 因为想点亮第一盏灯,所以将P2的值设定为0b1111 1110,即0xfe。 然后,可以进行移位操作,使0位不断变化。 也就是说,情况如下。

1111 1110

1111 1101

1111 1011

.

循环的代码如下所示

LED=1; LED =1; 这样就可以向左点亮了。

向右点亮也很相似。 循环代码如下。

LED=1; LED=0x8

0;

于是这样就完全实现了流水灯。

运行效果:

(后面还有几秒钟,但GIF要超过csdn的限定大小了。。。)

其他效果 灯光二进制计数器

核心代码:

int main() { u8 full = 0xff; u8 cnt; while (1) { cnt = -1; while (1) { // cnt: 0000 0000 -> 0000 0001 // LED: 1111 1111 -> 1111 1110 cnt +=1; LED = full - cnt; defaultDeley(); if (cnt == 0xff) { break; } } }}

思路是让一个变量从0开始计数到0xff,LED对应的bit是0发光1熄灭的,这刚好是和我们的计数变量的二进制位模式相反,因此使用LED = 0xff - cnt进行取反,进而使LED显示与计数变量的变化对应起来。

运行效果:

但是此时的灯光计数器最低位在最左边,看起来不太舒服,因此希望修改最低位在最右边

那么我们仍然使用cnt作为计数变量,它将从0x00变化到0xff,然后我们再思考建立cnt到LED的映射关系:
看前面的变化规律:
cnt: 0000 0000 -> 0000 0001 -> 0000 0010
LED: 1111 1111 -> 0111 1111 -> 1011 1111
可以发现,LED的值应为cnt的二进制位模式反转后的补码,
即LED = 0xff - reverse(cnt);

这样,我们很容易就可以写出控制代码:

int main() { u8 full = 0xff; u8 cnt = 0; while (1) { cnt = -1; while (1) { // cnt: 0000 0000 -> 0000 0001 -> 0000 0010 // LED: 1111 1111 -> 0111 1111 -> 1011 1111 // LED = full - (reverse(cnt)); cnt +=1; LED = full - (reverse(cnt));; defaultDeley(); if (cnt == 0xff) { break; } } }}

其中二进制位模式的翻转函数为(输入一个数,返回它二进制位模式反转值):

u8 reverse(u8 x) { int cnt = 8; int res = 0; while (cnt--) { res <<= 1; res += x % 2; x >>= 1; } return res;}

运行效果:

进阶版流水灯

效果:

思路:原来的最基本的流水灯部分我们已经建立了bit为1时对应的灯亮的映射,即LED = 0xff - val;,然后为了实现这个效果,我们的val变量的变化情况应该如下所示:

0000 00000000 00010000 0010...1000 00001000 00011000 0010......1111 1111

这样我们操作时可以看做是两个变化的东西,一个是左边的“1”,代表已经到达终点的1,另一个是右边不断左移的“1”,因此这两个部分可以放在两个变量中分别存储,这里设为leftPart和rightPart。

这样我们设计外层循环中leftPart每次的变化为:leftPart>>=1; leftPart+=0x80;,而内层循环中rightPart变化,为:rightPart<<=1;,且循环次数用变量leftMoveTimes进行存储,一开始值为7,代表可以左移7次,然后每次外循环后-=1。

核心代码:

void showAndDeley(u8 res) { LED = 0xff - res; defaultDeley();}int main() { u8 rightPart , res, i; u8 leftMoveTimes; u8 leftPart;start: LED = 0xff; leftPart = 0; leftMoveTimes = 7; rightPart = 0; res = leftPart | rightPart ; showAndDeley(res); while (1) {// 外循环 rightPart = 1; res = leftPart | rightPart ; showAndDeley(res); for(i = 0; i< leftMoveTimes; i++){ // 内循环 rightPart <<= 1; res = leftPart | rightPart ; showAndDeley(res); } if (leftMoveTimes ==0) { goto start;// 重新开始运行 } leftPart>>=1; leftPart+=0x80; leftMoveTimes--; }}
, ,