51单片机【点阵屏】
51单片机【点阵屏】
我们有一个8*8的点阵屏,里面是64个发光二极管。
二极管的阳极我们给它接了74HC595的八个输出引脚,阴极接P00-P07引脚。
74HC595的八个引脚控制八个行,P00-P07控制八个列,行为1,列为0 对应的那个LED灯会亮,其他的组合不行。
如何让74HC595的八个输出引脚输出不同的值,我们需要查看手册。
查看手册得知:这个芯片对我们有用的输入管脚有三个,一个SCK当它下降沿时使得移位寄存器右移一位,一个RCK当它下降沿时将移位锁存器里的值放到存储寄存器并输出到引脚上,一个SER将每次右移后前面缺出的位置补上它。移位前,移位寄存器每位都是0,通过SER给它加上1。
我们的板子上,P34控制SCK,P35控制RCK,P36控制SER。
我们想要在点阵屏绘制一幅图片,我们需要定义三个函数,一个初始化,一个写显存(这里的显存是个数组,接收外部传过来的,一个元素为一行的点亮的灯),最后一个函数是让通过595芯片的两个下降沿一行一行地控制,每一行有效时,把对应的显存赋给P0,就能让对应的亮起来。如果想使用回调函数,则每行一毫米刷新。以下是用定时器实现的代码。
#include "Int_LedMatrix.h"
// 移位寄存器时钟(上升沿有效,右移)
#define SCK P34
// 数据寄存器时钟
#define RCK P35
// IO线,补的位
#define SER P36
static u8 s_buffer[8] = 0;
static u8 s_pc = 0;
void LedMatrix_Init()
{
SCK = 0;
RCK = 0;
SER = 1;
}
void LedMatrix_SetPic(u8 *pic)
{
u16 i;
for (i = 0; i < 8; i++) {
s_buffer[i] = pic[i];
}
}
void LedMatrix_Refresh()
{
s_pc = s_pc>=8 ? SER=1, 0 : s_pc;
// 列引脚
P0 = 0xff;
// 上升沿
SCK = 1;
RCK = 1;
// 列引脚
P0 = ~s_buffer[s_pc++];
// Delay1ms(1);
// 关掉补位1
SER = 0;
//
SCK = 0;
RCK = 0;
}
// 主函数
#include "Int_LedMatrix.h"
// 下面的两个数组可以合并为一个,就是每次+8
// 这个没有实现什么效果,一个乱的图
static u8 s_pic[] = {1, 2, 4, 8, 16, 32, 64, 128};
static u8 s_pic1[] = {2, 12, 34, 58, 166, 372, 694, 1028};
void main() {
LedMatrix_Init();
// LedMatrix_SetPic(s_pic);
Dri_Timer0_Init();
Dri_Timer0_RegisterCallback(LedMatrix_Refresh);
while(1){
LedMatrix_SetPic(s_pic);
Delay1ms(500);
LedMatrix_SetPic(s_pic1);
Delay1ms(200);
}
}
如果一个数组里每8个是一个图,想让它流动起来,可以定义函数,让它从第六行图赋给第七行,第五行图赋给第四行...... 第0行补传过来的值,这个传过来的值就是数组(这个数组是main中的数组,不是显存)的下一个元素,这样的话,刚开始屏幕为0(显存就为0),也可以从第一行数组的第一个往下刷,刷完一次后,可以再刷几次空行,然后重复(这个重复是指主函数中的while(1)。)代码略。