LED点阵
点阵原理
- 我的开发板是 16*16 红绿 双色的LED点阵,但我只用到了红色的,所以我们暂且只看黑色LED,其实只要让LED导通,我们就可以点亮任意一个LED小灯
如要点亮 左上角第一个LED ,只要让 22 置 1 ,23 置 0 就可以让它导通,就亮了
- 如果要让整个点阵按自己的想法显示,比如显示数字汉字啥的,可以用类似于数码管的 动态扫描 想法,我的理解是给 行 一个 段选 码表,给 列 一个 位选 码表,让 行 逐行扫描,配合列看看该行有没有要显示的LED,不好理解等下看程序
点亮一个
程序
#include
#define LedH P0 //用P0口控制行
#define LedL P1 //用P1口控制列
void main()
{
while(1)
{
LedH=0x01; //只让第一个LED导通
LedL=0xfe;
}
}
显示图形
- 显示图形可以自己去计算每个点,但是效率太低,这里我们可以用到 取字模软件
![]()
- 就像这样,它会直接把你点亮的地方的段码给你,这样我们就可以直接用了
- 还有这个软件的一个参数设置,根据不同的编程,参数设置也是不同的
![]()
程序
#include
#define LedH P0
#define LedL P1
unsigned char code wei[8]=
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char code duan[8]=
{0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C};
void main()
{
unsigned char i;
while(1)
{
for(i=0;i<8;i++)
{
LedL=0xff; //消影
LedH=duan;
LedL=~wei;
}
}
}
- 不知道为什么,我用IO来传输数据时,它显示的有点暗,而用 95芯片 传输时,则不会这样,不知道是不是IO口的驱动能力不足导致的,所以下面我就用 595芯片 来驱动LED点阵
HC595芯片
- 在显示上,为了更节省IO口,更简便,我们可以用 595芯片 ,也可用 138芯片 之类的,而我则用了两个 595芯片,一个用来控制 行 给它 段选 ,一个来控制 列 给它 位选 ,这样就节省了两个IO口,同时为了防止产生上面显示太暗的这个弊端
用法
- 下面我直接给出 595芯片 的驱动程序吧,要说原理我也不太清楚,要用的直接在这个上面改就行了
#include "STC89C5xRC.H"
#include "intrins.h"
#define uchar unsigned char //对数据类型进行声明定义
***it SRCLK = P3^6; //定义IO口,看开发板的原理图
***it RCLK1 = P3^5;
***it SER = P3^4;
void HC595(uchar dat1) //595芯片驱动程序,,这是传一个,要穿两个可以加一个dat2
{
uchar a;
SRCLK = 1;
RCLK1 = 1;
for(a=0;a<8;a++) //发送8位数
{
SER=dat1>>7; //从最高位开始发送
dat1<<=1;
SRCLK=0; //发送时序
_nop_();
_nop_();
SRCLK=1;
}
RCLK1=0;
_nop_();
_nop_();
RCLK1=1;
}
- 二维数组
数据类型 数组名[数组长度1][数组长度2];
- 数组元素的数量可以小于数组元素个数,没有赋值的会自动给0,当数组元素的数量等于数组个数的时候,如下
unsigned char a[2][3] =
{
{1,2,3}, {4,5,6}
};
或者是
unsigned char a[2][3] =
{1,2,3,4,5,6};
unsigned char a[2][3] =
{
{1,2}, {3,4}
};
等价于
unsigned char a[2][3] =
{1,2,0,3,4,0};
反过来
unsigned char a[2][3] =
{1,2,3,4};
等价于
unsigned char a[2][3] =
{
{1,2,3}, {4,0,0}
};
最终程序
#include
#include "intrins.h"
#define uchar unsigned char
uchar code imagewei[8]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};
uchar code imageduan[11][8]=
{
{0x00,0x00,0x44,0x92,0x92,0x92,0x6C,0x00}, //3
{0x00,0x00,0xE4,0xA2,0xA2,0xA2,0x9C,0x00}, //2
{0x00,0x00,0x88,0x84,0xFE,0x80,0x80,0x00}, //1
{0x00,0xC3,0xC3,0xFF,0xFF,0xC3,0xC3,0x00}, //i
{0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C}, //心
{0x00,0x7F,0xFF,0xC0,0xC0,0xFF,0x7F,0x00}, //u
{0x00,0x18,0x3C,0x78,0x78,0x3C,0x18,0x00}, //小心
{0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C}, //中心
{0x3E,0x7F,0xFF,0xFE,0xFE,0xFF,0x7F,0x3E}, //大
// {0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C}, //中心
{0x00,0x18,0x3C,0x78,0x78,0x3C,0x18,0x00}, //缩小
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //全灭
};
***it SRCLK = P3^6;
***it RCLK1 = P3^5;
***it SER = P3^4;
void HC595(uchar dat1,uchar dat2) //595芯片驱动程序,直接拿上面的来用,修改一下
{
uchar a;
SRCLK = 1;
RCLK1 = 1;
for(a=0;a<8;a++)
{
SER=dat1>>7;
dat1<<=1;
SRCLK=0;
_nop_();
_nop_();
SRCLK=1;
}
for(a=0;a<8;a++) //传输的第二个数据
{
SER=dat2>>7;
dat2<<=1;
SRCLK=0;
_nop_();
_nop_();
SRCLK=1;
}
RCLK1=0;
_nop_();
_nop_();
RCLK1=1;
}
void main()
{
int k,x,y;
uchar j;
uchar i;
y=0;
while(1)
{
if(j<6)
{x=200;} //让前面321倒计时切换慢点
else
{x=60;} //让后面心跳快点
for(k=0;k
{
for(i=0;i<8;i++) //扫描
{
HC595(~imagewei,imageduan[j]);
}
}
j++;
if(j==11) //单独循环7次后面的心跳
{
j=7;
y++;
}
if(y==7) //单独循环完后重新开始
{
j=0;
y=0;
}
}
}
最终效果展示
啦~最终效果就完成啦
是不是看起来还可以,工科直男也有浪漫的好吧,我们不需要什么玫瑰花,不需要什么礼物,我们玩的高科技,玩的是技术,不开玩笑了,收工~
- 我本来想的在加一个定时器中断蜂鸣器来模拟心跳的声音的,但是这个不知道怎么上传视频,就懒得弄了
|
|
2022-1-21 13:54:49
评论
举报
|
|
|