感谢 大熙熙 的代码解析
网址 http://www.cnblogs.com/one-meter/p/4188277.html
他对具体的代码做了形象的解释
由于部分代码解析还不够具体 融入了 个人对该代码的理解
网上类似的源码很多, 可以自己找个合适的进行学习和验证
我是参考普中单片机的源码(注释函数太少)
代码如下:
#include <reg52.h>
#include <intrins.h>//重定义 函数变量
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//spi 所使用的 3个管脚 并进行定义
sbit MOSIO =P3^4;
sbit R_CLK =P3^5;
sbit S_CLK =P3^6;
//--点阵显示数组--//
uchar code tab0[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08,
0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,
0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00,
0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00};
//--10字模--//
uchar code tab1[] =
{0, 0, 0, 0, 0, 0, 8, 24, 14, 36, 8, 66, 8, 66, 8, 66,
8, 66, 8, 66, 8, 66, 8, 36, 62, 24, 0, 0, 0, 0, 0, 0};
//--09字模--//
uchar code tab2[] =
{0, 0, 0, 0, 0, 0, 24, 24, 36, 36, 66, 66, 66, 66, 66,
66, 66, 100, 66, 88, 66, 64, 66, 64, 36, 36, 24, 28, 0, 0, 0, 0} ;
//--08字模--//
uchar code tab3[] =
{0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 66, 66, 36,
66, 24, 66, 36, 66, 66, 66, 66, 36, 66, 24, 60, 0, 0, 0, 0};
//--07字模--//
uchar code tab4[] =
{0, 0, 0, 0, 0, 0, 24, 126, 36, 34, 66, 34, 66, 16, 66, 16,
66, 8, 66, 8, 66, 8, 66, 8, 36, 8, 24, 8, 0, 0, 0, 0};
//--06字模--//
uchar code tab5[] =
{0, 0, 0, 0, 0, 0, 24, 56, 36, 36, 66, 2, 66, 2, 66, 26, 66,
38, 66, 66, 66, 66, 66, 66, 36, 36, 24, 24, 0, 0, 0, 0};
//--05字模--//
uchar code tab6[] =
{0, 0, 0, 0, 0, 0, 24, 126, 36, 2, 66, 2, 66, 2, 66, 26, 66,
38, 66, 64, 66, 64, 66, 66, 36, 34, 24, 28, 0, 0, 0, 0};
//--04字模--//
uchar code tab7[] =
{0, 0, 0, 0, 0, 0, 24, 32, 36, 48, 66, 40, 66, 36, 66, 36, 66,
34, 66, 34, 66, 126, 66, 32, 36, 32, 24, 120, 0, 0, 0, 0};
//--03字模--//
uchar code tab8[] =
{0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 32, 66, 24, 66,
32, 66, 64, 66, 64, 66, 66, 36, 34, 24, 28, 0, 0, 0, 0};
//--02字模--//
uchar code tab9[] =
{0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 66, 66, 32, 66,
32, 66, 16, 66, 8, 66, 4, 36, 66, 24, 126, 0, 0, 0, 0};
//--01字模--//
uchar code tab10[] =
{0, 0, 0, 0, 0, 0, 24, 8, 36, 14, 66, 8, 66, 8, 66, 8, 66, 8, 66,
8, 66, 8, 66, 8, 36, 8, 24, 62, 0, 0, 0, 0};
//--00字模--//
uchar code tab11[] =
{0, 0, 0, 0, 0, 0, 24, 24, 36, 36, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 36, 36, 24, 24, 0, 0, 0, 0};
//--GO--//
uchar code tab12[] =
{0, 0, 0, 0, 0, 0, 60, 28, 34, 34, 34, 65, 1, 65, 1, 65, 1, 65, 113,
65, 33, 65, 34, 65, 34, 34, 28, 28, 0, 0, 0, 0};
//全局变量
ulong column; //列
ulong row; //行
ulong dt;
//具体分析 查看 函数实现方法
void HC595_data(uchar BT3,uchar BT2,uchar BT1,uchar BT0);
void main()
{
int k=0;
while(1)
{
//for() this is used by how long
for(k=0;k<16;k++)
{
HC595_data(~tab12[2*k+1],~tab12[2*k],tab0[2*k],tab0[2*k+1]);
}
HC595_data(0xff,0xff,0,0);
}
}
/********************************
BT3 是第2列 。。。。。。。 因此
输入为 列2 列1 行1(值是行2的值) 行2(值是行1的值)
然而 实际不是这样
原因是 74h595 是4个并联的 相当于 8个 8*8
而且只有一个输入 当输入值时 会进行进位操作
可以理解为 压栈
所以变成了 行2(值是行1的值) 行 1 (值是行2的值) 列 2 列 1
**********************************/
void HC595_data(uchar BT3,uchar BT2,uchar BT1,uchar BT0)
{
uchar i;
for(i=0;i<8;i++)
{
MOSIO=BT3>>7; //BT 右移7位 即是得到最高位的值
BT3<<=1; //左移1位 最高为溢出,第7位变成最高位,达到按位输入的功能
S_CLK=0; //开始累加
S_CLK=1; //关闭
}
for(i=0;i<8;i++)
{
MOSIO=BT2>>7; //BT 右移7位 即是得到最高位的值
BT2<<=1; //左移1位 最高为溢出,第7位变成最高位,达到按位输入的功能
S_CLK=0; //开始累加
S_CLK=1; //关闭
}
for(i=0;i<8;i++)
{
MOSIO=BT1>>7; //BT 右移7位 即是得到最高位的值
BT1<<=1; //左移1位 最高为溢出,第7位变成最高位,达到按位输入的功能
S_CLK=0; //开始累加
S_CLK=1; //关闭
}
for(i=0;i<8;i++)
{
MOSIO=BT0>>7; //BT 右移7位 即是得到最高位的值
BT0<<=1; //左移1位 最高为溢出,第7位变成最高位,达到按位输入的功能
S_CLK=0; //开始累加
S_CLK=1; //关闭
}
R_CLK = 0; //set dataline low
R_CLK = 1; //片选
R_CLK = 0; //set dataline low
}