楊佳 鄧力
(1.南寧第三職業(yè)技術(shù)學校 廣西 南寧 530001;2.桂林理工大學 南寧分校,廣西 南寧 530001)
【摘 要】文章通過對國內(nèi)嵌入式系統(tǒng)崗位的技能進行分析,針對國內(nèi)院校嵌入式系統(tǒng)課程的教學內(nèi)容、實驗實訓開設(shè)的現(xiàn)狀,根據(jù)企業(yè)對嵌入式崗位招聘需求,提出了基于元件技術(shù)手冊的嵌入式驅(qū)動開發(fā)的新思路。以LPC2106驅(qū)動LCD1602液晶的項目,探索了基于元件技術(shù)手冊來進行新產(chǎn)品開發(fā)的培訓新思路,提出了基于元件技術(shù)手冊進行產(chǎn)品研發(fā)的新方法,對拓展國內(nèi)外嵌入式系統(tǒng)教學提供了新的課程培訓思路。
【關(guān)鍵詞】嵌入式;驅(qū)動開發(fā);LCD1602;LPC2106
【中圖分類號】TP311 【文獻標識碼】A 【文章編號】1674-0688(2016)03-0046-05
1 嵌入式系統(tǒng)崗位分析
隨著我國信息化與工業(yè)化融合的推進,嵌入式技術(shù)的廣泛應(yīng)用已成為必然趨勢[1]。企業(yè)不僅對嵌入式系統(tǒng)人才需求的數(shù)量在增加,對嵌入式系統(tǒng)人才的技能要求也在不斷地提高。從事嵌入式產(chǎn)品的相關(guān)研發(fā),離不開硬件層、中間層、軟件層、功能層4個層次的研發(fā)工作[2]。它的開發(fā)流程都必須先定義產(chǎn)品功能,再對定義進行系統(tǒng)分割,然后進行軟硬件的規(guī)劃和設(shè)計,按照崗位職能可進一步細分如下。
軟件研發(fā)分為系統(tǒng)構(gòu)建工程師、上層驅(qū)動開發(fā)工程師、上層應(yīng)用程序開發(fā)工程師。
硬件研發(fā)分為電路原理圖設(shè)計工程師、PCB設(shè)計工程師、底層驅(qū)動開發(fā)工程師。
軟件研發(fā)的3類工程師按照操作系統(tǒng)的種類又分出與各種操作系統(tǒng)相對應(yīng)的工程師。目前,在各領(lǐng)域應(yīng)用的主流操作系統(tǒng)有UCOS-II、LINUX、WINCE、VXWORKS等。企業(yè)一般會按照不同的操作系統(tǒng)平臺招聘相應(yīng)的工程師。
2 當前嵌入式系統(tǒng)培訓的不足
目前,國內(nèi)高校開設(shè)嵌入式系統(tǒng)課程的高校、培訓機構(gòu)較少,嵌入系統(tǒng)課程的教學內(nèi)容、實驗實訓的開設(shè)還處在探索的階段[3]。通過對畢業(yè)學生、學員的回訪和到企業(yè)的調(diào)研發(fā)現(xiàn),由于在學習時學員對元件的手冊沒有全面地練習,對設(shè)備、元件的相關(guān)代碼都是通過修改(教師提供或網(wǎng)上下載)而得到的,因此當采用新元件時,學員對新元件的驅(qū)動編寫無從下手。
3 嵌入式系統(tǒng)培訓改進的基本思想
(1)要讓學員學習如何查看廠家提供的技術(shù)手冊并根據(jù)元器件技術(shù)手冊來進行設(shè)計。
(2)培訓項目元件的選取要有一定的復(fù)雜性,但最好選取學員不太陌生的元器件。
(3)為了使學員能更深刻地理解驅(qū)動程序的代碼是如何與元件的硬件電路相對應(yīng)的,驅(qū)動程序的代碼編寫先不采用操作系統(tǒng)。
4 項目設(shè)計
根據(jù)項目設(shè)置的基本思想,設(shè)置一個嵌入式驅(qū)動液晶顯示的電路并完成相關(guān)驅(qū)動代碼的編寫。
液晶采用LCD1602,嵌入式CPU采用LPC2106,驅(qū)動項目編寫軟件采用ADS1.2,為了驗證驅(qū)動代碼運行的結(jié)果是否正確,采用Proteus軟件完成電路設(shè)計,并通過Proteus電路仿真來驗證[4]驅(qū)動代碼在液晶電路的運行情況。
項目主要通過LCD1602的顯示程序來學習如何根據(jù)LCD1602廠家的技術(shù)手冊編寫驅(qū)動程序代碼。
液晶LCD1602的主要技術(shù)參數(shù)如下。
1602字符型液晶顯示模塊是一種專門用于顯示字母、數(shù)字、符號等點陣式LCD,可以顯示2行,每行顯示16個ASCII字符,并且可以自定義圖形,只需要寫入相對應(yīng)字符的ASCII碼就可以顯示[5](見表1)。
根據(jù)液晶接口信號引腳說明,完成液晶和CPU的電路連接(如圖1所示)。
根據(jù)電路的連接,在程序中完成管腳的定義:
#define rs (1<<8)
#define rw (1<<9)
#define en (1<<10)
#define busy (1<<7)
根據(jù)手冊管腳的接口信號說明,確定和液晶相連接的LPC2106的引腳為輸入輸出IO口,同時將與液晶連接的CPU引腳定義為輸出IO口的類型:
PINSEL0=0x00000000; //設(shè)置所有引腳連接GPIO
PINSEL1=0x00000000;
IO0DIR=0x7ff; //設(shè)置P0.0—P0.10為輸出IO口
1602液晶的D0~D7端為8位數(shù)據(jù)口,進行數(shù)據(jù)傳送,而RS、R/W、E端則配合可以做出不同的操作[5],對1602進行操作主要有4種,如下:{1}讀狀態(tài),輸入:RS=L,RW=H,E=H。輸出:D0~D7=狀態(tài)字。{2}寫指令,輸入:RS=L,RW=L,D0~D7=指令,E=高脈沖。輸出:無。{3}讀數(shù)據(jù),輸入:RS=H,RW=H,E=H。輸出:D0~D7=數(shù)據(jù)。{4}寫數(shù)據(jù),輸入:RS=H,RW=L,D0~D7=數(shù)據(jù),E=高脈沖。輸出:無。
在進行讀操作的時候,RW置于1,RS則根據(jù)讀的內(nèi)容(狀態(tài)或數(shù)據(jù))置為1或0,E置為1,可以在數(shù)據(jù)口讀到正確的數(shù)據(jù),在將E置為1之后,就可以緊跟著指令去讀取數(shù)據(jù),在讀到數(shù)據(jù)后,再將E置為0。
在進行寫操作的時候,RW要置為0,RS根據(jù)寫的內(nèi)容不同(指令或數(shù)據(jù))置為1或0,同時在將E置為1之前,要先將數(shù)據(jù)送到數(shù)據(jù)口上,然后將E置為1,經(jīng)過一定的延時后,再將E置為0,在這個時間段內(nèi)必須保證數(shù)據(jù)口上的數(shù)據(jù)穩(wěn)定不變,且為有效的數(shù)據(jù)。
從上文可以看出,如果想對1602進行何種操作,只要按其相對應(yīng)的操作規(guī)程來做即可。
雖然以上有4種操作,但實際上歸類起來只有2種,一種讀一種寫,并且進行讀或?qū)懚家M行數(shù)據(jù)的傳送。
液晶狀態(tài)字說明如圖2所示。
用CPU來控制LCD模塊的方式十分簡單,LCD模塊的內(nèi)部可以看成2組寄存器,一個為指令寄存器,另一個為數(shù)據(jù)寄存器,由RS引腳來控制。所有對指令寄存器或數(shù)據(jù)寄存器的存取均需檢查LCD內(nèi)部的忙碌標志STA7,此標志用來告知LCD內(nèi)部正在工作,并不允許接收任何的控制命令。而此位的檢查可以令RS=0,用讀取D7來加以判斷。當D7為0時,才可以寫入指令或數(shù)據(jù)寄存器。因此,在對控制器每次進行讀寫操作之前,都必須進行讀寫檢測,確保STA7為0。
根據(jù)手冊的要求,編寫、讀寫檢測函數(shù):
/****************************************************************************
* 名稱:ChkBusy( )
* 功能:檢查總線是否忙
****************************************************************************/
void ChkBusy( )
{
IO0DIR=0x700;
while(1)
{
IO0CLR=rs;
IO0SET=rw;
IO0SET=en;
if(!(IO0PIN & busy))break;
IO0CLR=en;
}
IO0DIR=0x7ff;
}
代碼說明:
根據(jù)讀狀態(tài),輸入RS=L,RW=H,E=H; 輸出D0~D7狀態(tài)字的定義。為了能讀出D7的狀態(tài),要使RS=L,RW=H,E=H,因此定義IO0DIR=0x700,使P0.8-P0.10為輸出IO口,而P0.0-P0.7輸入IO口。
忙檢測完成后,需要對LCD1602輸入指令和數(shù)據(jù),因此定義IO0DIR=0x7ff,將P0.0-P0.10全部定義為輸出IO口。
在對液晶進行忙檢測后,就可以對液晶進行讀寫操作。寫操作分為寫指令與寫數(shù)據(jù)2種操作,寫指令是定義對液晶進行何種操作,寫數(shù)據(jù)是將數(shù)據(jù)傳遞給1602液晶。對液晶進行寫操作一般是先執(zhí)行寫操作,然后再寫數(shù)據(jù)。寫指令與寫數(shù)據(jù)相對應(yīng)的函數(shù)如下:
/****************************************************************************
* 名稱:WrOp( )
* 功能:寫指令函數(shù)
****************************************************************************/
void WrOp(uint8 dat)
{
ChkBusy( );
IO0CLR=rs; //全部清零
IO0CLR=rw;
IO0CLR=0xff; //先清零
IO0SET=dat; //再送數(shù)
IO0SET=en;
IO0CLR=en;
}
通過寫指令函數(shù)完成對液晶的寫操作。
寫數(shù)據(jù)函數(shù):
/****************************************************************************
* 名稱:WrDat()
* 功能:寫數(shù)據(jù)函數(shù)
****************************************************************************/
void WrDat(uint8 dat) //讀數(shù)據(jù)
{
ChkBusy();
IO0SET=rs;
IO0CLR=rw;
IO0CLR=0xff; //先清零
IO0SET=dat; //再送數(shù)
IO0SET=en;
IO0CLR=en;
}
LCD1602手冊中液晶初始化的要求如圖3所示。
在使用1602之前,必須對其進行初始化操作,初始化過程是往1602固定寫入一定的指令,里面包括指定使用模式、清屏等[5]。LPC2106晶振為11.0592 MHz,為了能準確地延時,可能通過調(diào)用延時函數(shù)完成延時。
/*****************************************************************************
*名稱:DelayNS( )
*功能:長軟件延時
******************************************************************************/
void delay(uint8 z)
{
uint8 x,y;
for(x=z;x>0;x--)
for(y=200;y>0;y--) ;
}
/****************************************************************************
* 名稱:lcd_init( )
* 功能:lcd初始化函數(shù)
****************************************************************************/
void lcd_init(void)
{
Delay(15);
WrOp(0x38);
Delay(5);
WrOp(0x38);
Delay(5);
WrOp(0x38); //顯示模式設(shè)置
Delay(5);
WrOp(0x08); //顯示關(guān)屏
WrOp(0x01); //顯示清屏
WrOp(0x06); //光標加1
WrOp(0x0c); //開顯示
}
在1602上,分為二行,每行有16個字符位置,如何在我們需要的位置上顯示出對應(yīng)的字符呢?可由RAM地址映射圖及數(shù)據(jù)指針設(shè)置,確定液晶顯示的位置(如圖4所示)。
要顯示字符時先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符:比如第二行第一個字符的地址是40 H,那么是否直接寫入40H就可以將光標定位在第二行第一個字符的位置呢?這樣不行,因為寫入顯示地址時要求最高位D7恒定為高電平1,所以實際寫入的數(shù)據(jù)應(yīng)該是01000000B(40H)+10000000B(80H)=11000000B(C0H)
圖5是1602顯示RAM緩沖區(qū)對應(yīng)的地址,要在對應(yīng)的位置顯示出字符,首先要寫入一個設(shè)置數(shù)據(jù)地址的指令碼(80H+地址),然后緊跟著寫入要顯示的數(shù)據(jù)即可。
寫指令:WrOp (0x80+地址,0)
寫數(shù)據(jù):WrDat (字符ASCII碼,1)
比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A”。
最后完成主函數(shù)的編寫使用:
/****************************************************************************
* 名稱:main()
* 功能:顯示文本
****************************************************************************/
int main(void)
{
lcd_init( );
IODIR=0x7ff; //設(shè)置為輸出
IOCLR=0x7ff;
WrOp(0xc1);
WrDat('a');
}
代碼說明:WrOp(0xc1)寫指令函數(shù)定義字符在液晶中顯示的地址為第二行第一個字符,WrDat('a')將要顯示的字符a傳遞至液晶顯示。
完成程序的編譯后將生成的.hex文件下載到proteus電路中完成仿真,液晶在第二行第一列正常顯示出字符a。
5 項目的擴展
在完成了嵌入式液晶驅(qū)動代碼的實驗后,還可以引導(dǎo)學員對該項目進行擴展。
(1)如何在液晶中顯示字符串?
為了能夠顯示字符串,可編寫字符串顯示函數(shù):
/****************************************************************************
* 名稱:DisText( )
* 功能:顯示文本函數(shù)
****************************************************************************/
void DisText(uint8 addr,uint8 *p)
{
WrOp(addr);
while(*p !='\0')WrDat(*(p++));
}
(2)引導(dǎo)學員修改程序:如何讓液晶上顯示的字符動態(tài)移動顯示?
(3)如何將ARM中LCD1602液晶的顯示代碼移植到其他的CPU中(以移植到8051為例),讓學員感受到C語言作為高級語言的優(yōu)勢。
(4)在項目中,針對元件技術(shù)手冊引導(dǎo)學員進行其他課程的實驗:如由元件外形尺寸,引導(dǎo)學生在設(shè)計PCB時根據(jù)手冊上的元件外形尺寸設(shè)計LCD1602的元件PCB封裝。
6 結(jié)論
本文通過對國內(nèi)嵌入式系統(tǒng)崗位的分析,針對國內(nèi)嵌入式系統(tǒng)教學、培訓的情況,通過LPC2106驅(qū)動LCD1602液晶的項目,系統(tǒng)地展現(xiàn)了基于元件技術(shù)手冊進產(chǎn)品研發(fā)的方法,探索了基于元件技術(shù)手冊來進行新產(chǎn)品開發(fā)的培訓新思路,對拓展國內(nèi)外嵌入式系統(tǒng)教學提供了新的課程培訓思路。
參 考 文 獻
[1]黃?,摚柘喑?,何華光.嵌入式技術(shù)課程的教學探討[J].廣西大學學報(哲學社會科學版),2007,29(5):77-78.
[2]潘曉寧.高職高專院校嵌入式系統(tǒng)課程教學方法的探討[J].職業(yè)教育研究,2007(8):24-25.
[3]張其亮,韓斌.“嵌入式系統(tǒng)”課程的實驗教學研究[J].實驗室研究與探索,2009,28(6):132-133.
[4]倪蘊濤.基于嵌入式系統(tǒng)實驗課程教學方法改革和教學思路探索的研究[J].牡丹江教育學院學報,2007(4):130-131.
[5]趙亮.液晶顯示模塊LCD1602應(yīng)用[J].電子制作,2007(3):58-59.
[責任編輯:鐘聲賢]