ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

流水灯&数码管当LED灯闪烁小于0.2s时人眼几乎无法分辨

2020-07-04 23:39:38  阅读:286  来源: 互联网

标签:delay www LED 0.2 temp3 数码管 jianshu com


还记得第一次我们见面时的,我的紧张不知所措吗,还记得你用流水灯的悦动来安慰我吗,这些我都记得,致我们的那些年……
本人大一,某985电子信息专业在读,因为兴趣和爱好,第一次接触到51,也渐渐喜欢上了他,下面内容,欢迎各位大佬批评指正

主控芯片
这里采用的是某宝清翔51单片机开发板(说明一下,不是因为做广告,单纯只是说明自己的开发板,因为开发板设计不同,具体到某一模块的代码是有差异的,望大家不要存疑)
STC80C51芯片与STC公司另一款芯片STC89C52很相似

这里区分一下周期概念:
时钟周期:是时序的最小时间单位,所谓时序可以简单理解成时间顺序
时钟周期=1/时钟源频率
本文采用芯片晶振频率为11.0592MHz
机器周期:是单片机完成一个操作的最短时间,主要针对汇编语言而言,在汇编语言下程序的每一条语句执行所使用的时间都是机器
周期的整数倍,51单片机系列标准架构下一个机器周期是12个时钟周期,也就是12/11059200秒

流水灯

这里采用的共阳极LED灯组,分别接主控芯片8个IO口,所谓共阳极,也就是说,如果IO口输出高电平,无电势差,LED小灯无电流不点亮;反之,如果输出低电平 ,有电势差,LED小灯有电流点亮

以下是一次性电亮八个小灯的程序

#include <reg52.h>//包含51头文件

unsigned int i;//0~65535

void main()//main函数自身会循环

//1
temp1=0xaa;
for(i=16;i>0;i--)
{
P1=temp1;
delay(t);
temp1=~temp1;
P1=temp1;
delay(t);
t=t-10;
}
for(i=20;i>0;i--)
{
t=40;
P1=temp1;
delay(t);
temp1=~temp1;
P1=temp1;
delay(t);
}
temp1=0x00;
P1=temp1;
delay(1000);

//2
for(a2=0;a2<4;a2++)
{
temp2=C[a2];
P1=temp2;
delay(250);
temp2=_cror_(temp2,a2+1);
P1=temp2;
delay(250);
}
for(a2=0;a2<4;a2++)
{
temp2=C[a2+4];
P1=temp2;
delay(250);
temp2=_crol_(temp2,4-a2);
P1=temp2;
delay(250);
}

//3
//左加
c=1;
Temp=0xff;
temp3=0x01;
for(b=8;b>0;b--)
{
for(a=0;a<b;)
{
Temp=Temp^temp3;
P1=Temp;
delay(100);
a++;
if(a!=b)Temp=Temp|temp3;
if(a!=b)temp3=_crol_(temp3,1);
else temp3=_crol_(temp3,c);
}
c++;
}
delay(100);

//右减
c=1;
Temp=0x00;
temp3=0x80;
for(b=8;b>0;b--)
{
for(a=0;a<b;)
{
Temp=Temp|temp3;
P1=Temp;
delay(100);
a++;
if(a!=b)Temp=Temp^temp3;
if(a!=b)temp3=_cror_(temp3,1);
else temp3=_cror_(temp3,c);
}
c++;
}
delay(100);

//右加
c=1;
Temp=0xff;
temp3=0x80;
for(b=8;b>0;b--)
{
for(a=0;a<b;)
{
Temp=Temp^temp3;
P1=Temp;
delay(100);
a++;
if(a!=b)Temp=Temp|temp3;
if(a!=b)temp3=_cror_(temp3,1);
else temp3=_cror_(temp3,c);
}
c++;
}
delay(100);

//左减
c=1;
Temp=0x00;
temp3=0x01;
for(b=8;b>0;b--)
{
for(a=0;a<b;)
{
Temp=Temp|temp3;
P1=Temp;
delay(100);
a++;
if(a!=b)Temp=Temp^temp3;
if(a!=b)temp3=_crol_(temp3,1);
else temp3=_crol_(temp3,c);
}
c++;
}
delay(100);

//4

for(a=0;a<7;a++)
{
temp4=A[a];
for(b=8-a;b>0;b--)
{
P1=temp4;
temp4=_crol_(temp4,1);
delay(100);
}
temp4=_cror_(temp4,1);
for(b=8-a;b>0;b--)
{
P1=temp4;
temp4=_cror_(temp4,1);
delay(100);
}
}
temp4=0x00;
P1=temp4;
delay(100);
for(a=3;a>0;a--)
{
for(b=0;b<5;b++)
{
temp4=B[b];
P1=temp4;
delay(100);
}
}
}

说明:由于人眼具有视觉暂留最小时间,当LED灯闪烁小于0.2s时,人眼几乎无法分辨,这里用到了delay()毫秒级延迟函数,所根据的即上述周期的概念,用空语句来占据时间,达到延迟效果。而_crol_(),cror()语句为循环左右移,与<<和>>不同的是,循环移位是八位数循环,边位数据不会被挤掉

数码管

简单的说,数码管本质也是LED灯,由八个LED灯组成的段构成,最后一个段即每一位上的点,清翔51开发板上用的共阴极数码管,与流水灯共阳极类似,读者可自行理解。看到这里,相信大家都会发问,流水灯八个已经用了八个IO口了,数码管这么的位,每一个都有八个LED灯,那需要多少IO口啊,8x8=64?芯片引脚够用吗?为了解决这个问题,方法有很多种,而常用的是利用锁存器,清翔开发板上用的两片级联的74H573锁存器。

74H573锁存器的利用大大节省了IO口的使用,只使用8个IO口便可达到控制8位数码管的作用,使得其他IO口可以做其他用途使用。它的工作形式可以简单描述为,主控芯片依次先后用8个IO口发送位选值和段选值,位选值先用来控制哪一位的数码管,而段选值用来控制这位数码管具体显示哪一个数字。

静态显示
到这里我们就可以实现具体的一位数码管的静态静态显示:

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选

void main()//main函数自身会循环
{
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110 选通第一位数码管
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = 0X06;//0000 0110 显示“1”
DU = 0;//锁存段选数据

while(1)
{
}
}

动态扫描
静态显示效率太低了,每次上电只能显示一位数字,而想要多为数码管,多个数字扫描便需要动态显示。动态显示原理是,依据人眼的视觉暂留效果,机器运行时间极短,在这种条件下,先后控制不同位数码管显示数字,使得人眼看到的效果是显示了许多位,而本质,每次只显示一位。这里因为只用8个IO口,涉及位选和段选的切换,会造成改变选值时,在极短的时间内,上一个数据会转送进来并显示,使得数码管看上去有鬼影效果。消除鬼影的方法很多,很多博主都有介绍,而学习了几个月的51,自己也并没有完全掌握,鬼影时而也是存在的,可见微观世界的奇妙就像爱情一样,不是我们随随便便都能猜透彼此的心思,你可能想要的不要显鬼影,而她确如鬼影一般时时跟随着你,不离不弃,生死相依,人类宏观世界的奇妙,在微观世界同样存在,微观与宏观之间也存在着千丝万缕的联系,通过一行行美丽的代码文字而表达(纯属编者瞎扯…………)
下面先附上动态扫描的代码:

#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选

//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};

void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

void display(uchar i)
{
uchar bai, shi, ge;
bai = i / 100; //236 / 100 = 2
shi = i % 100 / 10; //236 % 100 / 10 = 3
ge = i % 10;//236 % 10 =6

//第一位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[bai];//
DU = 0;//锁存段选数据
delay(5);

//第二位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[shi];//
DU = 0;//锁存段选数据
delay(5);

//第三位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[ge];//
DU = 0;//锁存段选数据
delay(5);
}

void main()//main函数自身会循环
{
while(1)
{
display(236); //数码管显示函数
}
}

聪明的你会惊奇的发现,咦,这个段选表是什么东东捏?原来,在控制每一位数码管显示具体数字时,数字的样式对应数码管的需要点亮LED的结构时对应的,这种对应关系映射到用数组表达,每次需要显示一个数字的时候,让主控芯片输出对应数组的值,是不是效率就高了很多,代码理解起来也更方便,移植性也更强,当然我们也可以将位选也写成数组会更加方便。
附上完整的表格:

uchar code SMGduan[]={//共阴极数码管段选表
//0 1 2 3 4 5 6 7 8 9
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
uchar code SMGwei[8]={//共阴极数码管位选表
//1 2 3 4 5 6 7 8
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

鬼影消除
常用的方法是:
①P0 = 0XFF;在位选之前使用,达到消除鬼影的作用。
②更改延时,减少延时的时间或者中断里面的时间。
PS 编者的开发经验十分有限,欢迎各位大佬有更好的方法批评指正!

8X8点阵

清翔的开发板上,点阵屏是单拿出来的外接模块,底部有两片级联的74H595芯片。前面我们已经学会了流水灯,和数码管,8X8点阵屏和他们有相似的地方,每一个点也是一个LED灯,通过控制IO口输出电平形成电势差来控制亮灭。工作机理是遍利每一行,在改行时,控制点亮的点,通过动态扫描,实现一个汉字的显示。这里遍历每一行的顺序时固定的,因此我们只需要控制在该行时点了的点即可,这里可以借助汉字取模软件PCtoLCD2002来直接得到所需汉字的列选值,放在一个数组中。

#include <reg52.h>
#include <intrins.h> //循环右移头文件
sbit DIO = P3^4; //串行数据口
sbit S_CLK = P3^5;//移位寄存器时钟
sbit R_CLK = P3^6;//输出锁存器时钟
/*点阵字形码*/
unsigned char code tabel[2][8]={

0xE0,0xEE,0x01,0x6D,0x01,0x6D,0x01,0xEF,//电
0xE7,0xF7,0xF7,0xF7,0x80,0xF7,0xFB,0xC3//子
};
/*595发送一字节*/
void Send_Byte(unsigned char dat)
{
unsigned char i; //循环次数变量
S_CLK = 0;//拉低移位寄存器时钟
R_CLK = 0;//拉低输出锁存器时钟
for(i=0; i<8; i++) //循环8次
{
if(dat & 0x01)//发送1
DIO = 1;
else //发送0
DIO = 0;
dat >>= 1;//数据右移
S_CLK = 1;//拉高移位寄存器时钟,数据移位
S_CLK = 0;//拉低移位寄存器时钟
}
}
void main()
{
unsigned char j, k, ROW;//j发送8列和8行字形码,k字符数量,ROW行值
unsigned int z; //动态扫描延时变量
while(1)
{
for(k=0; k<2; k++)//k 需要显示的字符数量
{
for(z=0; z<1000; z++)//z刷新次数
{
ROW = 0x80;//行选初值
for(j=0; j<8; j++) //循环8次发送行和列值
{
Send_Byte(tabel[k][j]);//发送列选值
Send_Byte(ROW); //发送行选值
R_CLK = 1; //拉高输出锁存器,把移位寄存器中数据输出
R_CLK = 0; //拉低输出锁存器
ROW = _cror_(ROW, 1);//右移,选择下一行
}
}
}
}
}

写道这里,第一次认真写博客的小白同学,紧张万分,不知道会有什么反响,也不知道自己掌握的情况如何,热烈欢迎大家批评指正,我也将和各位一起努力成长,追寻我们的热爱!

https://www.jianshu.com/p/95fc695c3244
https://www.jianshu.com/p/8b12a52dd254
https://www.jianshu.com/p/23e0334467fc
https://www.jianshu.com/p/4d7c6c9c0031
https://www.jianshu.com/p/d4eaeb850bdd
https://www.jianshu.com/p/9e1ad60ecea2
https://www.jianshu.com/p/b77d0b722723
https://www.jianshu.com/p/125837d40392
https://www.jianshu.com/p/095b34482862
https://www.jianshu.com/p/640d626955d4
https://www.jianshu.com/p/b4ce55cb81ae
https://www.jianshu.com/p/f3e0c6ec5a9e
https://www.jianshu.com/p/eb9c4a4326c5
https://www.jianshu.com/p/ea4e8788f7fb
https://www.jianshu.com/p/718192bafb66
https://www.jianshu.com/p/e6fb79ab5a8c
https://www.jianshu.com/p/cf473e003ddb
https://www.jianshu.com/p/df90b37956a2
https://www.jianshu.com/p/78d27cdb67e2
https://www.jianshu.com/p/32e61d52428b
https://www.jianshu.com/p/84648dc5f519
https://www.jianshu.com/p/24f6802872d1
https://www.jianshu.com/p/d88b778c00cb
https://www.jianshu.com/p/67c3c9134797
https://www.jianshu.com/p/0ff8875846a1
https://www.jianshu.com/p/01921c1cbec2
https://www.jianshu.com/p/e64f7f2a0191
https://www.jianshu.com/p/49fd65fb1ae6
https://www.jianshu.com/p/3749b01e1c76
https://www.jianshu.com/p/ffeaefee206f
https://www.jianshu.com/p/ec540ef9df8c
https://www.jianshu.com/p/763d027f8f11
https://www.jianshu.com/p/5c38a72ece5f
https://www.jianshu.com/p/804015960ae9
https://www.jianshu.com/p/dc6809c05942
https://www.jianshu.com/p/f03194f521ca
https://www.jianshu.com/p/b5d9626fd30c
https://www.jianshu.com/p/263791a8350f
https://www.jianshu.com/p/3157b05052ae
https://www.jianshu.com/p/dd50179cf2e5
https://www.jianshu.com/p/b124ad90506a
https://www.jianshu.com/p/19ffb5a0b250
https://www.jianshu.com/p/f02ba65f1bda
https://www.jianshu.com/p/26b5d90b723e
https://www.jianshu.com/p/10398aaad8c2
https://www.jianshu.com/p/7e207b0b93c2
https://www.jianshu.com/p/15b72277c1bb
https://www.jianshu.com/p/32afff38d1d9
https://www.jianshu.com/p/07f66b9100ce
https://www.jianshu.com/p/1a66ca0367c0
https://www.jianshu.com/p/d5498b70fdf4
https://www.jianshu.com/p/9306ed576a9a
https://www.jianshu.com/p/d686dc84dae0
https://www.jianshu.com/p/be5f0fabf0aa
https://www.jianshu.com/p/a3983b727c68
https://www.jianshu.com/p/ca9e64db9402
https://www.jianshu.com/p/5f39b0569bca
https://www.jianshu.com/p/d06fd49337e1
https://www.jianshu.com/p/07a1fdd477f4
https://www.jianshu.com/p/2ef2725b4855
https://www.jianshu.com/p/ac1d5d97fe92
https://www.jianshu.com/p/f6a4049028a7
https://www.jianshu.com/p/36b965e56f8c
https://www.jianshu.com/p/470e8057f8ea
https://www.jianshu.com/p/75dfbf416b81
https://www.jianshu.com/p/517473b044b0
https://www.jianshu.com/p/4dcb5c9deb50
https://www.jianshu.com/p/2f02c12620d0
https://www.jianshu.com/p/0bf7c7c1a5e4
https://www.jianshu.com/p/d49dc8c83fa8
https://www.jianshu.com/p/f702cd18bbec
https://www.jianshu.com/p/b0cd3a80ef0f
https://www.jianshu.com/p/6cfdb96eba9d
https://www.jianshu.com/p/09a7199e1b14
https://www.jianshu.com/p/d346177c5e73
https://www.jianshu.com/p/2e744b2e4c25
https://www.jianshu.com/p/da525a59a502
https://www.jianshu.com/p/977f8751eca6
https://www.jianshu.com/p/34b4f14f2a9b
https://www.jianshu.com/p/b0ce76098f2c
https://www.jianshu.com/p/10befb188ceb
https://www.jianshu.com/p/df338651bb5d
https://www.jianshu.com/p/0859e8d6badf
https://www.jianshu.com/p/11b177a8f8e8
https://www.jianshu.com/p/44e0c70c22a4
https://www.jianshu.com/p/f6f840b945fe
https://www.jianshu.com/p/243233913b49
https://www.jianshu.com/p/64eb3252289f
https://www.jianshu.com/p/e302abafbc92
https://www.jianshu.com/p/c1c898b9e17d
https://www.jianshu.com/p/6a39ca1b7b91
https://www.jianshu.com/p/0c7a43fd8ae8
https://www.jianshu.com/p/e4dce8dd29ff
https://www.jianshu.com/p/3ea533932e30
https://www.jianshu.com/p/71b9f8ae037a
https://www.jianshu.com/p/c2b66d25dfc1
https://www.jianshu.com/p/5f665088ac90
https://www.jianshu.com/p/84564909aea5
https://www.jianshu.com/p/bc4d79167988
https://www.jianshu.com/p/cd1467875493
https://www.jianshu.com/p/a0f1e819a27e
https://www.jianshu.com/p/435b816d50c1
https://www.jianshu.com/p/07891ac5a48b
https://www.jianshu.com/p/62d6fce27ebc

 

标签:delay,www,LED,0.2,temp3,数码管,jianshu,com
来源: https://www.cnblogs.com/kaikaixin66/p/13237199.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有