首先讲一下用到的扩展芯片:74HC595(扩展IO口但速度变慢了)
RCLK初始为0 赋值1就移到输出缓存了,
如果已经移位7位了(8位数据满了)但还要继续移位==>溢出的那一位会移到QH'
而QH'又连接到另一个74HC595的SER
就像队列(先进先出)
测试一下74HC595这个芯片
原理图:
我们在输出端连接一串LED;
代码:
#include <REGX52.H>
sbit RCK=P3^5; // 右移
sbit SCK=P3^6; // 下移
sbit SER=P3^4; // 数据
void _74HC595_WriteByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SER=Byte&(0x80>>i); //SER非0即1
SCK=1;
SCK=0;
}
RCK=1; // 移到输出口
RCK=0;
}
void main()
{
SCK=0;
RCK=0;
_74HC595_WriteByte(0xAA); // 1010 1010
while(1)
{
}
}
最高位(首先进入的)被Q7输出
效果图:
program1 点阵显示一个笑脸
原理图:
点阵屏的话要自己测试一下高电平和低电平分别接哪个口
元件 | Proteus关键词 |
---|---|
51单片机芯片 | AT89C52 |
74HC595芯片 | 74HC595 |
点阵屏 | MATRIX-8X8-GREEN |
上拉电阻 | RESPACK-8 |
代码:
还是模块化,对应的头文件,防止一下重复定义就可以了
#ifndef ""
#define ""
要声明的函数;//记得加分号
#endif
MatrixLED.c
#include <REGX52.H>
#include "Delay.h"
sbit RCK=P3^5;
sbit SCK=P3^6;
sbit SER=P3^4;
#define MATRIX_LED_PORT P0
/**
* @brief 74HC595写入一个字节
* @param Byte 要写入的字节
* @retval 无
*/
void _74HC595_WriteByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SER=Byte&(0x80>>i); //SER非零即1
SCK=1;
SCK=0;
}
RCK=1; // 移到输出口
RCK=0;
}
/**
* @brief 点阵屏初始化
* @param 无
* @retval 无
*/
void MatrixLED_Init()
{
SCK=0;
RCK=0;
}
/**
* @brief LED点阵屏显示一列数据
* @param Column 要选择的列,范围:0~7,0在最左边
* @param Data 选择列显示的数据,高位在上,1为亮,0为灭
* @retval 无
*/
void MatrixLED_ShowColumn(unsigned char Column,Data)
{
_74HC595_WriteByte(Data);
MATRIX_LED_PORT=~(0x80>>Column);
/*
if(Cloumn==0){P0=~0x80;}
......
*/
Delay(1);//延时
MATRIX_LED_PORT=0xFF;//清零
}
Delay.c
这部分直接应用的之前的代码
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);//i!=0就卡在这
xms--;
}
}
main.c
写入的数据目前时自己计算的
#include <REGX52.H>
#include "MatrixLED.h"
void main()
{
MatrixLED_Init();
while(1)
{
MatrixLED_ShowColumn(0,0x3C);
MatrixLED_ShowColumn(1,0x42);
MatrixLED_ShowColumn(2,0xA9);
MatrixLED_ShowColumn(3,0x85);
MatrixLED_ShowColumn(4,0x85);
MatrixLED_ShowColumn(5,0xA9);
MatrixLED_ShowColumn(6,0x42);
MatrixLED_ShowColumn(7,0x3C);
}
}
效果图:
如果没有延时消影的话显示会有错误。
段选 位选 段选 位选 段选 位选 段选 位选......
即下一个一个位选可能延续上一个(原本两两匹配,但如果没有清零延时,可能第二个段选与第一个位选结合了)
program2:点阵显示动画
我们用到一个取模工具
首先点击基本操作==>新建图像==>画好后点击取模方式==>点击C51格式可以得到16进制数组;
我这里画了一个笑脸和哭脸
代码:
其他的不变
main.c
#include <REGX52.H>
#include "MatrixLED.h"
unsigned char code Animation[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
0x3C,0x42,0xA5,0x89,0x89,0xA5,0x42,0x3C,
0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void main()
{
unsigned char i,Offset=0,Count=0;
MatrixLED_Init();
while(1)
{
for(i=0;i<8;i++)
{
MatrixLED_ShowColumn(i,Animation[i+Offset]);
}
Count++;
while(Count>15)
{
Count=0;
Offset++; //逐帧
//Offset+=8;
if(Offset>32)
{
Offset=0;
}
}
}
}
效果图:
横向移动
第二个动画
main:
这个是一帧一画面
#include <REGX52.H>
#include "MatrixLED.h"
unsigned char code Animation[]={
0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
0x3C,0x42,0xA5,0x89,0x89,0xA5,0x42,0x3C,
0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
};
void main()
{
unsigned char i,Offset=0,Count=0;
MatrixLED_Init();
while(1)
{
for(i=0;i<8;i++)
{
MatrixLED_ShowColumn(i,Animation[i+Offset]);
}
Count++;
while(Count>15)
{
Count=0;
Offset+=8;
if(Offset>16)//数组越界清零
{
Offset=0;
}
}
}
}
效果:
笑脸哭脸来回跳动