嵌入式开发学习(STC51-9-led点阵)
内容
点亮一个点;
显示数字;
显示图像;
LED点阵简介
LED 点阵是由发光二极管排列组成的显示器件
通常应用较多的是8 * 8点阵,然后使用多个8 * 8点阵可组成不同分辨率的LED点阵显示屏,比如16 * 16点阵可以使用4个8 * 8点阵构成;因此理解了8 * 8LED点阵的工作原理,其他分辨率的LED点阵显示屏都是一样的;
8 * 8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮;
原理图

由图可知,点亮一个点,只需让对应行输出高电平,对应列输出低电平即可;
点亮一个点
思路
第一列置低电平,第一行置高电平;
编码
main.c
/** @Description: 点亮一个点*/
#include "reg52.h"typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入#define LEDDZ_COL_PORT P0 // 点阵列控制端口/*** @description: 延时函数(循环一次大约10us)* @param {u16} ten_us* @return {*}*/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*** @description: 延时函数(循环一次大约1ms)* @param {u16} ms* @return {*}*/
void delay_ms(u16 ms)
{u16 i, j;for (i = ms; i > 0; i--)for (j = 110; j > 0; j--);
}/*** @description: 向74HC595写入一个字节的数据* @param {u8} dat 要写入的数据* @return {*}*/
void hc595_write_data(u8 dat)
{u8 i = 0;for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中{SER = dat >> 7; // 优先传输一个字节中的高位dat <<= 1; // 将低位移动到高位SCK = 0;delay_10us(1);SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中delay_10us(1);}RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出delay_10us(1);RCK = 0;
}void main()
{u8 i = 0;LEDDZ_COL_PORT = 0x7f; // 将LED点阵左边第一列设置为0,即LED阴极为低电平,其余列为1,即高电平while (1){hc595_write_data(0x80); // 将LED点阵上边第一行设置为1,即LED阳极为高电平,其余行为0,即低电平}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
(注意把LED点阵旁的J24黄色跳线帽短接到GND一端)
结果:led点阵第一个点被点亮

显示数字
思路
利用动态扫描的思想,只要使两个点被点亮间隔不超过24ms,那么点看起来就像连续点亮一样;
把我们想要显示的数字在8 * 8点阵里用每个点表示出来(推荐使用文字取模软件)
循环扫描8行(每次让一行为1,其余行为0),显示每行需要点亮的点(行扫描法)
编码
main.c
/** @Description: 显示数字*/
#include "reg52.h"typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入#define LEDDZ_COL_PORT P0 // 点阵列控制端口u8 gled_row[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; // LED点阵显示数字6的行数据
u8 gled_col[8] = {0xff, 0x83, 0xbf, 0xbf, 0x83, 0xbb, 0xbb, 0x83}; // LED点阵显示数字6的列数据/*** @description: 延时函数(循环一次大约10us)* @param {u16} ten_us* @return {*}*/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*** @description: 延时函数(循环一次大约1ms)* @param {u16} ms* @return {*}*/
void delay_ms(u16 ms)
{u16 i, j;for (i = ms; i > 0; i--)for (j = 110; j > 0; j--);
}/*** @description: 向74HC595写入一个字节的数据* @param {u8} dat 要写入的数据* @return {*}*/
void hc595_write_data(u8 dat)
{u8 i = 0;for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中{SER = dat >> 7; // 优先传输一个字节中的高位dat <<= 1; // 将低位移动到高位SCK = 0;delay_10us(1);SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中delay_10us(1);}RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出delay_10us(1);RCK = 0;
}void main()
{u8 i = 0;while (1){for (i = 0; i < 8; i++) // 循环8次扫描8行、列{hc595_write_data(gled_row[i]); // 传送行选数据LEDDZ_COL_PORT = gled_col[i]; // 传送列选数据delay_10us(100); // 延时一段时间,等待显示稳定hc595_write_data(0x00); // 消影}}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
结果:显示数字6

显示图像
思路
与显示数字相同,但是我们这里用列扫描法;
编码
main.c
/** @Description: 显示图像*/
#include "reg52.h"typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入#define LEDDZ_COL_PORT P0 // 点阵列控制端口u8 gled_row[8] = {0x38, 0x7C, 0x7E, 0x3F, 0x3F, 0x7E, 0x7C, 0x38}; // LED点阵显示数字6的行数据
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // LED点阵显示数字6的列数据/*** @description: 延时函数(循环一次大约10us)* @param {u16} ten_us* @return {*}*/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*** @description: 延时函数(循环一次大约1ms)* @param {u16} ms* @return {*}*/
void delay_ms(u16 ms)
{u16 i, j;for (i = ms; i > 0; i--)for (j = 110; j > 0; j--);
}/*** @description: 向74HC595写入一个字节的数据* @param {u8} dat 要写入的数据* @return {*}*/
void hc595_write_data(u8 dat)
{u8 i = 0;for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中{SER = dat >> 7; // 优先传输一个字节中的高位dat <<= 1; // 将低位移动到高位SCK = 0;delay_10us(1);SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中delay_10us(1);}RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出delay_10us(1);RCK = 0;
}void main()
{u8 i = 0;while (1){for (i = 0; i < 8; i++) // 循环8次扫描8行、列{LEDDZ_COL_PORT = gled_col[i]; // 传送列选数据hc595_write_data(gled_row[i]); // 传送行选数据delay_10us(100); // 延时一段时间,等待显示稳定hc595_write_data(0x00); // 消影}}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
结果:显示一个爱心

相关文章:
嵌入式开发学习(STC51-9-led点阵)
内容 点亮一个点; 显示数字; 显示图像; LED点阵简介 LED 点阵是由发光二极管排列组成的显示器件 通常应用较多的是8 * 8点阵,然后使用多个8 * 8点阵可组成不同分辨率的LED点阵显示屏,比如16 * 16点阵可以使用4个8 *…...
RedisTemplate.opsForZSet()用法简介并举例
RedisTemplate.opsForZSet()是RedisTemplate类提供的用于操作ZSet类型(有序集合)的方法。它可以用于对Redis中的ZSet数据结构进行各种操作,如添加成员、获取成员、删除成员等。 下面是一些常用的RedisTemplate.opsForZSet()方法及其用法示例…...
Java个人博客系统--基于Springboot的设计与实现
目录 一、项目概述 应用技术 接口实现: 数据库定义: 数据库建表: 博客表数据库相关操作: 添加项⽬公共模块 加密MD5 页面展示:http://121.41.168.121:8080/blog_login.html 项目源码:https://gitee…...
在jupyter中下载数据集失败及解决方法(以IMDB为例)
在IMDB数据集下载时,由于网络原因下载失败,报错如下: Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz ConnectionResetError Traceback (most recent call last) … Exception: URL fetch f…...
【设计模式】-工厂方法模式
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它通过定义一个用于创建对象的接口,但是将具体对象的创建推迟到子类中。这样,子类可以决定要实例化的对象类型。工厂方法模式提供了一种方式,通…...
H7-TOOL的高速DAPLINK用于新版STM32CubeIDE V1.13及其以上版本的超简单实现方法(2023-08-08)
之前分享了一个方法,太繁琐了,H7-TOOL群的群友提供了一个方法,实现非常简单。1、使用STM32CubeMX或者自己创建一个STM32CubeIDE工程后,设置这两个地方即可: 配置调试器,设置完毕记得点击右下角的Apply 2、然…...
成功解决ubuntu-22.04的sudo apt-get update一直卡在【0% [Waiting for headers]】
成功解决ubuntu-22.04的sudo apt-get update一直卡在【0% [Waiting for headers]】 问题描述解决方案 问题描述 在下载安装包的时候一直卡在0% [Waiting for headers],报错信息如下: Get:1 file:/var/cudnn-local-repo-ubuntu1804-8.5.0.96 InRelease […...
openLayers实战(一):vue项目中的离线地图引入
最近的项目涉及到离线地图的操作,查阅社区文章,决定使用openLayersvue离线地图的方式进行开发,前期基础引入操作完全参考掘金文章,非常优秀全面的文章。 openlayers 实战离线地图 - 掘金 此外,开发过程的地图操作可参考…...
如何构造一个安全的单例?
为什么要问这个问题? 我们知道,单例是一种很常用的设计模式,主要作用就是节省系统资源,让对象在服务器中只有一份。但是实际开发中可能有很多人压根没有写过单例这种模式,只是看过或者为了面试去写写demo熟悉一下。那…...
单片机开发 esp8266
一、固件界面 二、项目介绍 固件名称:esp8266-universalboard v1.0 提供商: 半条虫(466814195) 下载:esp8266-universalboard.bin 源码地址:Gitlab...
Linux 查看版本和用户权限提升实践心得
文章目录 linux (Ubuntu内核)查看版本版本信息解释内置yum工具?用户权限提升操作步骤 查看deepin系统的版本和其debian的版本遇到的问题:deepin-release文件不存在 linux (Ubuntu内核)查看版本 使用lsb_release命令: lsb_release -a该命令将…...
多线程编程5:线程同步和进程通信(C++11和linux)
常见的线程同步 linux: 互斥锁:实现共享资源的串行访问,有三个版本普通锁(默认属性),检错锁(可以防止相同线程重复加锁)和递归锁(相同线程可以重复加锁)条件变量:配合互斥锁使用,实现线程之间的通信&#…...
tensorrt官方int8量化方法汇总
原理及操作 量化的基本原理及流程可参看懂你的神经网络量化教程:第一讲、量化番外篇、TensorRT中的INT8、tensorRT int8量化示例代码 Tensorrt 方式1:trtexec(PTQ的一种) int8量化 trtexec --onnxXX.onnx --saveEnginemodel.…...
21、p6spy输出执行SQL日志
文章目录 1、背景2、简介3、接入3.1、 引入依赖3.2、修改database参数:3.3、 创建P6SpyLogger类,自定义日志格式3.4、添加spy.properties3.5、 输出样例 4、补充4.1、参数说明 1、背景 在开发的过程中,总希望方法执行完了可以看到完整是sql语…...
实力认证!TDengine 入选 Gartner 中国数据分析与人工智能技术成熟度曲线
近日,国际权威研究机构 Gartner 发布了《2023 年中国数据分析及人工智能技术成熟度曲线》(即《Hype Cycle for Data, Analytics and AI in China, 2023》)报告,TDengine 成功入选实时数据管理领域代表产品。 作为评估全球新技术成…...
如何将jar包部署到宝塔
尝试多种方式上传,但启动一直失败,这种方式亲测是好使的 项目内修改位置 在pom.xml文件中将mysql的scope改成provided,如果是固定的版本号会出现问题 之后就可以打包啦,直接点击maven中的package 找到打包文件的位置ÿ…...
el-tree-select那些事
下拉菜单树形选择器 用于记录工作及日常学习涉及到的一些需求和问题 vue3 el-tree-select那些事 1、获取el-tree-select选中的任意层级的节点对象 1、获取el-tree-select选中的任意层级的节点对象 1-1数据集 1-2画面 1-3代码 1-3-1画面代码 <el-tree-selectv-model"s…...
分布式任务调度框架之开山鼻祖:Quartz
1.简介 最近我司上线使用了分布式任务调度框架:XXL-JOB,方便对任务的管理控制。本来一开始就想讲述一下该框架,但是在学习了解过程中发现该框架式基于Quartz思想开发实现的,Quartz 是一个很火的开源任务调度框架,完全…...
Django实现音乐网站 ⑺
使用Python Django框架制作一个音乐网站, 本篇主要是后台对歌手原有实现功能的基础上进行优化处理。 目录 新增编辑 表字段名称修改 隐藏单曲、专辑数 姓名首字母 安装xpinyin 获取姓名首字母 重写保存方法 列表显示 图片显示处理 引入函数 路径改为显示…...
PO、DTO和VO的区别
PO:Persistence Object,是持久化对象,也叫实体对象(Entity),是对象到关系表的映射。在关系型数据库中,每张表对应着一个PO,PO 中的属性值与表中数据一一对应,通过数据访问…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
