今天的实验带大家在Proteus当中,通过Arduino来驱动和使用LED点阵,掌握基本的LED点阵的 *** 作方法。
关于LED点阵的工作原理,将在实验之后再进行一些解释和说明。现在还是首先动手,将LED点阵驱动起来,先知其然,再探究其所以然。
第一步,先将Proteus运行起来,同样新建一个Arduino 328的项目,自己为项目取个名字,此处取名为LEDMatrix。
第二步,要从元件库当中找到LED点阵,并添加到工作区。
点击左侧“Component Mode”按钮——点击“P”按钮——在输入框中输入 matrix——在下方的分类中选择 Optoelectronics,此时在右侧的结果(Results)窗口中将会出现搜索结果。
我们选择一个8×8规格的点阵,颜色可以选择自己喜欢的。
此处选择MATRIX-8×8-RED。
第三步,将LED点阵放置在原理图设计画布上。
此时我们可以观察到,放置完成的LED点阵一共有64个LED灯珠,共8行,8列;同时上下两侧各有8根管脚。
现在遇到的一个重要问题是如何判断这16根管脚的功能和连接方式。
最简单的办法是搜索、查阅LED点阵的相关数据手册。通过简单的研究我们可以了解到,缓知LED点阵的两排管脚,一排代表“行”,一排代表“列”,通过某行某列的交叉来定位某一个灯珠,同时通过“行高电平、列低电平”或者相反的“行低电平、列高电平”来决定某灯珠是否被点亮。那我们选择的这一款LED点阵,究竟哪一排是“行”?哪一排是“列”?驱动模式是“行高列低”还是“行低列高”呢?
接下来就要用到一个简单的小办法,来自行测试、探索一下。
小技巧:如何来测试LED点阵的工作模式?
我们直接在LED点阵模块的不同管脚上,加上电源和接地,来观察LED点阵的点亮情况。
在Terminal模式下,选择Power,放置一个电源端子,并设置其属性为VCC。同样的方法,添加一个GROUND接地端子。
按照下图,完成最简单的连线,并点击仿真按钮,进行仿真,观察运行结果。
结果分析:
1、首先,左侧上排接高电平,下排接低电平的部分被点亮;而右侧上排接低电平、下派接高电平的部分未被点亮。
2、其次,观察左侧被点亮的部分,1,2列和1,3行被点亮,因此上排管脚为“列”,下排管脚为“行”。扰皮消
3、结论:上排管脚为列,下排管脚为行,点亮模式为:列高行低。
第四步,将LED点阵模块的管脚与Arduino的IO管脚进行连接。如下图。
第五步,在Source Code模式下,编写Arduino程序。
程序中自定义了一个litup()的点亮函数。在主函数loop()循环中,将IO端口号作为参数传入握如litup()函数中,同时通过for循环的嵌套,完成了64个位置的遍历。
运行效果:
一个红色光点,从LED屏幕的左上角开始,沿着每一行从左到右移动,并自动换到下一行。
思考练习
1、如何在一个8×8 的点阵屏上显示数字3?
2、如何让点阵以一次递增一个的方式点亮全部灯珠?
要用首档拿8×8的LED点阵显示数字0~9,先用proteus 画出仿真图,然后用取模软件画出数字8×8点阵图形,并按行取模,每个数字共8个字节数据,显示时取出字模并逐蠢源行扫描就者搭行了。
#include<reg51.h>
unsigned char seven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90}
unsigned char flash,mode=0
char min=50,hour=12,hour_rom,min_rom,sec=25
unsigned char j,k
unsigned int i
unsigned char key_set_s,key_up_s,key_down_s,key_reset_s
sbit P0_7=P0^7
sbit key_set=P3^4
sbit key_up=P3^5
sbit key_down=P3^6
sbit key_reset=P3^7
sbit buzzer=P1^0
bit dop,bb //声明
void delay(unsigned int x) //延时
{
while(x--)
}
void timer0_isr(void) interrupt 1 //中断服务函数
{
TH0=0xf8 //为65535-2000=63535转化为16进制取高八位
TL0=0x2f //取低八位
i++
bb=!bb
if(i>=250) 枯瞎基//半秒,五神闷百没谨一秒
{
i=0
k++
flash=~flash
dop=!dop
}
if(k>=2) //大于二归零
{
k=0
sec++
}
if(sec>=60) //秒
{
sec=0
min++
}
if(min>=60) //分
{
min=0
hour++
}
if(hour>=24) //小时
hour=0
P0=0xff //P0初始化为全1 11111111
if(mode==0) //正常显示
{
switch(j) //控制语句
{
case 0:P0=seven_seg[sec%10]P2=0xfebreak //秒个位
case 1:P0=seven_seg[sec/10]P2=0xfdbreak //秒十位
case 2:P0=seven_seg[min%10]P0_7=dopP2=0xfbbreak
case 3:P0=seven_seg[min/10]P2=0xf7break
case 4:P0=seven_seg[hour%10]P0_7=dopP2=0xefbreak //dop为小数点
case 5:P0=seven_seg[hour/10]P2=0xdfbreak
}
}
////////////////////
if(mode==1) //模式一 C1状态
{
switch(j)
{
case 0:P0=seven_seg[min%10]P2=0xfebreak
case 1:P0=seven_seg[min/10]P2=0xfdbreak
case 2:P0=seven_seg[hour%10]| flashP2=0xfbbreak //flash为闪烁
case 3:P0=seven_seg[hour/10]| flashP2=0xf7break
case 4:P0=seven_seg[1]P2=0xefbreak //1为C1状态
case 5:P0=0xc6P2=0xdfbreak //0xc6为显示C
}
}
////////////////////
if(mode==2) //模式二 C1状态
{
switch(j)
{
case 0:P0=seven_seg[min%10]| flashP2=0xfebreak
case 1:P0=seven_seg[min/10]| flashP2=0xfdbreak
case 2:P0=seven_seg[hour%10]P2=0xfbbreak
case 3:P0=seven_seg[hour/10]P2=0xf7break
case 4:P0=seven_seg[1]P2=0xefbreak
case 5:P0=0xc6P2=0xdfbreak
}
}
////////////////////
if(mode==3) //模式三 C2状态
{
switch(j)
{
case 0:P0=seven_seg[min_rom%10]P2=0xfebreak
case 1:P0=seven_seg[min_rom/10]P2=0xfdbreak
case 2:P0=seven_seg[hour_rom%10]| flashP2=0xfbbreak
case 3:P0=seven_seg[hour_rom/10]| flashP2=0xf7break
case 4:P0=seven_seg[2]P2=0xefbreak
case 5:P0=0xc6P2=0xdfbreak
}
}
////////////////////
if(mode==4) //模式四 C2状态
{
switch(j)
{
case 0:P0=seven_seg[min_rom%10]| flashP2=0xfebreak
case 1:P0=seven_seg[min_rom/10]| flashP2=0xfdbreak
case 2:P0=seven_seg[hour_rom%10]P2=0xfbbreak
case 3:P0=seven_seg[hour_rom/10]P2=0xf7break
case 4:P0=seven_seg[2]P2=0xefbreak
case 5:P0=0xc6P2=0xdfbreak
}
}
j++
if(j>=6)
j=0
}
void key(void) //调用开关函数
{
////////////////
if(key_set==0) //设置
{
delay(300)
if(key_set==0)
key_set_s=1
}
if(key_set==1&&key_set_s==1)
{
mode++
if(mode>=5)
mode=1
key_set_s=0
}
////// ///
if(key_up==0) //上调
{
delay(300)
if(key_up==0)
key_up_s=1
}
if(key_up==1&&key_up_s==1)
{
if(mode==1)hour++
if(mode==2)min++
if(mode==3)hour_rom++if(hour_rom>=24)hour_rom=0
if(mode==4)min_rom++if(min_rom>=60)min_rom=0
key_up_s=0
}
/////////////////
if(key_down==0) //下调
{
delay(300)
if(key_down==0)
key_down_s=1
}
if(key_down==1&&key_down_s==1)
{
if(mode==1)hour--if(hour<0)hour=23
if(mode==2)min-- if(min<0)min=59
if(mode==3)hour_rom--if(hour_rom<0)hour_rom=23
if(mode==4)min_rom--if(min_rom<0)min_rom=59
key_down_s=0
}
/////////////////
if(key_reset==0) //复位
{
delay(300)
if(key_reset==0)
key_reset_s=1
}
if(key_reset==1&&key_reset_s==1)
{
key_reset_s=0
mode=0
}
}
void timer0_init(void) //timero初始化函数
{
TMOD=0x01 //方式1
TH0=0xf8
TL0=0x2f
EA=1 //中断开关
ET0=1 //中断小开关
TR0=1 //开始计数
}
void main(void) //主函数
{
timer0_init()
while(1)
key()
{
if(hour==hour_rom&&min==min_rom)
buzzer=bb //buzzer为蜂鸣器
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)