新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 自制單片機之七……LCD12864的驅動之源代碼

        自制單片機之七……LCD12864的驅動之源代碼

        作者: 時間:2016-11-13 來源:網絡 收藏
        今天將LCD12864的源代碼發上來。


        //LCD12864
        //**********************************************************
        //連線表: CPU=89C51 SysClock=12MHz *
        //RS=P1.0 R/W=P1.1 E=P1.2 CS1=P1.3 CS2=P1.4 *
        //DB0-DB7=P0.0-P0.7 /Reset=InBoard *
        //**********************************************************
        #include
        #include
        #include
        #include
        #include
        #define uchar unsigned char
        #define uint unsigned int
        /********************引腳定義********************/
        #define DataPort P3 //LCD128*64 I/O 信號管腳
        sbit RS =P2^0; //數據指令
        sbit RW =P2^1; //讀寫
        sbit E =P2^2; //使能
        sbit CSL =P2^3; //左片選
        sbit CSR =P2^4; //右片選
        uchar Page; //頁 地址
        uchar Col; //列 地址
        uchar code BMP1[]; //一幅圖
        uchar code HZK_12[]; //12×12陣點字模
        uchar code ASC_5x7[]; //5×7陣點字模
        uchar str[4];

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

        /********************函數定義*******************/
        void BusyL(void); //左屏檢測忙
        void BusyR(void); //右屏檢測忙
        void CheckBusy(void); //讀取忙信號
        void Delay(uint MS); //延時
        void Locatexy(void); //將屏幕橫向0-12縱向0-7轉換成左、右屏的的X、Y
        void WriteCommandL( uchar CommandByte ); //向左屏寫入指令
        void WriteCommandR( uchar CommandByte ); //向右屏寫入指令
        uchar ReadData( void ); //讀數據
        void WriteData( uchar DataByte ); //寫數據
        void LcmClear( void ); //清屏
        void LcmInit( void ); //初始化
        void LcmPutBMP( uchar *puts ); //顯示一幅圖
        void LcmReverseBMP( void ); //將整屏反顯
        void LcmPutHZ_12( uchar x,uchar y,uchar HZcode ); //在屏幕上任意點顯示一個12×12漢字
        uchar * uchartostr(unsigned char unm); //將值轉成字符串
        void LcmPutAsc( uchar asc ); //顯示一個5×7的ASC字符
        void LcmPutstr( uchar row,uchar y,uchar * str ); //在設定位置顯示字符串
        void LcmPutpoint( uchar ro,uchar lie,uchar colour ); //在設定位置顯示一個點

        /***************************/
        /*檢查Busy */
        /***************************/
        void BusyL(void)
        {
        CSL= 1;
        CSR= 0;
        CheckBusy();
        }
        void BusyR(void)
        {
        CSL= 0;
        CSR= 1;
        CheckBusy();
        }
        void CheckBusy(void)
        {
        RS = 0; //指令
        RW = 1;
        DataPort= 0xFF; //輸出0xff以便讀取正確
        E = 1;
        _nop_();
        while(0); //DataPort & 0x80); //Status Read Bit7 = BUSY 這地方有點問題,用了while(//DataPort & 0x80)后就一直讀不到0了,陷入死循環。當用while(0) 時反而能正常工作,不知道有沒有人能解釋
        E = 0;
        _nop_();
        }
        /********************************************************/
        /*根據設定的坐標數據,定位LCM上的下一個操作單元位置 */
        /********************************************************/
        void Locatexy(void)
        {
        uchar x,y;
        switch (Col&0xc0) /* col.and.0xC0 */
        { /*條件分支執行 */
        case 0: {BusyL();break;}/*左區 */
        case 0x40: {BusyR();break;}/*右區 */
        }
        x = Col&0x3F|0x40; /* col.and.0x3f.or.Set Y Address*/
        y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */
        CheckBusy(); /* waitting for enable */
        RS = 0; //指令
        RW = 0; //寫
        DataPort = y; //設置頁面地址
        E = 1;
        _nop_();
        E = 0;
        _nop_();
        CheckBusy(); /* waitting for enable */
        RS = 0;
        RW = 0;
        DataPort = x; //設置列地址
        E = 1;
        _nop_();
        E = 0;
        _nop_();
        }
        /***************************/
        /*寫指令 */
        /***************************/
        void WriteCommandL( uchar CommandByte )
        {
        BusyL();
        DataPort = CommandByte;
        RS = 0; //指令
        RW = 0;
        E = 1;
        _nop_();
        E = 0;
        _nop_();
        }
        void WriteCommandR( uchar CommandByte )
        {
        BusyR();
        DataPort = CommandByte;
        RS = 0; //指令
        RW = 0;
        E = 1;
        _nop_();
        E = 0;
        _nop_();
        }
        /***************************/
        /*讀數據 */
        /***************************/
        uchar ReadData( void )
        {
        uchar DataByte;
        Locatexy(); /*坐標定位,返回時保留分區狀態不變 */
        RS = 1; /*數據輸出*/
        RW = 1; /*讀入 */
        DataPort = 0xFF; //輸出0xff以便讀取正確
        E = 1; /*讀入到LCM*/
        _nop_();
        DataByte = DataPort; /*數據讀出到數據口P1 */
        E = 0;
        _nop_();
        return DataByte;
        }
        /***************************/
        /*寫數據 */
        /***************************/
        void WriteData( uchar DataByte )
        {
        Locatexy(); /*坐標定位,返回時保留分區狀態不變 */
        RS = 1; /*數據輸出*/
        RW = 0; /*寫輸出 */
        DataPort = DataByte; /*數據輸出到數據口 */
        E = 1; /*寫入到LCM*/
        _nop_();
        E = 0;
        _nop_();
        }
        void LcmClear( void )
        {
        Page = 0;
        Col = 0;
        for(Page=0;Page<8;Page++)
        for(Col=0;Col<128;Col++)
        WriteData(0);
        }
        void LcmInit( void )
        {
        Delay(200); //等待復位
        WriteCommandL(0x3f); //開顯示
        WriteCommandR(0x3f);

        WriteCommandL(0xc0); //設置起始地址=0
        WriteCommandR(0xc0);
        WriteCommandL(0x3f); //開顯示
        WriteCommandR(0x3f);
        LcmClear();
        Col = 0;
        Page= 0;
        Locatexy();
        }

        void LcmPutBMP( uchar *puts )
        {
        uint X=0;
        Page = 0;
        Col = 0;
        for(Page=0;Page<8;Page++)
        {
        for(Col=0;Col<128;Col++)
        {
        WriteData( puts[X] );
        X++;
        }
        }
        }
        void LcmReverseBMP( void )
        {
        uchar temp;
        Page = 0;
        Col = 0;
        for(Page=0;Page<8;Page++)
        {
        for(Col=0;Col<128;Col++)
        {
        temp = ReadData(); //空讀一次
        temp = ReadData();
        temp = ~temp;
        WriteData(temp);
        }
        }
        }
        void LcmPutHZ_12( uchar x,uchar y,uchar HZcode )
        {
        uchar offset,Rd,Wt,m,tmp,i;
        uint n;
        if(x<117&y<53) //x為橫向起始點數0-117,超過117就顯示不全一個漢字了。y同理。
        {
        Page=(y & 0x38)>>3; //將豎向的點陣數y轉換成頁數
        Col=x; //橫向的X就是LCD的列數。
        n = 0x18*HZcode; //一個漢字24字節(18H),HZcode為字庫序號。n就是要顯示漢字的起始地址
        offset=y&0x07;    //將顯示該頁的豎向偏移量。
        if(offset<5) //如果偏移量小于5,那么在豎向用兩個頁的范圍就可顯示出漢字了。
        {

        for(i=12;i>0;i--)
        {
        Rd=ReadData();
        Rd=ReadData(); //讀出LCD該Page、Col位置的上半個數據。
        m=HZK_12[n]; //讀出漢字模第n的數據。
        Wt=Rd&(0xff>>(8-offset))|(m< WriteData(Wt); //再將Wt寫回LCD
        Page++; //頁位置移到下半個漢字位置
        n++;
        tmp=m; //將取得的上半個字模數據交給tmp
        m=HZK_12[n]; //取下半個字模數據
        Rd=ReadData(); //讀LCD下半個字模數據
        Rd=ReadData();
        Wt=tmp>>(8-offset)|(m<|(rd&(0xff<<(offset+4))); br="">|(rd&(0xff<<(offset+4))); br=""> WriteData(Wt);//再寫回LCD
        Col++;//列數增加一
        Page--;//將頁數返回上半個漢字位置。
        n++;
        }
        }
        else //如果偏移量大于或等于5,豎向就要用3個頁的范圍來顯示一個漢字了。
        {
        for(i=12;i>0;i--)
        |(rd&(0xff<<(offset+4)));>|(rd&(0xff<<(offset+4)));>

        {
        Rd=ReadData();
        Rd=ReadData(); //讀取LCD上漢字上部位置的原來數據。
        m=HZK_12[n]; //讀取漢字模數據
        Wt=Rd&(0xff>>(8-offset))|(m< WriteData(Wt); //寫回
        Page++; //到下一頁即漢字中部位置
        n++;
        tmp=m; //上半個字模交給tmp
        m=HZK_12[n]; //讀取下半個字模
        Wt=tmp>>(8-offset)|(m< WriteData(Wt); //寫回
        Page++; //到下一頁即漢字下部位置
        n++;
        Rd=ReadData();
        Rd=ReadData(); //讀取LCD上漢字下部位置的原來數據
        Wt=m>>(8-offset)|(Rd&(0xff<<(offset-4))); //嵌入
        WriteData(Wt); //寫回
        Page=Page-2;//恢復位置
        Col++; //修正下一個漢字的起始位置
        }
        }
        }
        }

        uchar * uchartostr(uchar unm)
        {
        uchar x00,xx,x0,x,n;
        x00=unm/100;
        xx=unm%100;
        x0=xx/10;
        x=xx%10;
        n=0;
        if(x00!=0)
        { str[n]=x00+48; //值加48即為字符
        n++;
        }
        if(!(x00==0&x0==0))
        { str[n]=x0+48;
        n++;
        }
        str[n]=x+48;
        n++;
        str[n]=

        主站蜘蛛池模板: 洞口县| 隆尧县| 保定市| 松滋市| 拜城县| 龙南县| 商洛市| 怀来县| 淮阳县| 内江市| 吴旗县| 台中县| 湘潭市| 定州市| 乌兰浩特市| 威海市| 舒城县| 巴彦县| 门头沟区| 高邑县| 高陵县| 开平市| 鄢陵县| 滕州市| 漳浦县| 务川| 柘城县| 锦州市| 剑川县| 大同市| 泰安市| 临汾市| 佛冈县| 新闻| 武义县| 潍坊市| 雷波县| 龙陵县| 砚山县| 南川市| 汉源县|