c51的led点阵是用74Hc595这个串行输出芯片输出的,这样是为了不占用多余的IO口同时也能达到控制每个LED的亮灭的效果,非常的好使,而且这个芯片还可以几个连在一起使用,可以多级来连接,
下面直接上图解释
可以看到分别有三个引脚控制这个芯片,后面就有一排输出数据引脚。
首先看这个P34——SER这个引脚是干嘛的呢。串行数据口,意思就是一个一个的输出,怎么工作的呢,这个就到了下一个引脚的功能了,P36——SRCLK这个引脚就是串行时钟,意思就是时钟每开一次,这个SER引脚的数据就写入以为,至于写入1还是0这个就是自己决定的。那么写完这么多位我怎么写入到输出引脚的,这个就是由P35——RCLK引脚叫做锁存时钟,作用就是,数据写够了这么多位了,那么这个引脚启动,就会把写的数据一些子搬运到输出引脚。总共八个引脚,所以P34移位8次,然后P36时钟要打开八次,然后P35引脚等到8次写完了,那么就直接打开把这些搬运出去。大概就在这么个流程。
下面解释一下点阵这个图,这个是网上截的图,但是实物跟这个是一样的哈,标红线的就是这个点阵图的引脚排列,接的端口。可以看到D0到D7是从下往上对着的,然后P0到P7是从右往左走的,假如说,我要点亮第左上角第一个,那么我D7就要高电平,P7就要低电平,或者两个反过来。
但是假如说我要斜对角亮那是不是D0到D7都给高电平,然后P0到P7都给低电平这样就可以了,虽然这样是可以,但是其它的灯也会跟着同时亮,这样就达不到我们要的效果,所以我么就要扫描,就是我们先把左上角第一个灯点亮D7和P7,然后关掉,然后再给D6和P6然后依次,亮灭亮灭扫描的效果就可以达到了。然后显示字体也是一样的效果的。
懂得原理就行了。接下来就写代码了。
首先初始化引脚三个控制引脚。再加一个P0。
#include <regx52.h>
sbit SER=P3^4; //用于数据的地址输入
sbit RLCK=P3^5; //当有数据输入的时候这个变1就是有上升沿到来的时候,就把SER的数据并行输出
sbit SERCLK=P3^6; //当这个为1的时候就是把SER的数据移位输出每来一个高电平就输出一个,
#define MATRIX_LED_PORT P0 //这里给共定义方便等下写
然后开始写引脚初始化,我们要先关闭。引脚先
/**
* @brief 矩阵LED初始化
* @param 无
* @retval 无
*/
void juzhenLED_Init(void)
{
SERCLK=0; //这里首先把数据位上升沿关闭。
RLCK=0;
}
然后到我们的扫描选项了,这个怎么扫描呢,就是上刚才说的,先 个SER,然后打开SRCLK,写完后就直接给RCLK启动依次循环八次。就是这样
/**
* @brief 74Hc595写入数据函数,把数据写入到点阵实现段选 位选
* @param Byte 十六进制0x00~0xff
* @retval 无
*/
void _74Hc595_writeByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++) //移位在 8421 8421移位 在第一个8开始往左移
{
SER=Byte&(0x80>>i); //如果最高位是1那么就是1 如果最高位是0那么就是0可以用if代替
SERCLK=1;
SERCLK=0;
}
RLCK=1;
RLCK=0;
这个位选好了,那么接下来,就好像刚才说的那种D0跟P0的关系了,我们要先给D0到D7的高电平选择然后根据情况也控制P0到P7这样就可以循环控制扫描了
/**
* @brief LED点阵函数
* @param COlumn 控制列 0~7; Data 写入 0x00~0xff 写1选中 写0不选中;
* @retval 无
*/
void juzhenLED_showNumer(unsigned char Column,Data)
{ //这里是8421码操作1111 1111看着给就行了分别对应左往右的操作
_74Hc595_writeByte(Data); //操作点阵的行8421 8421从上往下数 1选中
MATRIX_LED_PORT=~(0x80>>Column); //操作点阵的列从左往右数,8421 8421 0选中 这里赋值一后取反意思也是赋值0
delay(1); //这里延迟为了防止段选 位选 段选 位选 串位。
MATRIX_LED_PORT=0xff; //所以要加上段选 位选 延迟清零 段选 位选。这样才能达到同时选中多个数据只要延迟的够快,怎么样显示都行
}
那么扫描操作都写好了,就可以直接用了,可以先试着写一下什么效果,写完之后呢,我们就可以字摸软件生成8*8的的字模了,然后我们在主函数里面循环这个字模数组就可以流动字体了。
#include <regx52.h>
sbit SER=P3^4; //用于数据的地址输入
sbit RLCK=P3^5; //当有数据输入的时候这个变1就是有上升沿到来的时候,就把SER的数据并行输出
sbit SERCLK=P3^6; //当这个为1的时候就是把SER的数据移位输出每来一个高电平就输出一个,
#define MATRIX_LED_PORT P0 //这里给共定义方便等下写
unsigned char juzhenLED[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x18,0x24,0x12,0x24,0x18,0x00,0x00,
0x38,0x44,0x22,0x11,0x22,0x44,0x38,0x00,
0x88,0x84,0x42,0x41,0x41,0x42,0x84,0x88,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
int main(void)
{
unsingned char i,set=3,count=0;
juzhenLED_Init();
while(1)
{
for(i=0;i<8;i++)
{
juzhenLED_showNumer(i,juzhenLED[i+set]);
}
count++;
if(count>10)
{
count=0;
set++; //如果要显示动画那么就每一次加8,这样上面数组也是每一帧写一个8*8的图像
if(set>32)
set=0; //防止流动超出产生乱码,这个可以看上的数组的,反正一次显示8个,看着数组的大小最后预留8个就行
}
}
}
/**
* @brief LED点阵函数
* @param COlumn 控制列 0~7; Data 写入 0x00~0xff 写1选中 写0不选中;
* @retval 无
*/
void juzhenLED_showNumer(unsigned char Column,Data)
{ //这里是8421码操作1111 1111看着给就行了分别对应左往右的操作
_74Hc595_writeByte(Data); //操作点阵的行8421 8421从上往下数 1选中
MATRIX_LED_PORT=~(0x80>>Column); //操作点阵的列从左往右数,8421 8421 0选中 这里赋值一后取反意思也是赋值0
delay(1); //这里延迟为了防止段选 位选 段选 位选 串位。
MATRIX_LED_PORT=0xff; //所以要加上段选 位选 延迟清零 段选 位选。这样才能达到同时选中多个数据只要延迟的够快,怎么样显示都行
}
/**
* @brief 74Hc595写入数据函数,把数据写入到点阵实现段选 位选
* @param Byte 十六进制0x00~0xff
* @retval 无
*/
void _74Hc595_writeByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++) //移位在 8421 8421移位 在第一个8开始往左移
{
SER=Byte&(0x80>>i); //如果最高位是1那么就是1 如果最高位是0那么就是0可以用if代替
SERCLK=1;
SERCLK=0;
}
RLCK=1;
RLCK=0;
}
/**
* @brief 矩阵LED初始化
* @param 无
* @retval 无
*/
void juzhenLED_Init(void)
{
SERCLK=0; //这里首先把数据位上升沿关闭。
RLCK=0;
}
大概就是这么多了。这些看着很简单的,可以试着改一下面的参数效果就知道是怎么实现了。
while(1)
{
for(i=0;i<8;i++)
{
juzhenLED_showNumer(i,juzhenLED[i+set]);
}
count++;
if(count>10)
{
count=0;
set++; //如果要显示动画那么就每一次加8,这样上面数组也是每一帧写一个8*8的图像
if(set>32)
set=0; //防止流动超出产生乱码,这个可以看上的数组的,反正一次显示8个,看着数组的大小最后预留8个就行
}
}