嵌入式进阶——数码管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号引脚。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋野酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值