🎬 秋野醬:《個人主頁》
🔥 個人專欄:《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) {}
}
封裝的一些疑問
封裝的特點
封裝是面向對象程序設計中的一個重要概念,它將數據和行為封裝在一起,形成一個獨立的單元。下面是封裝的特點:
- 數據隱藏:封裝可以隱藏數據,只對外界公開必要的接口,從而保證數據的安全性和可靠性。
- 接口統一:封裝可以將數據和行為組織在一起,形成一個類或對象,通過統一的接口對外提供服務,便于使用和管理。
- 信息隱藏:封裝可以隱藏實現細節,只對外界公開必要的信息,從而降低了程序的復雜度和耦合度,提高了程序的可維護性和可擴展性。
- 可重用性:封裝可以將數據和行為封裝成一個獨立的單元,便于復用和重復利用,提高了程序的開發效率和代碼的可重用性。
- 封裝和繼承相結合:封裝和繼承是面向對象程序設計中的兩個重要概念,它們相互配合,可以構建出更加復雜、靈活和可擴展的程序。
總之,封裝是面向對象程序設計的核心思想之一,它可以提高程序的可靠性、安全性、可維護性和可擴展性,是程序設計中不可或缺的重要概念。
當前設計問題
接口設計:定義初始化(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 數字位 5NIXIE_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號引腳。