标题:
单片机数码管动态扫描程序,有一个没搞懂,求解惑!
[打印本页]
作者:
tanghao8887
时间:
2018-11-7 14:57
标题:
单片机数码管动态扫描程序,有一个没搞懂,求解惑!
以下这段是数码管动态扫描的单片机程序,这段程序实现的是8个数码管同时循环显示11111111,22222222,一直到99999999,以下几个地方我不明白,大家帮我指导以下:
①数码管用共阴极,用的是138译码器控制8和数码管的负级,大家知道,138译码器一次性只能输出一位低电平,不能同时全输出低电平,也就是只能通过switch选择语句来一位一位的点亮,不能实现同时一起点亮同一个数,并且循环扫描显示,于是,我就请教了很多论坛朋友,他们修改了一段代码,我就不理解是什么意思,也就是从我编写的原基础上,增加了:
void main()
{
unsigned char i;
while(1)
{
for (i=0;i<200;i++)
{
DigDisplay();
}
k++;
if (k>9)
{
k=0;
}
}
}
我看不懂的是,它在main主函数里增加要循环200次这个子函数的意义是什么,这样会不会是为了快速刷新子函数里面的这个switch反复执行来达到138译码器全部无间隔的提供负级,让数码管显示00000000,11111111,这样循环显示到99999999然后又从0开始?是这样吗?
以下是网友们修改的代码,可以实现同时一起动态扫描显示,我就不理解为何要让子函数执行200次的循环!
修改后我不能理解的程序:
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned char k=0;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(u16 i)
{
while(i--);
}
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i)
{
case(0):
LSA=0;LSB=0;LSC=0; break;
case(1):
LSA=1;LSB=0;LSC=0; break;
case(2):
LSA=0;LSB=1;LSC=0; break;
case(3):
LSA=1;LSB=1;LSC=0; break;
case(4):
LSA=0;LSB=0;LSC=1; break;
case(5):
LSA=1;LSB=0;LSC=1; break;
case(6):
LSA=0;LSB=1;LSC=1; break;
case(7):
LSA=1;LSB=1;LSC=1; break;
}
P0=smgduan[k];
delay(100);
P0=0x00;
}
}
void main()
{
unsigned char i;
while(1)
{
for (i=0;i<200;i++)
{
DigDisplay();
}
k++;
if (k>9)
{
k=0;
}
}
}
复制代码
下面是我个人写的不能同时显示得程序,这个程序就只能利用动态扫描来显示出1234567,就不动了!
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
void delay(u16 i)
{
while(i--);
}
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=smgduan[i];//发送段码
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void main()
{
while(1)
{
DigDisplay(); //数码管显示函数
}
}
复制代码
作者:
Dremt
时间:
2018-11-7 16:43
动态扫描就是几个数码显示的数字式一直显示的,实际上是一个一个在显示,这就是动态显示
作者:
mengzhixinheng
时间:
2018-11-7 17:15
显示同一个数的次数,相当于延时
作者:
qingfengyu
时间:
2018-11-7 17:54
你的 i 先复制为零 在循环八次 之后 i就为八了 所以就不会继续显示了 所以你的i要去判断
if (i == 8)
{
i = 0;
}
作者:
chengdeshi
时间:
2018-11-7 18:13
uchar code ledcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar buf1[8];
void dis()
{
uchar i,j=0x7f;
for(i=0;i<8;i++)
{
cs1=0;cs2=1;
P0=ledcode[buf1[i]];wr=1;wr=0;
cs1=1;cs2=0;
P0=j;wr=1;wr=0;
delay(100);
cs1=cs2=1;
j=_cror_(j,1);
P0=0xff;wr=1;wr=0;
}
}
void main()
{
buf[0]=1; //想用第几个数码管就写buf[几]
buf[1]=2; //等于后面的是用来显示上面的数组的,
//等于1就是显示ledcode的第一个数组也就是1
buf[2]=3; //不过我这个是共阴极的数码管
while(1){dis();}
}
复制代码
作者:
wulin
时间:
2018-11-7 22:03
他在main主函数里增加要循环200次是为了延时,使0~9变化不至于太快而无法辨识。也就是数码管动态扫描显示200次,显示内容才变化1次。由于单片机运行速度非常快,你要处理的任务又很少,主循环周期很短。0~9变化太快你看到的是笔画亮度不均的8字。坛友是在你的程序基础上优化的,在实际应用中不可能是这样处理的。
作者:
zl2168
时间:
2018-11-8 09:06
还是要打基础,学理论,否则,问题多多,事倍功半。
作者:
ljx8940
时间:
2018-11-8 10:30
第一段程序的变量k是两段程序运行结果不一样的关键
作者:
yzwzfyz
时间:
2018-11-8 13:38
是你未理解如何扫描:
准备好一行的显示码 → 关所有显示(防止因切换引起错码闪动)→ 输出显示码 → 打开显示
→ 间隔一段时间(这段时间才能让人眼感觉到显示的信息!间隔小了人眼看分不清,间隔大了有闪烁感,需要仔细选择)
下一行开始,如发泡制。
作者:
tanghao8887
时间:
2018-11-16 19:27
wulin 发表于 2018-11-7 22:03
他在main主函数里增加要循环200次是为了延时,使0~9变化不至于太快而无法辨识。也就是数码管动态扫描显示20 ...
谢谢,我明白了!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1