嵌入式进阶——数码管2

🎬 秋野酱:《个人主页》
🔥 个人专栏:《Java专栏》《Python专栏》

⛺️心若有所向往,何惧道阻且长

文章目录

    • 驱动封装
    • 封装的一些疑问
    • 数字走马灯实现
    • 扩展知识

驱动封装

根据前面的内容可以将代码进行封装,封装后作为一个独立的整体出现:

#ifndef __NIXIE_H__
#define __NIXIE_H__

#include "config.h"

#define	NIXIE_DI	P44	// 数据输入
#define	NIXIE_SCK	P42	// 移位寄存器
#define	NIXIE_RCK	P43	// 锁存寄存器

#define NIXIE_PIN_INIT() {    P4M0 &= ~0x1c; P4M1 &= ~0x1c; }

void NIXIE_init();

// 		u8 a_dat = 0x12;	// 0001 0010	字母位
//		u8 b_idx = 0x1F;	// 0001 1111	数字位
void NIXIE_show(u8 a_dat, u8 b_idx);

// num对应数字在数组里的位置(索引)
// id 显示在指定位置(0 -> 7)
void NIXIE_display(u8 num, u8 id);

#endif

● 定义 NIXIE_init() 函数,负责对GPIO相关的初始化
● 定义 NIXIE_display()函数负责显示

#include "NIXIE.h"
#include "Delay.h"

#define GET_BIT_VAL(byte, pos)	(byte & (1 << pos))

//#define NOP_TIME() NOP40()	// 用于看logic分析仪
#define NOP_TIME() NOP2()

// 锁存操作 - 多行宏定义
#define RCK_ACTION() 		\
		NIXIE_RCK = 0;		\
		NOP_TIME();			\
		NIXIE_RCK = 1;		\
		NOP_TIME();

void NIXIE_init(){
	NIXIE_PIN_INIT();
}


static void NIXIE_out(u8 dat){
		char i;
		// 8bit,先发出去的会作为高位
		for(i = 7; i >= 0; i--){            
			NIXIE_DI = GET_BIT_VAL(dat, i);
			// 寄存器的移位操作
			NIXIE_SCK = 0;
			NOP_TIME(); // 休眠一会儿
			NIXIE_SCK = 1;
			NOP_TIME(); // 休眠一会儿
		}
}

// 每次可以显示多个,但是内容都是一样的a_dat
// 		u8 a_dat = 0x12;	// 0001 0010	字母位
//		u8 b_idx = 0x1F;	// 0001 1111	数字位
void NIXIE_show(u8 a_dat, u8 b_idx){
	
		// 显示 7.
		// 0111 1000
		// 先发字母位 (控制显示的内容)	// 0点亮
		// 8bit,先发出去的会作为高位
		NIXIE_out(a_dat);
	
		// 0,1,2,3....7
		// 再发数字位 (控制显示哪几个) // 只要不是0,就是高电平
		// 1111 1011
		// 7.7.空7. 7.7.7.7.  -------------------与二级制是反向
		// 8bit,先发出去的会作为高位
		NIXIE_out(b_idx);
		
		// 锁存操作
		RCK_ACTION();
		
}

以上为Nixie.h的实现,也是对之前代码的封装处理。

#include "Config.h"
#include "NIXIE.h"
#include "Delay.h"

int main() {
    u8 a_dat = 0xF8;	// 0001 0010	字母位
    u8 b_idx = 0xFB;	// 0001 1111	数字位

    NIXIE_init();

	// NIXIE_show写到循环外边即可
	NIXIE_show(a_dat, b_idx);
    while(1) {
    }
}

封装的一些疑问

封装的特点
封装是面向对象程序设计中的一个重要概念,它将数据和行为封装在一起,形成一个独立的单元。下面是封装的特点:

  1. 数据隐藏:封装可以隐藏数据,只对外界公开必要的接口,从而保证数据的安全性和可靠性。
  2. 接口统一:封装可以将数据和行为组织在一起,形成一个类或对象,通过统一的接口对外提供服务,便于使用和管理。
  3. 信息隐藏:封装可以隐藏实现细节,只对外界公开必要的信息,从而降低了程序的复杂度和耦合度,提高了程序的可维护性和可扩展性。
  4. 可重用性:封装可以将数据和行为封装成一个独立的单元,便于复用和重复利用,提高了程序的开发效率和代码的可重用性。
  5. 封装和继承相结合:封装和继承是面向对象程序设计中的两个重要概念,它们相互配合,可以构建出更加复杂、灵活和可扩展的程序。
    总之,封装是面向对象程序设计的核心思想之一,它可以提高程序的可靠性、安全性、可维护性和可扩展性,是程序设计中不可或缺的重要概念。
    当前设计问题
    接口设计:定义初始化(Nixie_init),和具体功能(Nixie_display),初始化和芯片开发板设计相关,功能的定义和业务相关。
    初始化问题:为什么不用库函数?首先是可以使用库函数的。观察使用库函数和不是库函数的区别。一个初始化写在头文件,一个写在c文件。c文件是实现,做到抛开平台相关是最好的方案,也就是换了芯片平台,实现不动,通过改变头中的配置,就可以做到移植。(当然,理想状态是这样的,还得看实现复杂度。目标明确,尽量做到这个,为移植提供最少变化方案,这个是共识)
// 索引对应表格参见:
// https://www.yuque.com/icheima/stc8h/kmz2mllvxs1uvdfy#lLhhp
u8 code LED_TABLE[] = 
{
	// 0 	1	 2	-> 9	(索引012...9)
	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
	// 0. 1. 2. -> 9.	(索引10,11,12....19)
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,
	// . -						(索引20,21)
	0x7F, 0xBF,
	// AbCdEFHJLPqU		(索引22,23,24....33)
	0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xF1,0xC7,0x8C,0x98,0xC1
};

// 每次只显示一个
// 	\arg num 对应数字在数组里的位置(索引)
//  \arg id 显示在指定位置(0 -> 7)
void NIXIE_display(u8 num, u8 id){
	u8 a_dat = LED_TABLE[num];	// 0001 0010	字母位
	u8 b_idx = 1 << id;					// 0010 0000	数字位 5
	
	NIXIE_show(a_dat, b_idx);
}

● index在没有封装前,一个bit表示一个灯。封装后表示灯的下标。这样设计符合人的思考习惯,函数就是让人调得舒服
● dat在没有封装前,是自己来总结灯的开灭,封装后表示自己定义的字符,通过下标访问。这样简化操作。还是为了调用舒服。

数字走马灯实现

#include "Config.h"
#include "NIXIE.h"
#include "Delay.h"


int main() {
    u8 i;
    // u8 a_dat = 0xF8;	// 0001 0010	字母位
    // u8 b_idx = 0xFB;	// 0001 1111	数字位

    NIXIE_init();

    // NIXIE_show写到循环外边即可
    // NIXIE_show(a_dat, b_idx);

    while(1) {		
        // 1000 / (2 * 8) = 62.5帧/秒
        // 走马灯
        for(i = 0; i < 8; i++) {
            NIXIE_display(i + 1, i);
            delay_ms(100);
        }
    }
}

扩展知识

原理图中,大部分引脚我们已经知道了,但是还有些引脚功能不清楚。
● RESET: 10号引脚。
● OUTPUT_ENABLE: 13号引脚。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/646544.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter仿照微信实现九宫格头像

一、效果图 2、主要代码 import dart:io; import dart:math;import package:cached_network_image/cached_network_image.dart; import package:flutter/material.dart;class ImageGrid extends StatelessWidget {final List<String> imageUrls; // 假设这是你的图片URL…

山东大学软件学院数据库实验1-9(全部)

目录 前言 实验代码 实验一 1-1 1-2 1-3 1-4 1-5 1-6 实验二 2-1 2-2 2-3 2-4 2-5 2-6 2-7 2-8 2-9 2-10 实验三 3-1 3-2 3-3 3-4 3-5 3-6 3-7 3-8 3-9 3-10 实验四 4-1 4-2 4-3 4-4 4-5 4-6 4-7 4-8 4-9 4-10 实验五 5-1…

代码随想录算法训练营第三十六天 | 1005.K次取反后最大化的数组和、134.加油站、135.分发糖果

目录 1005.K次取反后最大化的数组和 思路 代码 代码 134.加油站 思路 代码 135.分发糖果 思路 代码 1005.K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有思路。 代码随想录 思路 直觉&#xff0c;直接写&…

<学习笔记>从零开始自学Python-之-实用库篇(一)-pyscript

由Anaconda创建的PyScript是一项实验性的但很有前途的新技术&#xff0c;它使python运转时在支撑WebAssembly的浏览器中作为一种脚本言语运用。 每个现代常用的浏览器现在都支撑WebAssembly&#xff0c;这是许多言语&#xff08;如C、C和Rust&#xff09;能够编译的高速运转时…

K8S/ hpa分享

在 Kubernetes 中&#xff0c;HorizontalPodAutoscaler 自动更新工作负载资源 &#xff08;例如 Deployment 或者 StatefulSet&#xff09;&#xff0c; 目的是自动扩缩工作负载以满足需求。 hpa的使用本身还是很简单的 示例如下&#xff1a; 官网示例 apiVersion: apps/v1 k…

基础—SQL—DDL—建表、查表、修改表以及总结

一、DDL—表—创建表与数据类型的设定 &#xff08;1&#xff09;要求 根据需求创建表(设计合理的数据类型、长度) 设计一张员工信息表&#xff0c;要求如下: 1、编号&#xff08;纯数字) 2、员工工号(字符串类型&#xff0c;长度不超过10位) 3、员工姓名&#xff08;字符串类…

设计模式10——装饰模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 装饰模式 是一种行为型模式。…

笔记88:LeetCode_134_加油站

前言&#xff1a; 前言1&#xff1a;这个题的题目条件给的不太严谨&#xff0c;题目描述中说“如果存在解&#xff0c;则保证它是唯一的”&#xff0c;通过我的实践&#xff0c;我发现这句话的意思其实是本题的所有样例只有两种情况&#xff0c;无解/有唯一解&#xff1b;而不可…

【Spring】认识 Spring AOP

认识 Spring AOP 1.什么是 AOP2.AOP 中的概念3.用 AOP 方式管理日志3.1 编写 AOP 日志注解类3.2 编写控制器用于测试 1.什么是 AOP AOP&#xff08;Aspect Oriented Program&#xff0c;面向切面编程&#xff09;把业务功能分为核心、非核心两部分。 核心业务功能&#xff1a…

tcpdump源码分析

进入tcpdump.c&#xff08;函数入口&#xff09;之前&#xff0c;先看一些头文件netdissect.h里定义了一个数据结构struct netdissect_options来描述tcdpump支持的所有参数动作&#xff0c;每一个参数有对应的flag, 在tcpdump 的main 里面&#xff0c; 会根据用户的传入的参数来…

构建高效的在线培训机构CRM应用架构实践

在当今数字化时代&#xff0c;在线培训已成为教育行业的重要趋势之一。为了提供更好的学习体验和管理服务&#xff0c;在线培训机构需要构建高效的CRM&#xff08;Customer Relationship Management&#xff09;应用架构。本文将探讨在线培训机构CRM应用架构的设计与实践。 一、…

力扣周赛398题解

特殊数组Ⅰ 如果数组的每一对相邻元素都是两个奇偶性不同的数字&#xff0c;则该数组被认为是一个 特殊数组 。 Aging 有一个整数数组 nums。如果 nums 是一个 特殊数组 &#xff0c;返回 true&#xff0c;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;nums [1] …

数据结构和算法|排序算法系列(二)|冒泡排序

首先需要你对排序算法的评价维度和一个理想排序算法应该是什么样的有一个基本的认知&#xff1a; 《Hello算法之排序算法》 主要内容来自&#xff1a;Hello算法11.3 冒泡排序 我觉得冒泡排序非常有意思&#xff0c;也非常简单&#xff0c;就是不停地交换相邻的元素即可&#…

代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点 、 面试题 02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点 题目链接&#xff1a; 24. 两两交换链表中的节点 文档讲解&#xff1a;代码随想录 状态&#xff1a;没做出来&#xff0c;没有正确更新头节点&#xff0c;因为head和cur共享引用&#xff0c;会随着cur的移动&#xff0c;丢失之前存放的节点 错误代码&…

腾讯发布ELLA:为扩散模型注入LLM能力,提升复杂场景的图像生成,准确率超90%

前言 近年来&#xff0c;基于扩散模型的文本到图像生成技术取得了显著进步&#xff0c;能够生成高质量、逼真的图像。然而&#xff0c;大多数扩散模型仍然使用CLIP作为文本编码器&#xff0c;这限制了它们理解复杂提示的能力&#xff0c;例如包含多个物体、详细属性、复杂关系…

摄像头应用测试

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

MySQL(一) 库和表的基础操作

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质&#xff1a;磁盘内存 为了解…

学 C/C++ 具体能干什么?

学习 C 和 C 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;这两种语言以其高性能和低级控制而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 系统编程 C 和 C 是系统编程的首选语言&#xff0c;适用于操作系统、驱动程序和嵌入式系统开发。 操作系统开发…

PgMP:项目集管理,哪些人适合学习?

美国项目管理协会&#xff08;PMI&#xff09;对项目集经理&#xff08;Program Manager&#xff09;的角色做出如下的定义&#xff1a; 在最少的领导/监督下&#xff0c;项目集经理PgMP负责在商业和组织目的下协调管理多个相关项目。这些项目含有跨部门、组织、地理区域…

【kubernetes】探索k8s集群中金丝雀发布后续 + 声明式资源管理yaml

目录 一、K8S常见的发布方式 1.1蓝绿发布 1.2灰度发布&#xff08;金丝雀发布&#xff09; 1.3滚动发布 二、金丝雀发布 三、声明式管理方法 3.1YAML 语法格式 3.1.1查看 api 资源版本标签 3.1.2查看资源简写 3.2YAML文件详解 3.2.1Deployment.yaml 3.2.2Pod.yaml …