51单片机——8*8LED点阵
LED 点阵的行则为发光二极管的阳极,LED 点阵的列则为发光二极管的阴极
根据 LED 发光二极管导通原理,当阳极为高电平,阴极为低电平则点亮,否则熄灭。
因此通过单片机P0口可控制点阵列,74HC595可控制点阵行
11 脚 SRCLK( SHCP):移位寄存器时钟输入
12 脚 RCLK( STCP):存储寄存器时钟输入
14 脚 SER( DS):串行数据输入
74HC595 需要用到的控制管脚SER、RCLK、SRCLK直接连接到 51 单片机的P3.4-P3.6 IO 口上
1、IO扩展(串转并)-74HC595芯片
要实现的功能是:通过 74HC595 模块控制 LED 点阵以一行循环滚动显示
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
void delay_10us(u16 ten_us){
while(ten_us--);
}
//595管脚
sbit SRCLK=P3^6; //移位寄存器
sbit RCLK1=P3^5; //存储寄存器
sbit SER=P3^4; //串行数据输入
//8*8点阵P0口
#define LEDDZ_COL_PORT P0
//8*8点阵控制口,横向,向595中传数据
u16 hc_595_buf[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //行
void hc595_write_date(u16 dat){
u16 i=0;//位移
for(i=0;i<8;i++){
//要求:从高位开始传
SER=dat>>7;
dat<<=1; //dat=dat<<1;把次高位移到了最高位//移位寄存器时钟上升沿将端口数据送入寄存器中
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);
}//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
//并行输出,数据寄存器
RCLK1=0;
delay_10us(1);
RCLK1=1;
}
void main(){
u16 i=0;
LEDDZ_COL_PORT=0x00; //列值全部都是低电平,P0口可控制点阵列
while(1){
for(i=0;i<8;i++){
hc595_write_date(hc_595_buf[i]); //74HC595可控制点阵行
delay_10us(50000);
}
}
}
注意事项:LED 点阵旁的J24黄色跳线帽短接到GND一端
2、LED点阵实验
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay(u16 time){
while(time--);
}
//定义595控制管脚
sbit srclk=P3^6; //移位寄存器
sbit rclk=P3^5; //存储寄存器
sbit ser=P3^4; //串行数据输入
//P0口
#define LEDDZ_PORT P0
//LED点阵,行,取模
gled_row[]={0x49,0x52,0x7C,0x52,0x49,0x7F,0x00,0x00};
//LED点阵,列,自己对P0口赋值
gled_col[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //第一列-第八列
//往595中写数据
void hc595_write_data(u8 dat){
u16 i=0;
for(i=0;i<8;i++){
ser=dat>>7; //优先传最高位
dat<<=1; //次高位移到最高位
srclk=0;
delay(1);
srclk=1;
delay(1);
}
rclk=1;
delay(1);
rclk=0;
}
void main(){
u16 i=0;
while(1){
for(i=0;i<8;i++){
LEDDZ_PORT=gled_col[i]; //P0口可控制点阵列
hc595_write_data(gled_row[i]); //74HC595可控制点阵行
delay(10); //等待显示稳定
hc595_write_data(0x00); //消隐或消影
}
}
}
3、 流动LED点阵实验
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay(u16 time){
while(time--);
}
//定义595控制管脚
sbit srclk=P3^6; //移位寄存器
sbit rclk=P3^5; //存储寄存器
sbit ser=P3^4; //串行数据输入
//P0口
#define LEDDZ_PORT P0
//LED点阵,行,取模
//gled_row[]={0x49,0x52,0x7C,0x52,0x49,0x7F,0x00,0x00};
gled_row[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x10,0x10,0x7E,0x00,0x7E,0x10,0x10,0x7E,0x00,0x7E,0x10,0x10,0x7E,0x00,0x4A,0xFE,0x22,0x00,0x20,0x04,0x79,
0x4C,0x50,0x00,0x00,0x2C,0x04,0x51,0x0E,0x06,0x48,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00}; //前后16个0x00是为了使两次流水灯不连在一起,中间为要流动的图形(4*8长)
//LED点阵,列,自己对P0口赋值
gled_col[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
//往595中写数据
void hc595_write_data(u8 dat){
u16 i=0;
for(i=0;i<8;i++){
ser=dat>>7; //优先传最高位
dat<<=1; //次高位移到最高位
srclk=0;
delay(1);
srclk=1;
delay(1);
}
rclk=1;
delay(1);
rclk=0;
}
void main(){
u16 i=0;
u16 offset=0; //偏移量
u16 count=0;
while(1){
for(i=0;i<8;i++){
LEDDZ_PORT=gled_col[i];
hc595_write_data(gled_row[i+offset]);
delay(10); //等待显示稳定
hc595_write_data(0x00); //消隐或消影
}
count++;
if(count>10){
count=0;
offset++;
}
if(offset>40){
offset=0;
}
}
}