首页 > 编程语言 >【51单片机】程序实验7&8.IO扩展-LED点阵

【51单片机】程序实验7&8.IO扩展-LED点阵

时间:2024-11-30 12:28:50浏览次数:9  
标签:LED u8 芯片 0x00 51 单片机 点阵 SER

主要参考学习资料:B站【普中官方】51单片机手把手教学视频

前置知识:C语言

单片机套装:普中STC51单片机开发板A4标准版套餐7

码字不易,求点赞收藏加关注(´•ω•̥`)

有问题欢迎评论区讨论~

目录

IO扩展-74HC595

外围设备占用的IO口较多,而51单片机提供的IO口非常有限,如果想要连接更多的外围设备,就需要通过扩展IO来实现。这里使用的是74HC595的串转并芯片。

74HC595芯片介绍

74HC95是一个8位串行输入、并行输出的位移缓存器,其中并行输出位三态输出(高电平、低电平和高阻抗)。

Q0~Q7为并行数据输出,Q7’为串行数据输出,DS为串行数据输入。通过串行数据输出连接串行移位输入可以级联多个595芯片,从而实现IO扩展功能。

MR为低电平复位引脚,名称上面一杠说明低电平有效。

SH_CP为移位寄存器的时钟输入,控制移位寄存器一位一位地移动存储数据;ST_CP为存储寄存器的时钟输入,控制移位寄存器中的八位数据一次性全部存储到存储寄存器当中。存储寄存器的输出连接到并行输出口Q0~Q7。

OE为使能引脚,如果该信号为低电平则并行输出口可以输出。

硬件介绍

在51单片机中,595芯片被用于LED点阵。LED点阵的原理与矩阵按键类似,对行共阳、列共阴二极管来说,列线路低电平、行线路高电平时相应的二极管被点亮。

595芯片的两个时钟输入分别连接P35-36引脚,串行输入连接P34引脚,用于接受并行输出的数据。并行输出引脚与LED点阵行线路引脚一一对应。

实验7-1 IO扩展

实现功能:通过72HC595模块控制LED点阵以行为单位循环滚动显示。

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

//定义两个时钟输入和串行输入端口
sbit SRCLK = P3^6;
sbit rCLK = P3^5;
sbit SER = P3^4;

//定义LED点阵端口
#define LED_COL_PORT P0

//存储点亮LED点阵每一行的串行输入数据
u8 ghc595_buf[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

//延时函数
void delay_10us(u16 time)
{
	while(time --);
}

//写入串行输入数据函数
void hc595_write_data(u8 dat)
{
	u8 i = 0;
	for(i = 0;i < 8;i++)
	{
        //移位寄存器从高位到低位依次存储数据
		SER = dat >> 7; //存储最高位
		dat <<= 1; //将数据的次高位移到最高位
        
        //移位寄存器时钟产生上升沿(低电平转高电平瞬间)控制SER写入寄存器
		SRCLK = 0;
		delay_10us(1); //寄存器对传输延时有要求(详见芯片手册),该芯片寄存器延时为纳秒级
		SRCLK = 1;
	}
    //移位寄存器存储完8位数据,存储寄存器时钟产生上升沿控制数据转入存储寄存器
	rCLK = 0;
	delay_10us(1);
	rCLK = 1;
}

void main()
{
	u8 i = 0;
    //LED点阵列线路有下拉电阻默认高电平,需全部设为低电平
	LED_COL_PORT = 0x00;
	while(1)
	{
		for(i = 0;i < 8;i++)
		{
            //将使LED点阵每一行点亮的串行输入数据依次写入芯片
			hc595_write_data(ghc595_buf[i]);
			delay_10us(50000);
		}
	}
}

使用LED点阵需要用黄色跳线帽插在GND和OE上将OE接地,使并行输出口有效。不使用时则插在OE和VCC上。

实验7-2 IO扩展(595级联)

当多个595芯片级联时,数据会以字节为单位从前一个芯片推向后一个芯片。以上图为例,当四个字节的数据存入移位寄存器后,在转入存储寄存器时,最后一个字节在该芯片并行输出,而前三个字节溢出到串行输出口传输到第二个芯片。以此类推,第二个芯片并行输出倒数第二个字节,前两个字节溢出到第三个芯片;第三个芯片并行输出第二个字节,第一个字节溢出到最后一个芯片并行输出。其中前两个芯片分别控制前八行、后八行,后两个芯片分别控制前八列、后八列。

实现功能:通过72HC595模块控制LED点阵以行为单位循环滚动显示。

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit SRCLK = P3^6;
sbit rCLK = P3^5;
sbit SER = P3^4;

//传入四个一字节的参数,按并行输出芯片序号命名,如dat1由第一个芯片并行输出
void hc595_write_data(u8 dat1, u8 dat2, u8 dat3, u8 dat4)
{
	u8 i = 0;
    //输入顺序与输出芯片顺序相反,所以按倒序依次写入四个字节的数据
	for(i = 0;i < 8;i++)
	{
		SER = dat4 >> 7;
		dat4 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat3 >> 7;
		dat3 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat2 >> 7;
		dat2 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat1 >> 7;
		dat1 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    //四个字节的数据都写入移位寄存器后传入存储寄存器
	rCLK = 0;
	delay_10us(1);
	rCLK = 1;
}

void main()
{
	u8 i = 0;
	while(1)
	{
        //先通过第一个芯片遍历1~8行,再通过第二个芯片遍历9~16行,后两个芯片控制所有列线路为低电平
		for(i = 0;i < 8;i++)
		{
			hc595_write_data(ghc595_buf[i], 0, 0, 0);
			delay_10us(50000);
		}
        for(i = 0;i < 8;i++)
		{
			hc595_write_data(0, ghc595_buf[i], 0, 0);
			delay_10us(50000);
		}
	}
}

LED点阵

LED点阵介绍

LED点阵是由发光二极管排列组成的显示器件,被广泛应用于汽车报站器、广告屏等。

LED点阵每一行的阳极并联在一起,每一列的阴极并列在一起,行为高电平、列为低电平的二极管被点亮。硬件结构在上一节已经介绍过。

实验8-1 点亮一个点

实现功能:在点阵屏上点亮一个点,以左上角的点为例。

//main函数之外的程序与实验7-1相同
#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit SRCLK = P3^6;
sbit rCLK = P3^5;
sbit SER = P3^4;

#define LED_COL_PORT P0

void delay_10us(u16 time)
{
	while(time --);
}

void hc595_write_data(u8 dat)
{
	u8 i = 0;
	for(i = 0;i < 8;i++)
	{
		SER = dat >> 7;
		dat <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
	rCLK = 0;
	delay_10us(1);
	rCLK = 1;
}

void main()
{
	LED_COL_PORT = 0x7f; //列线路设为01111111
	while(1)
	{
		hc595_write_data(0x80); //行线路设为10000000
	}
}

实验8-2 显示数字

实现功能:在点阵屏上显示一个数字。

数字、文字等点阵图像较为复杂,可以通过字模提取软件方便地生成点阵数据。

软件界面:

基本操作-新建图像,根据点阵屏大小选择行列数,生成空白点阵:

模拟动画-放大格点:

在点阵上点选需要点亮的点:

参数设置-其他选项,取模方式根据扫描方式选择横向或纵向,横向取模数据为每一行点亮对应列LED的数据,纵向取模数据为每一列点亮对应行LED的数据,字节倒序根据开发板接线顺序按需勾选,输出数据的数位对应点阵上的行和列上高下低、左高右低时不勾选,反之则勾选:

取模方式-C51格式,在点阵生成区生成字模数据。

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit SRCLK = P3^6;
sbit rCLK = P3^5;
sbit SER = P3^4;

#define LED_COL_PORT P0

//控制数字0每一列上哪些行的点被点亮的数据,即纵向取模生成的字模数据
u8 gled_row[8] = {0x00, 0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00};
//控制点阵依次扫描每一列的数据,即被扫描列为低电平,其余为高电平
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};

void delay_10us(u16 time)
{
	while(time --);
}

void hc595_write_data(u8 dat)
{
	u8 i = 0;
	for(i = 0;i < 8;i++)
	{
		SER = dat >> 7;
		dat <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
	rCLK = 0;
	delay_10us(1);
	rCLK = 1;
}

void main()
{
	u8 i = 0;
	while(1)
	{
		for(i = 0;i < 8;i++)
		{
            //扫描相应的列
			LED_COL_PORT = gled_col[i];
            //将该列上的行点亮
			hc595_write_data(gled_row[i]);
			delay_10us(100); //延时控制在人眼视觉暂留范围内
			hc595_write_data(0x00); //消隐
		}
	}
}

实验8-3 显示数字(595级联)

本实验采用横向取模。8×8点阵上面对应595芯片并行输出的高位,下面对应低位,而16×16点阵上面为低位,下面为高位,因此勾选字节倒序,取模参数如下:

当对16×16点阵横向取模时,取模软件对每一行先取前八列数据为一个字节,再取后八列数据为一个字节,从上往下,得到取模结果:

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit SRCLK = P3^6;
sbit rCLK = P3^5;
sbit SER = P3^4;

//控制数字0每一行上哪些列的点被点亮的数据,即横向取模生成的字模数据
//根据取模顺序可知,奇数位的数据对应前八列,传给第三个芯片,偶数位的数据对应后八列,传给第四个芯片
//取模的规则为高电平点亮、低电平不点亮,这与列线路点亮规则相反,因此后续使用要取反
u8 gled_col[32] =
{0x00, 0x00, 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, 0x04, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x10,
 0x04, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, 0x00, 0x00}
//控制点阵依次扫描每一行的数据
//我们将前两个芯片的数据写在一个数组里,前十六个传给第一个芯片,后十六个传给第二个芯片
//扫描前八列时,对应后八列的第二个芯片全为0x00;扫描后八列时,对应前八列的第一个芯片全为0x00
u8 gled_row[32] =
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,}

void hc595_write_data(u8 dat1, u8 dat2, u8 dat3, u8 dat4)
{
	u8 i = 0;
	for(i = 0;i < 8;i++)
	{
		SER = dat4 >> 7;
		dat4 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat3 >> 7;
		dat3 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat2 >> 7;
		dat2 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
    for(i = 0;i < 8;i++)
	{
		SER = dat1 >> 7;
		dat1 <<= 1;
		SRCLK = 0;
		delay_10us(1);
		SRCLK = 1;
	}
	rCLK = 0;
	delay_10us(1);
	rCLK = 1;
}

void main()
{
	u8 i = 0;
	while(1)
	{
        //依次扫描每一行点亮对应列的数据,对参数的详细解释见定义数组的注释
		for(i = 0;i < 16;i++)
		{
			hc595_write_data(gled_row[i], gled_row[i + 16], ~gled_col[i * 2], ~gled_col[i * 2 + 1]);
			delay_10us(10); //由于传输四个字节的数据的延时较长,所以这里延时较短
		}
	}
}

本篇完

标签:LED,u8,芯片,0x00,51,单片机,点阵,SER
From: https://blog.csdn.net/mojin2005/article/details/144087356

相关文章

  • [C++][CMake][Error] set_target_properties called with incorrect number of argume
    1简介这篇文章将探讨了在使用CMake构建C++项目时,调用set_target_properties函数时参数数量不正确所引发的问题。2错误案例以下为可能发生错误的案例include_directories(${CMAKE_SOURCE_DIR}/common)find_package(Threads)add_library(libusbmuxdSHAREDlibusbm......
  • Qt运行生成的exe报错“This application failed to start because no Qt platform plu
    Qt运行生成的exe报错“ThisapplicationfailedtostartbecausenoQtplatformplugincouldbeinitialized.Reinstallingtheapplicationmayfixthisproblem.”报错复现将exe复制一份至单独文件夹中,直接运行会发现报错缺少一些dll去Qt根目录D:\QT\Qt\5.15.0\mingw8......
  • 【每日一题】3251. 单调数组对的数目 II
      给你一个长度为 n 的 正 整数数组 nums 。如果两个 非负 整数数组 (arr1,arr2) 满足以下条件,我们称它们是 单调 数组对:两个数组的长度都是 n 。arr1 是单调 非递减 的,换句话说 arr1[0]<=arr1[1]<=...<=arr1[n-1] 。arr2 是单调 非递增 ......
  • 【纯干货分享】计算机毕业设计必看必学36113+PHP 高校成绩管理系统原创的定制程序,单
     高校成绩管理系统的设计与实现摘 要随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用PHP技术建设高校成绩管理系统。本设计主要实现集人性化、高效......
  • 【纯干货分享】计算机毕业设计必看必学(44127+spark 手机销售数据的可视化分析系统)原创
    spark手机销售数据的可视化分析系统摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对手机销售数据管理等问题,对手机销售数据管理进行研究分......
  • 【纯干货分享】计算机毕业设计必看必学30973+springboot 个人健康管理系统小程序原创
    摘 要随着中国经济的飞速增长,消费者的智能化水平不断提高,许多智能手机和相关的软件正在得到更多的关注和支持。其中,微信小程序的个人健康管理系统更是深得消费者的喜爱,它的出现极大地改善了消费者的生活质量,同时,它还创造了一种快捷、有效的数据信息管理网络平台,让消费者更......
  • STM32单片机学习记录(11.29)
    一、STM32    6.4-PWM驱动程序        1.PWM基本结构:运行控制——时基单元——输出比较单元——GPIO。        2.PWM程序编写步骤:        (1)RCC开启时钟,将要用的TIM外设和GPIO外设的时钟打开;      ......
  • POJ1251-Jungle Roads
    开始刷邝斌飞最小生成树专题POJ1251HDU1301可用平台就刷AC人数300+的那四个题     ###:好饿,好冷,好累,腿好软,感觉有点虚脱了。已经不知道是第几次饿的走不回去了肚子里面感觉有点恶心。去,好饿啊。好想去8点半吃个泡面,吃个干拌面,但是那玩意儿根本就吃不饱。死贵死......
  • 2025蓝桥杯(单片机)备赛--扩展外设之PWM的原理与应用(十三)
    1PWM原理        PWM:该方法未使用常规的PWM相关的寄存器配置;而是使用了定时器2;与这个类似。周期:通过定时器2设置每次进中断的间隔,来设置最小周期(步进),如设置100us,这时PWM的最小周期为100us,最大频率为1/100us;可通过设置一个变量进行累加,当该变量的值达到一定......
  • 力扣刷题——3251. 单调数组对的数目 II
    考虑arr1可以取到的数字组合数,从0到i+1位置的合法的arr1组合数,可以从0到i的组合数得到。因此可以想到用动态规划解决问题,使用一个数组dp[i][j]代表arr1[i]=j时,前i+1个数字有多少个组合。这样一来,最终的答案即为sum(dp[n-1][0...M],其中M为nums中最大值。根据这个思路写出一个简......