第73節:在液晶屏中把字體鏡像顯示的算法程序

2021-01-12 電子產品世界
開場白:

有的項目會要求把字體或者圖像進行鏡像顯示處理,這一節把這個算法教給大家。

本文引用地址:http://www.eepw.com.cn/article/201611/319735.htm

這個算法的本質是:

16x16點陣的圖像或者字體有16行,每行有2個字節,如果把這2個字節看成是一個16位int型數據,那麼就是要這個數據從原來左邊是高位,右邊是低位的順序顛倒過來。本程序沒有把2個字節合併成一個int型數據,而是直接在一個字節數據內把高低位順序顛倒過來,然後把第1位元組數據跟第2位元組數據交換。

8x16點陣的圖像或者字體有16行,每行有1個字節,把這個數據從原來左邊是高位,右邊是低位的順序顛倒過來。

具體內容,請看原始碼講解。

(1)硬體平臺:

基於朱兆祺51單片機學習板

(2)實現功能:開機上電後,從上往下分別顯示「饅頭V5」四個字以及右邊鏡像後的「饅頭V5」四個字。

(3)原始碼講解如下:

#include "REG52.H"

sbit LCDCS_dr = P1^6; //片選線

sbit LCDSID_dr = P1^7; //串行數據線

sbit LCDCLK_dr = P3^2; //串行時鐘線

sbit LCDRST_dr = P3^4; //復位線

void SendByteToLcd(unsigned char ucData); //發送一個字節數據到液晶模塊

void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模擬SPI發送一個字節的命令或者數據給液晶模塊的底層驅動

void WriteCommand(unsigned char ucCommand); //發送一個字節的命令給液晶模塊

void LCDWriteData(unsigned char ucData); //發送一個字節的數據給液晶模塊

void LCDInit(void); //初始化 函數內部包括液晶模塊的復位

void display_lattice(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount); //顯示任意點陣函數

void display_clear(void); // 清屏

void hz1616_mirror(const unsigned char *p_ucHz,unsigned char *p_ucResult); //把16x16點陣字庫鏡像

void hz816_mirror(const unsigned char *p_ucHz,unsigned char *p_ucResult); //把8x16點陣字庫鏡像

void delay_short(unsigned int uiDelayshort); //延時

code unsigned char Hz1616_man[]= /*饅 橫向取模 16X16點陣 */

{

0x21,0xF8,0x21,0x08,0x21,0xF8,0x3D,0x08,0x45,0xF8,0x48,0x00,0x83,0xFC,0x22,0x94,

0x23,0xFC,0x20,0x00,0x21,0xF8,0x20,0x90,0x28,0x60,0x30,0x90,0x23,0x0E,0x00,0x00,

};

code unsigned char Hz1616_tou[]= /*頭 橫向取模 16X16點陣 */

{

0x00,0x80,0x10,0x80,0x0C,0x80,0x04,0x80,0x10,0x80,0x0C,0x80,0x08,0x80,0x00,0x80,

0xFF,0xFE,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x30,0x08,0x18,0x10,0x0C,0x20,0x08,

};

code unsigned char Zf816_V[]= /*V 橫向取模 8x16點陣 */

{

0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,

};

code unsigned char Zf816_5[]= /*5 橫向取模 8x16點陣 */

{

0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,

};

unsigned char ucBufferResult[32]; //用於臨時存放轉換結束後的字模數組

void main()

{

LCDInit(); //初始化12864 內部包含液晶模塊的復位

display_clear(); // 清屏

display_lattice(0,0,Hz1616_man,0,2,16); //顯示鏡像前的字

hz1616_mirror(Hz1616_man,ucBufferResult); //把字鏡像後放到ucBufferResult臨時變量裡。

display_lattice(1,0,ucBufferResult,0,2,16); //顯示鏡像後的字

display_lattice(0,16,Hz1616_tou,0,2,16); //顯示鏡像前的字

hz1616_mirror(Hz1616_tou,ucBufferResult); //把字鏡像後放到ucBufferResult臨時變量裡。

display_lattice(1,16,ucBufferResult,0,2,16); //顯示鏡像後的字

display_lattice(8,0,Zf816_V,0,1,16); //顯示鏡像前的字符

hz816_mirror(Zf816_V,ucBufferResult); //把字符鏡像後放到ucBufferResult臨時變量裡。

display_lattice(9,0,ucBufferResult,0,1,16); //顯示鏡像後的字符

display_lattice(8,16,Zf816_5,0,1,16); //顯示鏡像前的<5>字符

hz816_mirror(Zf816_5,ucBufferResult); //把<5>字符鏡像後放到ucBufferResult臨時變量裡。

display_lattice(9,16,ucBufferResult,0,1,16); //顯示鏡像後的<5>字符

while(1)

{

;

}

}

void display_clear(void) // 清屏

{

unsigned char x,y;

WriteCommand(0x34); //關顯示緩衝指令

WriteCommand(0x34); //關顯示緩衝指令 故意寫2次,怕1次關不了 這個是因為我參考到某廠家的驅動程序也是這樣寫的

y=0;

while(y<32) //y軸的範圍0至31

{

WriteCommand(y+0x80); //垂直地址

WriteCommand(0x80); //水平地址

for(x=0;x<32;x++) //256個橫向點,有32個字節

{

LCDWriteData(0x00);

}

y++;

}

WriteCommand(0x36); //開顯示緩衝指令

}

/* 注釋一:

* 16x16點陣鏡像的本質:

* 16x16點陣有16行,每行有2個字節,如果把這2個字節看成是一個16位int型數據,

* 那麼就是要這個數據從原來左邊是高位,右邊是低位的順序顛倒過來。本程序沒有把2個字節

* 合併成一個int型數據,而是直接在一個字節數據內把高低位順序顛倒過來,然後把第1位元組數據跟第2位元組數據交換。

*/

void hz1616_mirror(const unsigned char *p_ucHz,unsigned char *p_ucResult) //把16x16點陣字庫鏡像的函數

{

unsigned char a;

unsigned char b;

unsigned char c;

unsigned char d;

for(a=0;a<16;a++) //這裡16代表有16行。每一行有2個字節。把每一個字節看做一列,這裡先把第1列字節的數據從原來左邊是高位,右邊是低位的順序顛倒過來,相當於鏡像。

{

b=p_ucHz[a*2+0]; //這裡的2代表16x16點陣每行有2列字節,0代表從第1列開始。

c=0;

for(d=0;d<8;d++) //把一個字節調換順序

{

c=c>>1;

if((b&0x80)==0x80)

{

c=c|0x80;

}

b=b<<1;

}

p_ucResult[a*2+1]=c; //注意,因為是鏡像,所以要把顛倒順序後的字節從原來是第1列的調換到第2列

}

for(a=0;a<16;a++) //這裡16代表有16行。每一行有2個字節。把每一個字節看做一列,這裡先把第2列字節的數據從原來左邊是高位,右邊是低位的順序顛倒過來,相當於鏡像。

{

b=p_ucHz[a*2+1]; //這裡的2代表16x16點陣每行有2列字節,1代表從第2列開始。

c=0;

for(d=0;d<8;d++) //把一個字節調換順序

{

c=c>>1;

if((b&0x80)==0x80)

{

c=c|0x80;

}

b=b<<1;

}

p_ucResult[a*2+0]=c; //注意,因為是鏡像,所以要把顛倒順序後的字節從原來是第2列的調換到第1列

}

}

/* 注釋二:

* 8x16點陣鏡像的本質:

* 8x16點陣有16行,每行有1個字節,把這個數據從原來左邊是高位,右邊是低位的順序顛倒過來。

*/

void hz816_mirror(const unsigned char *p_ucHz,unsigned char *p_ucResult) //把8x16點陣字庫鏡像的函數

{

unsigned char a;

unsigned char b;

unsigned char c;

unsigned char d;

for(a=0;a<16;a++) //這裡16代表有16行。每一行有1個字節。這裡先把每一行字節的數據從原來左邊是高位,右邊是低位的順序顛倒過來,相當於鏡像。

{

b=p_ucHz[a*1+0]; //這裡的1代表8x16點陣每行有1列字節,0代表從第1列開始。

c=0;

for(d=0;d<8;d++) //把一個字節調換順序

{

c=c>>1;

if((b&0x80)==0x80)

{

c=c|0x80;

}

b=b<<1;

}

p_ucResult[a*1+0]=c; //注意,因為每一行只有一列,所以不用像16x16點陣那樣把第1列跟第2列對調交換。

}

}

/* 注釋三:本節的核心函數,讀者尤其要搞懂x_amount和y_amount對應的顯示關係。

* 第1,2個參數x,y是坐標體系。x的範圍是0至15,y的範圍是0至31.

* 第3個參數*ucArray是字模的數組。

* 第4個參數ucFbFlag是反白顯示標誌。0代表正常顯示,1代表反白顯示。

* 第5,6個參數x_amount,y_amount分別代表字模數組的橫向有多少個字節,縱向有幾橫。

*/

void display_lattice(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount)

{

unsigned int j=0;

unsigned int i=0;

unsigned char ucTemp;

WriteCommand(0x34); //關顯示緩衝指令

WriteCommand(0x34); //關顯示緩衝指令 故意寫2次,怕1次關不了 這個是因為我參考到某廠家的驅動程序也是這樣寫的

for(j=0;j

{

WriteCommand(y+j+0x80); //垂直地址

WriteCommand(x+0x80); //水平地址

for(i=0;i

{

ucTemp=ucArray[j*x_amount+i];

if(ucFbFlag==1) //反白顯示

{

ucTemp=~ucTemp;

}

LCDWriteData(ucTemp);

// delay_short(30000); //把上一節這個延時函數去掉,加快刷屏速度

}

}

WriteCommand(0x36); //開顯示緩衝指令

}

void SendByteToLcd(unsigned char ucData) //發送一個字節數據到液晶模塊

{

unsigned char i;

for ( i = 0; i < 8; i++ )

{

if ( (ucData << i) & 0x80 )

{

LCDSID_dr = 1;

}

else

{

LCDSID_dr = 0;

}

LCDCLK_dr = 0;

LCDCLK_dr = 1;

}

}

void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模擬SPI發送一個字節的命令或者數據給液晶模塊的底層驅動

{

SendByteToLcd( 0xf8 + (ucWRS << 1) );

SendByteToLcd( ucWData & 0xf0 );

SendByteToLcd( (ucWData << 4) & 0xf0);

}

void WriteCommand(unsigned char ucCommand) //發送一個字節的命令給液晶模塊

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucCommand, 0);

delay_short(90);

}

void LCDWriteData(unsigned char ucData) //發送一個字節的數據給液晶模塊

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucData, 1);

}

void LCDInit(void) //初始化 函數內部包括液晶模塊的復位

{

LCDRST_dr = 1; //復位

LCDRST_dr = 0;

LCDRST_dr = 1;

}

void delay_short(unsigned int uiDelayShort) //延時函數

{

unsigned int i;

for(i=0;i

{

;

}

}

總結陳詞:

細心的網友一定會發現,這種12864液晶屏普遍有個毛病,在坐標軸x,y方向上不能完全做到以一個點陣為單位進行隨心所欲的顯示,比如橫向的至少是一個字節8個點陣為單位,而第1,2行跟第3,4行又做不到無縫對接顯示,假如我要把漢字一半顯示在第2行一半顯示在第3行,行不行?當然可以。但是需要我們編寫額外的算法程序。這種算法程序是怎樣編寫的?欲知詳情,請聽下回分解在液晶屏中讓字體可以跨區域無縫對接顯示的算法程序。

相關焦點

  • 「模型雲」cad中防止鏡像字體顛倒的方法與步驟
    CAD中如何防止鏡像字體顛倒?在我們使用CAD鏡像功能進行模型的複製時,有沒有辦法避免出現鏡像字體顛倒的情況呢?本期,模型云為您帶來了cad防止鏡像字體顛倒的方法與步驟,希望能夠給您帶來幫助。cad防止鏡像字體顛倒的方法與步驟步驟一、打開CAD軟體後,首先使用文字命令,在繪圖區任意輸入一些文字,我們來演示CAD中如何防止鏡像字體顛倒。步驟二、在文字旁邊繪製一條鉛直線,以用作鏡像時的對稱軸線。以正常的方式執行鏡像命令,觀察鏡像後的效果,可以看到現在CAD鏡像字體是顛倒的,要怎麼將它復原呢?
  • CAD字體問題匯總(字體顯示問號,文字無法編輯......
    原因可能是:①對應的字型沒有使用漢字字體,如HZTXT.SHX等;②當前系統中沒有漢字字體形文件;應將所用到的形文件複製到AutoCAD的字體目錄中(一般為...\FONTS\);③對於某些符號,如希臘字母等,同樣必須使用對應的字體形文件,否則會顯示成?號。
  • 算法是什麼:計算機領域中算法的科普
    為何它們會顯示正確答案?所有這些都要感謝算法。每當你使用手機、計算機、筆記本電腦或計算器時,其實都在使用算法。那麼,什麼是算法?如果你想做數學運算,比如說兩個數字相乘(不使用任何電子設備),那麼你需要在紙上做乘法。你按照一定的規則獲得正確的答案。你也可以使用耗時更少的方法來做計算。這就是算法。算法是為執行特定的任務而設計的一組指令。
  • 張凌寒:算法自動化決策與行政正當程序制度的衝突與調和
    例如,在算法自動化決策參與行政許可行為中,我國《行政許可法》第 33 條規定了以數據電子方式提出行政許可,應在行政機關的網站公布許可事項。作為行政信息公開在算法治理時代的因應性調整。然而,在算法自動化決策參與的行政活動中,尚有行政信息公開原則的一些基本規則尚未得到滿足。首先,應增強算法自動化決策的可見性,作為行政信息公開的基本要求。
  • 樹莓派推出 SD 卡鏡像程序 Raspberry Pi Imager
    Raspberry Pi 宣布推出新的鏡像實用程序 Raspberry Pi Imager,以提供一種更簡單的方法,將作業系統輕鬆鏡像到
  • 遺傳算法Python實戰 008.魔術方塊
    idx = bisect_left(a,3.6)print(idx)# 4然後初始化一堆參數:diagonalSize是你方塊的數量,3就表示3*3的方塊maxAge是本節算法需要著重說明的地方,後面解釋nSquared 這個方塊表面總共有多少個格子geneset
  • 華文中宋-免ROOT換字體
    安裝後啟用新字體方法:進入菜單>設置>顯示>字體風格>字體溫馨操作提示:*系統個別軟體需要Root權限,附帶ROOT教程.**ROOT教程:http://root.wap3.cn/***提示:所有卸載系統軟體的軟體都必須獲得ROOT權限,本工具附帶的ROOT教程為第三方教程,如無法ROOT並非本軟體功能缺失****更換系統字體為修改系統文件,由於安卓衍生系統比較多,不保證所有系統,機型均能成功使用我們已推出字體有:1.
  • 研究顯示手機應用程式測皮膚癌風險不靠譜
    一些智慧型手機應用程式宣稱可以評估皮膚癌變風險,儘早發現皮膚癌,且有所謂研究數據為證。但英國一項最新研究顯示,這些應用程式「不靠譜」,不推薦使用它們測皮膚癌。在歐洲,有兩款手機應用程式獲得醫藥管理部門批准,被列為對用戶存在低至中度風險的一類醫療裝置。
  • 不要輕易使用 Alpine 鏡像來構建 Docker 鏡像,有坑!
    Go 語言鏡像精簡Go 語言程序編譯時會將所有必須的依賴編譯到二進位文件中,但也不能完全肯定它使用的是靜態連結,因為 Go 的某些包是依賴系統標準庫的,例如使用到 DNS 解析的包。也就是說,如果 Go 程序使用了 net 包,就會生成一個動態的二進位文件,如果想讓鏡像能夠正常工作,必須將需要的庫文件複製到鏡像中,或者直接使用 busybox:glibc 鏡像。
  • 用「Python」開啟程序猿的愛情之旅
    前段時間有一段很火的視頻,有一位程式設計師喜歡一個女孩子,選擇了七夕節向這個女生表白,給她發了一串數字:73、76、79、86、85。聯繫到男生的職業,女生嘗試各種程序代碼,最終通過「ASCII對照表」破譯5個數字:I LOV U。
  • 新的AppStore中的應用程式稱為鏡面三星電視和鏡子的LG電視
    如果您擁有三星或LG品牌的智能電視,那麼您將很高興知道自己無需購買Apple TV或在iPhone或iPad上安裝大量難看的加密狗即可將其顯示在電視上。新的App Store中的應用程式稱為鏡面三星電視和鏡子的LG電視,都是由開發AirBeamTV BV,讓你無線廣播你的iOS 12設備的屏幕支持智能電視輕鬆。
  • 戴爾伺服器Hybrid ISO非零偏移鏡像
    例如,ISOhybrid鏡像上的fdisk-l將會顯示如下:  linux# fdisk -l Centos60-Base.iso  Disk Centos60-Base.iso: 231 MB, 231735296 bytes  64 heads, 32 sectors/track, 221 cylinders, total 452608 sectors
  • 刷入字體後開機顯示異常的常見解決方法
    現象二確保操作正常,刷入字體之後,開機發現中文字體都丟失了,顯示不出來。這個問題其實我也提到過不少次,詳見這篇:事實上,刷字體,是一個把我寫好的文件塞到系統裡去的過程。並且我的字體經常是開啟多字重效果的,系統本身的單字重字體文件可能就10幾個MB,我的5字重字體是五倍以上的體積,以我的信黑專業版為例,就需要96M的系統空間。如果你的系統空間只剩下80MB,那麼無論是刷入還是替換字體,都是不能完全把字體塞進去的,字體就會顯示異常。
  • 如何修改支付寶小程序開發者工具字體
    在進行支付寶小程序開發時,使用小程序開發者工具進行開發;但是工具默認的字體太小,特別是對有近視的開發人員,長時間看會很累。那麼,如何修改支付寶小程序開發者工具字體?下面利用具體的實例說明:操作步驟:1、打開小程序開發者工具,創建一個小程序項目
  • 無需其他虛擬光碟機軟體即可打開ISO鏡像,在Windows10中是這樣做的
    ISO鏡像是一種容器格式,旨在存儲物理磁碟(CD、DVD或藍光光碟)的內容。軟體公司通常使用這種文件格式作為介質來分發應用程式和工具,而無需使用物理光碟,這可能既昂貴又耗時。例如,微軟現在使用此格式將Windows 10的預覽版分發給測試人員。
  • 中科院開發的一款算法程序可以做到了|硬科技
    近日,中科院北京研究小組就開發了一款算法程序Deep Face Drawing,它可以利用人工智慧來幫助用戶將人像的簡單塗鴉立即轉換為照片肖像。公開研究顯示,這一技術主要是通過構建圖像深度學習模型來實現的。具體來說,研究人員採取了一個從局部再到整體的方法,首先構建了相應的算法模型,並將人臉分成了左眼、右眼、鼻子、嘴、其餘部位這5個關鍵「組件」。
  • 資料| 算法心得:高效算法的奧秘(中文第2版)
    內容簡介 · · · · · ·【編輯推薦】 由在IBM工作50餘年的資深計算機專家撰寫,Amazon全五星評價,算法領域最有影響力的著作之一 Google公司首席架構師、Jolt大獎得主Hoshua Bloch
  • 從安全到鏡像流水線,Docker 最佳實踐與反模式一覽
    在同一個容器中運行多個服務雖然你可以在同一個容器中運行多個服務,但我並不建議你這麼做,原因有兩個。在使用Docker服務時,我們應該努力維持責任單一性。最佳做法是,組成應用程式的每個服務都應在各自的容器中運行,請務必將每項獨立的功能都打包到單獨的獨立容器鏡像中。
  • 「Scratch AI 數學」可愛的小鬧鐘第1節(共3節)
    文 | 大程「Scratch AI 數學系列」第三課:可愛的小鬧鐘第1節(共3節)視頻:契合小學數學課本「時間、鬧鐘」的知識點,提供該節課程,將同學們書桌上的鬧鐘搬到程序裡來【Scratch AI 數學】可愛的小鬧鐘第1節(共3節)
  • iOS 13將增加17000種新字體,不希望更改系統字體
    在iOS 13系統中,蘋果增加了對第三方字體的支持,允許用戶通過AppStore安裝和使用第三方字體。最新消息顯示,iOS 13系統將首次能夠使用Adobe的大型字體庫,擁有17000多個字體,用戶可以通過自定義字體選項來運行iOS 13.1版本的系統。