这是本文档旧的修订版!


我用两块74HC595级联,第一块的D0-D7依次控制1-8行,第二块的D0-D7依次控制1-8列。8*8点阵屏型号是1088BS,共阳极。
数据手册:

原理图和接线

程序
// 595.h 文件

#ifndef __595_H__
#define __595_H__

sbit SER = P2^0;   // 串行数据输入
sbit RCLK = P2^1;  // (显示) 输出存储器锁存时钟线(上升沿移位寄存器数据进入输出存储寄存器,下降沿输出存储寄存器不变)
sbit SRCLK = P2^2; // (移位) 数据输入时钟线(上升沿移位寄存器数据移位,下降沿移位寄存器数据不变)

void ClearScreen_8x8(void);
void FullScreen_8x8(void);
void ShowImage_8x8(unsigned char word[8]);

#endif
// 595.c 文件

#include <REGX51.H>
#include "595.h"

static unsigned char IT1_Enable = 0; // 是否使能interrupt1,1使能,2失能。

unsigned char TestImage[4][8] =
{
    {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}, // 网格,起始(1,1)亮
    {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}, // 网格,起始(1,1)灭
    {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 单点,只有(1,1)亮
    {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00}, // 只亮最中间4个
};

void ClearScreen_8x8(void)
{
    unsigned char i = 0;
    for(i=0; i<16; i++)
    {
        SER = 0;
        SRCLK = 1;
        SRCLK = 0;
    }
    RCLK = 0;
    RCLK = 1;
    RCLK = 0;
}

void FullScreen_8x8(void)
{
    unsigned char i = 0;
    for(i=0; i<8; i++)
    {
        SER = 0;
        SRCLK = 1;
        SRCLK = 0;
    }
    for(i=0; i<8; i++)
    {
        SER = 1;
        SRCLK = 1;
        SRCLK = 0;
    }
    RCLK = 1;
}

void ShowImage_8x8(unsigned char word[8])
{
    // 经过实际测试,扫描一行用时约600us,即4.8ms一屏,每秒能完整刷屏约208次。
    unsigned char i = 0, j = 0, k = 0;
    for(i=0; i<8; i++) // 行扫描,一次亮一行
    {
        for(j=0; j<8; j++) // 列数据(595芯片后输入的到D7,先输入的到D0)
        {
            SER = ~((bit)(word[i] & (0x80 >> j))); // 列给低是亮,字模是阳模,要取反
            SRCLK = 1;
            SRCLK = 0;
        }
        for(j=0; j<8; j++) // 行数据
        {
            if(j<i || j>i) SER = 0;
            if(j == i) SER = 1;
            SRCLK = 1;
            SRCLK = 0;
        }
        RCLK = 1;
        RCLK = 0;
    }
}
// main.c 文件

#include <REGX51.H>
#include "Delay.h"
#include "Timer.h"
#include "595.h"

unsigned char Ring[5][8] = // 亮“圆环”,从全灭,到中间最小4点,最后到最大。
{
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00},
    {0x00, 0x18, 0x24, 0x42, 0x42, 0x24, 0x18, 0x00},
    {0x18, 0x42, 0x00, 0x81, 0x81, 0x00, 0x42, 0x18},
};

void main() 
{
    Timer0_Init();
    ClearScreen_8x8();
    Delay_ms(10);
    
    while(1) 
    {
        unsigned char i = 0, j = 0;
        for(i=0; i<5; i++)
        {
            for(j=0; j<100; j++) ShowImage_8x8(Ring[i]); // 执行一次(扫描一屏)约4.8ms,100次约500毫秒。
        }
    }
}