新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > LPC2134學習日志 -- LCD12864學習

        LPC2134學習日志 -- LCD12864學習

        作者: 時間:2016-11-21 來源:網絡 收藏
        由于項目所需,所以這段時間,抽空學了一下LPC2134,它是基于ARM7核的微處理器,內部有128K的flash與16k的RAM,所以一般的處理程序,內部空間就夠用了,當然你要上想在上面跑跑操作系統什么的,那就另當別論了。關于這個處理器其它方面的內部資料,如果你想了解,建議你好好翻翻它的數據手冊,如果你說英文太難啃,網上有大把中文的資料,當然懶貓還是建議你看英文原版,一它是廠家的資料,比較真實可靠一般不會有什么大錯,二你還可以湊這個空檔學學英語,真學好了這也是你要工資的籌碼。

        今天只是實驗一下它的IO端口功能,如何實驗,懶貓就不再從流水燈開始了,懶貓選擇從LCD12864開始,說實在看著這么大一塊屏,挺嚇人的,其實LCD也沒有那么可怕,處理好時序就能讓它乖乖的顯示,所以想寫好LCD12864的驅動首先還是要好好翻看它的數據手冊,這里懶貓就不再詳述數據手冊上的內容了。不過在這里懶貓要先啰嗦一句,想讓LCD12864正確顯示,一定要記住先清屏,其實也就是清它內部寄存器,否則初始化時它內部的RAM中不知道是什么亂七八糟的東東,一旦你沒有清屏,很可能在顯示時會出現亂碼或顯示不正常,如下圖所示:

        本文引用地址:http://www.104case.com/article/201611/319452.htm



        圖1-1 初始化時沒有加清屏函數


        其實懶貓在上大學時就試著用51寫LCD12864的驅動程序,所以這次使用還算順利,記得當時初次使用LCD12864出現這種情況,懶貓非常郁悶,以為自己的驅動程序沒有寫好,于是使勁翻看數據手冊,仔細的看時序,最后還單步調試,發現問題還是沒有解決,最后懶貓看到LCD12864中RAM時,突然想到單片機的設置變量時,初值也是隨機的,于是就想著清一下RAM,結果問題還真解決了,呵呵,當時那個興奮呀,無以言表。現在想想那時真的有點傻的可愛,網上有好多現成的程序,自己卻一個人死扣自己的程序。可惜時光如梭,轉眼間懶貓畢業就要兩年了,那些激情燃燒的歲月已漸漸遠去,卻永遠無法抹去我美好的記憶……


        好了,不費話,說一說這次測試的電路,外圍電路很簡單,沒有接什么東東,就接了一塊LCD12864,2134的晶振是12MHz的,實時時鐘頻率是32.768KHz,下面給出仿真電路圖,上面省略了很多東東,這次仿真用的是proteus7.5的版本,仿真不能代替實物,懶貓的程序都是通過實物測試通過的,仿真只是為了調試之用,如果你真想學到真本領,做項目是最好的途徑。




        圖2 電路仿真


        注意,這是仿真電路圖,實際設計中要加上電源,晶振,電位器等部件,這個電路圖只說明一下LCD與LPC2134的數據接口。


        說一下程序,程序包括main.c與display.c兩個C源程序代碼,只是簡單的測試一下lpc2134與LCD12864為后面的實驗做一個鋪墊,以后的實驗可能會用到這個驅動,由于程序東東比較多,所以就只貼出display.c這個源程序,其它的程序在附件中,如果有興趣可以下載下來查看:



        //文件名稱:display.c


        //功 能:LCD12864驅動函數


        //作 者:懶貓愛飛


        //備 注:MCU -- LPC2134


        // Crystal -- 12MHz


        // RTC -- 32.768KHz


        // 開發環境 -- RealView MDK-ARM Verxion 4.12



        #define IN_DISPLAY



        #include "config.h"


        #include "display.h"



        //LCD12864引腳配置


        #define LCD_CS1 4


        #define LCD_CS2 3


        #define LCD_RST 5


        #define LCD_DI 21


        #define LCD_RW 11


        #define LCD_EN 10



        //LCD12864操作宏定義


        #define LCD_DE() IO0SET |= 1<


        #define LCD_IE() IO0CLR |= 1<


        #define LCD_RE() IO0SET |= 1<


        #define LCD_WE() IO0CLR |= 1<


        #define LCD_EH() IO0SET |= 1<


        #define LCD_EL() IO0CLR |= 1<




        //LCD12864命令宏定義


        #define LCDSTARROW 0xC0


        #define LCDPAGE 0xB8


        #define LCDLINE 0x40




        void delay_us(uint32 us)


        {


        while(us--);


        }




        void Out_Data(uint8 Odata)


        {


        IO1CLR |= (uint32)(0xFF<<16); // 將輸出端口置0


        IO1SET |= (uint32)(Odata<<16); // 輸出要輸出的數據Odata


        }




        void Write_Data(uint8 Wdata)


        {


        LCD_DE(); // 寫數據使能


        delay_us(1); // 延時等待端口電平穩定


        LCD_WE(); // 寫命令使能


        delay_us(1); // 延時等待數據寫進端口寄存器


        Out_Data(Wdata); // 輸出要寫入LCD12864的數據


        delay_us(1); // 延時等待端口電平穩定


        LCD_EH(); // 數據在EN下降沿寫入LCD12864中


        delay_us(3); // 延時


        LCD_EL(); // EN下降沿


        delay_us(3); // 延時一下


        }




        void Write_Cmd(uint8 Wcmd)


        {


        LCD_IE(); // 寫命令使能


        delay_us(1);


        LCD_WE(); // 寫命令使能


        delay_us(1);


        Out_Data(Wcmd); // 寫入命令


        delay_us(1);


        LCD_EH(); // 數據在EN下降沿寫入LCD12864中


        delay_us(3);


        LCD_EL(); // EN下降沿


        delay_us(3);


        }




        void Init_LCDIO(void)


        {


        IO0DIR |= (1< // 初始端口方向


        |(1<

        |(1<

        |(1<

        |(1<

        |(1<

        IO0SET |= (1<

        IO0CLR |= 1< // 初始化時EN腳置低


        IO0CLR |= 1< // 初始化時先復位一下


        delay_us(50);


        IO0SET |= 1< // 再重新啟動LCD12864


        delay_us(50);


        IO0SET |= (1<

        Write_Cmd(0x3F); //開顯示, 關顯示為 -- 0x3e


        Write_Cmd(0x38); // 8位形式,兩行字符


        Write_Cmd(0x0F); // 開顯示


        Write_Cmd(0x01); // 清屏


        Write_Cmd(0x06); // 畫面不動,光標右移


        Write_Cmd(0xC0); // 設置起始行


        }




        void Show_Row(uint8 ucPage,uint8 ucLine,uint8 ucWidth,uint8 const *ucaRow)


        {


        uint8 ucCount = 0;


        if(ucLine<64)


        {


        IO0SET |= 1< // 選通左屏


        IO0CLR |= 1<

        Write_Cmd(LCDPAGE+ucPage); // 設定頁號


        Write_Cmd(LCDLINE+ucLine); // 設定列號


        Write_Cmd(0x34);


        if(ucLine+ucWidth<64) // 位于左半屏


        {


        for(ucCount = 0;ucCount


        {


        Write_Data(*(ucaRow+ucCount)); // 寫入數據


        }


        }


        else // 跨越兩個半屏 先寫完左半屏


        {


        for(ucCount=0;ucCount<64-ucLine;ucCount++)


        {


        Write_Data(*(ucaRow+ucCount)); // 寫入數據


        }



        IO0CLR |= 1< // 再寫右半屏


        IO0SET |= 1<

        Write_Cmd(LCDPAGE+ucPage); // 設定頁號


        Write_Cmd(LCDLINE); // 設定列號


        Write_Cmd(0x34);


        for(ucCount=64-ucLine;ucCount


        {


        Write_Data(*(ucaRow+ucCount));// 寫入數據


        }


        }


        }


        else // 位于右半屏


        {


        IO0CLR |= 1<


        IO0SET |= 1<

        Write_Cmd(LCDPAGE+ucPage); // 設定頁號


        Write_Cmd(LCDLINE+ucLine-64); // 設定列號


        Write_Cmd(0x34);


        for(ucCount=0;ucCount


        {


        Write_Data(*(ucaRow+ucCount)); // 寫入數據


        }


        }


        }




        void Show_Word(uint8 ucPage,uint8 ucLine,uint8 const *ucaChinMap)


        {


        Show_Row(ucPage,ucLine,16,ucaChinMap); // 漢字上半部分


        Show_Row(ucPage+1,ucLine,16,ucaChinMap+16); // 漢字下半部分


        }




        void Display_HZ(uint8 pagenum,uint8 colnum,uint8 num)


        {


        //uint8 k;


        uint8 const *p1;


        //k=colnum*16;


        p1=hz_mode[num];


        Show_Word(pagenum,colnum,p1);


        }



        void Show_Char(unsigned char ucPage,unsigned char ucLine,unsigned char const *ucaCharMap)


        {


        Show_Row(ucPage,ucLine,8,ucaCharMap);


        Show_Row(ucPage+1,ucLine,8,ucaCharMap+8);


        }



        void Clear_Screen()


        {


        uint8 i,j;


        for(i=0;i<8;i+=2) //共8頁


        {


        for(j=0;j<128;j+=8) //共128列


        {


        Show_Char(i,j,CHAR_B);


        }


        }


        }



        void Init_LCD(void)


        {


        Init_LCDIO(); // 初始化LCD接口


        Clear_Screen(); // 要先清屏,不然會顯示不正常




        Display_HZ(2,0,10); // 懶


        Display_HZ(2,16,11); // 貓


        Display_HZ(2,32,12); // 愛


        Display_HZ(2,48,13); // 飛



        Display_HZ(3,64,14); // 學


        Display_HZ(3,80,15); // 習


        Display_HZ(3,96,16); // 日


        Display_HZ(3,112,17); // 志


        }


        當然這個程序還不完善,還沒顯示圖片的函數,還沒有菜單等功能,不過這些以后會慢慢加上的,現在只是在LPC2134中裸奔,主要是為了了解一下它內部結構與內部資源,以后的日志中會涉及到ucos或其它嵌入式系統,這個以后在日志中慢慢總結。


        好了,今天說就先到這吧




        關鍵詞: LPC2134LCD1286

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 确山县| 深泽县| 泰州市| 临澧县| 余姚市| 石屏县| 福清市| 仙游县| 平凉市| 北京市| 白山市| 安顺市| 涿鹿县| 建德市| 屯留县| 灌云县| 定兴县| 兴安盟| 比如县| 甘泉县| 乐昌市| 牙克石市| 隆德县| 青岛市| 简阳市| 福州市| 道真| 武夷山市| 长白| 安庆市| 大足县| 广平县| 莱州市| 白玉县| 韩城市| 阿克| 富川| 临西县| 桃园市| 潼关县| 子洲县|