屏幕顯示英文字符
??有個屏幕,掌機的可玩性可以大大增強,打地鼠玩膩了,可以玩?zhèn)€貪吃蛇,俄羅斯方塊,以及其他需要開動想象力的游戲。并且,以前總是玩別人的游戲,現(xiàn)在可以自己寫游戲,豈不美哉。
??后來我感覺0.96的OLED屏幕太小了,搞個更大的全彩屏,換成STM32F4系列單片機,跑個ucos,運行NES模擬器,然后我是不是就能拳打任天堂,腳踢PSP了?哈哈哈
??打地鼠的游戲,可以顯示生命值,得分,關(guān)卡或難度。所以要定義幾個變量。
//main.c
//默認(rèn)參數(shù)
#define LIFE_NUM 3 // 默認(rèn)幾條命
//全局變量定義
u8 life = LIFE_NUM; //生命
u32 score = 0; //得分記錄
u8 level = 1; //當(dāng)前難度,數(shù)字越大難度越高
??一般來說,顯示英文字符都會有配套的顯示函數(shù)。我參考的代碼也提供了這些函數(shù)。直接調(diào)用即可。formatScreen用于清屏,就像老師板書之前要擦黑板一樣。showString用于在指定的坐標(biāo)顯示英文字符,每個參數(shù)的含義可以跳轉(zhuǎn),看函數(shù)說明。
int main(void)
{
LED_Init();
KEY_Init();
delay_init();
initIIC();
initOLED();
formatScreen(0x00);
showString(0,0,"yoodao",FONT_16_EN);
showString(0,2,"life:",FONT_16_EN);
showString(0,4,"level:",FONT_16_EN);
showString(0,6,"score:",FONT_16_EN);
showNumber(56,2,life,DEC,8,FONT_16_EN);
showNumber(56,4,level,DEC,8,FONT_16_EN);
showNumber(56,6,score,DEC,8,FONT_16_EN);
while(1)
{
score++;
showNumber(56,6,score,DEC,8,FONT_16_EN);
delay_ms(1000);
}
}
屏幕顯示漢字
??漢字的顯示可能就稍微復(fù)雜些,因為我們選用的屏幕沒有中文字庫,所以要自行取模。在取模之前,我先試了試人家顯示漢字的函數(shù)showCNString與顯示圖片的函數(shù)showImage’’,成功。
在此感謝風(fēng)媒電子。
//main.c
formatScreen(0x00);
showImage(0,0,128,8,FM_LOGO_ENUM);
delay_ms(1000);
// showString(0,0,"yoodao",FONT_16_EN);
showCNString(0,0,"風(fēng)媒電子",FONT_16_CN);
??然后把顯示的LOGO和漢字改一改。
formatScreen(0x00);
// showImage(0,0,128,8,Y_LOGO_ENUM);
// delay_ms(1000);
// formatScreen(0x00);
// showString(0,0,"yoodao",FONT_16_EN);
showCNString(0,0,"小極客打地鼠掌機",FONT_16_CN);
??然后用取模軟件,生成“小極客打地鼠掌機”的字模
??取模軟件的使用:
??取得字模以后,替換原先的漢字?jǐn)?shù)組。
/************************************16*16 漢字************************************/
const unsigned char CN1616[8][32] =
{
{0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00},/*"小",0*/
{0x10,0x10,0xD0,0xFF,0x90,0x10,0x02,0x02,0xFE,0x02,0x02,0x62,0x5A,0xC6,0x00,0x00,0x04,0x03,0x00,0xFF,0x00,0x43,0x30,0x8F,0x80,0x43,0x2C,0x10,0x2C,0x43,0x80,0x00},/*"極",1*/
{0x10,0x0C,0x84,0x44,0xB4,0xA4,0x25,0x26,0x24,0xA4,0x64,0x24,0x04,0x14,0x0C,0x00,0x04,0x04,0x04,0xFA,0x4A,0x4A,0x49,0x49,0x49,0x4A,0x4A,0xFA,0x04,0x04,0x04,0x00},/*"客",2*/
{0x10,0x10,0x10,0xFF,0x10,0x90,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x00,0x04,0x44,0x82,0x7F,0x01,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00},/*"打",3*/
{0x20,0x20,0x20,0xFF,0x20,0x20,0x80,0xF8,0x80,0x40,0xFF,0x20,0x10,0xF0,0x00,0x00,0x10,0x30,0x10,0x0F,0x08,0x08,0x00,0x3F,0x40,0x40,0x5F,0x42,0x44,0x43,0x78,0x00},/*"地",4*/
{0x00,0x00,0x7E,0x4A,0x4A,0x49,0x40,0x40,0x40,0x4A,0x4A,0x4A,0x7E,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x49,0x12,0x00,0xFF,0x80,0x49,0x12,0x00,0x3F,0x40,0xF0,0x00},/*"鼠",5*/
{0x00,0x10,0x0C,0x05,0x76,0x54,0x54,0x57,0xD4,0xD4,0xF6,0x85,0x14,0x0C,0x00,0x00,0x00,0x10,0x15,0x15,0x15,0x55,0x95,0x7F,0x14,0x14,0x14,0x14,0x14,0x10,0x00,0x00},/*"掌",6*/
{0x10,0x10,0xD0,0xFF,0x90,0x10,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x04,0x03,0x00,0xFF,0x00,0x83,0x60,0x1F,0x00,0x00,0x00,0x3F,0x40,0x40,0x78,0x00},/*"機",7*/
};
unsigned char CN1616_Index[] = "小極客打地鼠掌機"; //16*16中文字庫索引表
??編譯,下載程序,可以看出漢字能夠正常顯示出來。
??這里有個注意事項,工程中所有文件設(shè)置的編碼格式必須統(tǒng)一。因為編譯器不認(rèn)識漢字,只認(rèn)識漢字的編碼,同一個漢字,其UTF-8與GB2312的編碼是不一樣。不同的編碼在編譯器看來,就是不同的漢字。所以要保證,工程里所有文件的編碼方式都一致。我發(fā)的源碼工程采用UTF-8的編碼。
圖片的顯示
??顯示圖片與顯示漢字的原理是一樣的,畢竟,,,,漢字也是被當(dāng)成圖片處理的嘛。話說,外國人眼里的漢字,可能就是圖片。
??我打算顯示的圖片是我自己的LOGO,像是刻在石碑上的字母Y。也需要借助取模軟件把圖片變成一個數(shù)組。
??然后模仿人家的程序,把數(shù)組名字和枚舉類型修改下。
//main.c
showImage(0,0,128,8,Y_LOGO_ENUM);
//OLED.c
/**
* 功能:在制定區(qū)域顯示圖片
* 參數(shù):
* x:x軸坐標(biāo) 0-127
* y:y軸坐標(biāo) 0-7
* x_len:顯示區(qū)域橫坐標(biāo)長度 0-128
* y_len:顯示區(qū)域縱坐標(biāo)長度 0-8
* image_index:圖片枚舉索引
* 說明:該函數(shù)一般用于顯示全屏LOGO,另外靈活運用可以顯示PPT切換特效
*
* 返回值:None
*/
void showImage(u8 xpos, u8 ypos,u8 x_len, u8 y_len,IMAGE_INDEX image_index)
{
u16 i,j;
for(i=0;i setPos(xpos,ypos++); for(j=i*128+xpos;j { switch(image_index) { case Y_LOGO_ENUM :writeData(Y_LOGO[j]); break; default : break; } } } } ??顯示大LOGO一次成功。 ??接著我設(shè)計了幾個位圖,都是32像素見方的,分別是上下左右,ABCD,圓和圓圈。萬一以后要擴展炫舞或者太鼓達人的游戲呢, ??代碼也相應(yīng)修改了下。數(shù)組里內(nèi)容太長,就不列出來了。數(shù)組和位圖都上傳了。 //main.c //顯示幾個小LOGO formatScreen(0x00); showImage(0,0,32,4,UP_LOGO_ENUM); showImage(32,0,32,4,DOWN_LOGO_ENUM); showImage(64,0,32,4,LEFT_LOGO_ENUM); showImage(96,0,32,4,RIGHT_LOGO_ENUM); showImage(0,4,32,4,A_LOGO_ENUM); showImage(32,4,32,4,B_LOGO_ENUM); showImage(64,4,32,4,C_LOGO_ENUM); showImage(96,4,32,4,D_LOGO_ENUM); delay_ms(1000); ??顯示圖片的函數(shù)也做了修改 void showImage(u8 xpos, u8 ypos,u8 x_len, u8 y_len,IMAGE_INDEX image_index) { u16 i,j; for(i=0;i setPos(xpos,ypos++); for(j=i*128+xpos;j { switch(image_index) { case Y_LOGO_ENUM :writeData(Y_LOGO[j]); break; case UP_LOGO_ENUM :writeData(UP_LOGO[j]); break; case DOWN_LOGO_ENUM :writeData(DOWN_LOGO[j]); break; case LEFT_LOGO_ENUM :writeData(LEFT_LOGO[j]); break; case RIGHT_LOGO_ENUM :writeData(RIGHT_LOGO[j]); break; case A_LOGO_ENUM :writeData(A_LOGO[j]); break; case B_LOGO_ENUM :writeData(B_LOGO[j]); break; case C_LOGO_ENUM :writeData(C_LOGO[j]); break; case D_LOGO_ENUM :writeData(D_LOGO[j]); break; case CIRCLE_LOGO_ENUM :writeData(CIRCLE_LOGO[j]); break; case EMPTY_LOGO_ENUM :writeData(EMPTY_LOGO[j]); break; default : break; }//switch }//for j }//for i } 結(jié)果卻出現(xiàn)了亂碼,這是怎么回事? 解決亂碼 ??我首先分析了showImage函數(shù)。函數(shù)的說明中,這句話引起了我的注意: 說明:該函數(shù)一般用于顯示全屏LOGO,另外靈活運用可以顯示PPT切換特效 ??全屏LOGO?全屏是128×64像素 ,我的Y-LOGO顯示沒有問題。而箭頭是32×32像素的圖片,顯示出來卻有問題,這說明,此函數(shù)可以顯示128×64的圖片,不能顯示32×32的圖片。 ??然后我開始分析顯示函數(shù)的坐標(biāo)體系。屏幕是黑白的,共有128×64個像素,每個像素有黑白兩種狀態(tài),正好對應(yīng)0和1兩種狀態(tài),所以一個圖片需要128×64個bit(二進制位),也就是需要128×8個byte(字節(jié))來表示。x坐標(biāo)取值范圍是0-127,y坐標(biāo)的取值范圍是0-7,所以能猜出來,豎直方向上的8個二進制位,組成了一個字節(jié)。這對應(yīng)了在使用取模軟件時的一個細節(jié):取模方式為列行式。先取最左邊一列上的8個點,再往右取一列上的8個點。 ??還有一個需要說明的點:取字方向是低位在前。為了說明位圖與數(shù)組的關(guān)系,我們來分析一下上箭頭的圖與數(shù)組的關(guān)系。 ??取模結(jié)果的前16位是 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFC,0xFC, ??為了看的更清楚,我把位圖與取模得到的數(shù)組結(jié)合在一起了。已經(jīng)具體到這種地步了,就不用再說明圖片是怎么變成數(shù)組了吧? ??接下來把數(shù)組還原為圖片。 ??首先要明確一個問題:數(shù)組是一維的,圖片是二維的。是否可以使用二維數(shù)組?可以,但沒有必要。用一維的數(shù)組儲存二維的圖片,假設(shè)圖片的尺寸是x×y,那么圖片中個點的坐標(biāo)系是這樣的。 0 1 。 。 x-2 x x+1 。 。 2x-2 。 。 。 。 。 (y-1)x (y-1)x+1 。 。 。 ??最后一個點也可以寫為(y-1)x+(x-1),與xy-1在數(shù)學(xué)上等價。 ??儲存到數(shù)組中是這樣的: 0 1 。。。 x-1 x x+1 。。。 (y-1)x (y-1)x+1 。。。 ??就像大家去操作做廣播體操,做操時,排成陣列。然而操場的門很小,只能讓一個人通過,因此離開操場時,要排成一隊。 ??明白這一點以后,來分析代碼 for(i=0;i setPos(xpos,ypos++); //2 for(j=i*128+xpos;j { switch(image_index) { case Y_LOGO_ENUM :writeData(Y_LOGO[j]); break;//4 }//switch }//for j ??代碼1,i ??代碼2,設(shè)置原點,直接使用了傳入的坐標(biāo)系,沒毛病 ??代碼4,把參數(shù)j作為數(shù)組索引來顯示,如果想顯示第一個“像素排”,那么j = 0,如果想顯示第二排的第一個“像素排”,那么j = 0+x_len。 ??那么代碼3,為什么i要×128? ??問題就出現(xiàn)在這里了。顯示大LOGO的時候,這個函數(shù)是可以用的,因為大LOGO的寬度正好是128。顯示32×32的小圖片的時候,函數(shù)就用不了了,因為,圖片的寬度是32啊! ??稍作修改,用傳入的圖片寬度參數(shù)替換掉128。大功告成。 //for(j=i*128+xpos;jfor(j=i*x_len;j 代碼其實還可以優(yōu)化 ??我發(fā)現(xiàn)屏幕刷新的速度太慢了,玩游戲的朋友都知道,F(xiàn)PS太低,畫面看起來就卡頓。這怎么能忍,F(xiàn)PS太低會影響我超神的啊! ??只顯示分?jǐn)?shù)當(dāng)然沒問題,但如果需要玩太鼓達人,或者炫舞之類,依賴屏幕刷新圖片的游戲,肯定會卡頓。我分析了一下,可能是IIC總線太慢。代碼里IIC操作的延遲都是1us,OLED屏幕最小支持350ns。但是STM32做納秒級的延時,理論計算并不可靠,需要實測,且提升有限,未做嘗試。 ??也考慮過使用SPI,理論上快不少。用一個大數(shù)組把屏幕上所有點的信息都記下來,數(shù)組也就1024個元素就能存儲所有的的信息,然后使用定時器+DMA+SPI,每隔一小段時間就刷新一下屏幕,只修改有變化的像素點,理論上速度快很多。暫時先做打地鼠的游戲,有空再折騰吧。
上一篇:STM32掌機教程5,程序框架,隨機,加命與升級
下一篇:STM32掌機教程3,工程模板與帶燈按鍵測試
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 人形機器人馬拉松背后的思考,兆易創(chuàng)新如何賦能機器人產(chǎn)業(yè)
- 一種基于STM32的智能柜控制器設(shè)計
- 小型傾轉(zhuǎn)旋翼機的無刷直流電機驅(qū)動器設(shè)計
- 超高速攝影機電控系統(tǒng)設(shè)計
- 基于GPS自動授時的無線智能控制器的設(shè)計
- 基于PTR2000的無線氣象信息采集系統(tǒng)設(shè)計
- Microchip推出MEC175xB系列器件,為嵌入式控制器引入硬件 抗量子攻擊能力
- 無人飛行器機載穩(wěn)定云臺控制系統(tǒng)的設(shè)計
- 匠芯創(chuàng)推出面向具身智能高性能實時處理器M7000
- OEM機器制造商利用仿真軟件提高效率
- 基于機器視覺的帶鋼焊縫定位
- 米爾RK3576核心板適配多種系統(tǒng),解鎖多樣化應(yīng)用
- 實時控制和通信領(lǐng)域的IT/OT融合如何推動工業(yè)自動化
- IXD0579M高壓側(cè)和低壓側(cè)柵極驅(qū)動器提供緊湊型即插即用解決方案
- 如何讓自動化領(lǐng)域的串口設(shè)備具備聯(lián)網(wǎng)能力?
- MBD應(yīng)用于霍爾組件位置選定
- 村田汽車和工業(yè)設(shè)備用PoC系統(tǒng)靜噪對策:難點及攻略全解析,別錯過
- 智慧節(jié)點的遠程運動控制實現(xiàn)可靠的自動化
- Windows 11電腦USB-C接口功能混亂結(jié)束了 微軟:所有接口必須支持?jǐn)?shù)據(jù)、充電和顯示
- 是德科技服務(wù)日研討會|武漢站——邀請函
- 上演你的“ADI實驗室電路”DIY,贏取E金幣 !
- 免費領(lǐng)取 | 射頻年度盛會EDI CON VIP全場通票(北京,3.20~22)
- EE牽手TI上傳有禮、積分雙倍
- 有獎直播|恩智浦嵌入式人機界面解決方案詳解
- 多款TI Launch板免費測評試用,趕緊來看看吧!
- 現(xiàn)場抽取PS5等諸多好禮 SiFive RISC-V 中國技術(shù)論壇 上海、北京、深圳 3場線下活動邀您出席!
- 下載汽車電氣化精品文章,贏【體脂秤、羅技鼠標(biāo)、手持風(fēng)扇】,開啟MPS汽車技術(shù)進階之旅!
- TI攜您共創(chuàng)未來乘駕新體驗——深入學(xué)習(xí): 點評明星產(chǎn)品,為它打榜