色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

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


          //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://cafeforensic.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了,陷入死循環(huán)。當用while(0) 時反而能正常工作,不知道有沒有人能解釋
          E = 0;
          _nop_();
          }
          /********************************************************/
          /*根據設定的坐標數據,定位LCM上的下一個操作單元位置 */
          /********************************************************/
          void Locatexy(void)
          {
          uchar x,y;
          switch (Col&0xc0) /* col.and.0xC0 */
          { /*條件分支執(zhí)行 */
          case 0: {BusyL();break;}/*左區(qū) */
          case 0x40: {BusyR();break;}/*右區(qū) */
          }
          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(); /*坐標定位,返回時保留分區(qū)狀態(tài)不變 */
          RS = 1; /*數據輸出*/
          RW = 1; /*讀入 */
          DataPort = 0xFF; //輸出0xff以便讀取正確
          E = 1; /*讀入到LCM*/
          _nop_();
          DataByte = DataPort; /*數據讀出到數據口P1 */
          E = 0;
          _nop_();
          return DataByte;
          }
          /***************************/
          /*寫數據 */
          /***************************/
          void WriteData( uchar DataByte )
          {
          Locatexy(); /*坐標定位,返回時保留分區(qū)狀態(tài)不變 */
          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字節(jié)(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]=