久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 14149|回復: 2
打印 上一主題 下一主題
收起左側

51單片機的LCD1602與12864函數-C

[復制鏈接]
跳轉到指定樓層
樓主
ID:70941 發表于 2015-3-21 05:00 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
      
LCD1602和LCD12864的函數庫,包括并行與串行

lcd12864
帶中文字庫的128X64 是一種具有4 位/8 位并行、2 線或3 線串行多種接口方式,內部含有國標一級、二級簡體 中文字庫的點陣圖形液晶顯示模塊;其顯示分辨率為128×64, 內置8192 個16*16 點漢字,和128 個16*8 點ASCII 字符 集.利用該模塊靈活的接口方式和簡單、方便的操作指令,可構成全中文人機交互圖形界面。可以顯示8×4 行16×16 點 陣的漢字. 也可完成圖形顯示.低電壓低功耗是其又一顯著特點。由該模塊構成的液晶顯示方案與同類型的圖形點陣液晶 顯示模塊相比,不論硬件電路結構或顯示程序都要簡潔得多,且該模塊的價格也略低于相同點陣的圖形液晶模塊。
LCD1602
1602液晶也叫1602字符型液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。它由若干個5X7或者5X11等點陣字符位組成,每個點陣字符位都可以顯示一個字符,每位之間有一個點距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用,正因為如此所以它不能很好地顯示圖形(用自定義CGRAM,顯示效果也不好)。
1602LCD是指顯示的內容為16X2,即可以顯示兩行,每行16個字符液晶模塊(顯示字符和數字)。



LCD1602基礎驅動函數#ifndef __LCD1602_JCK_C__
#define __LCD1602_JCK_C__
/************************************************
**                                              **
**            六哥LCD1602基礎函數庫              **
**                                              **
**************************************************/

//使用請注意定義引腳


#include"yscx.c"


/*****************************************************************
              LCD1602判忙函數
******************************************************************/
void LCD1602_PM(void)
{
unsigned char temp1;//狀態信息(判斷是否忙)
LCD1602_SJ=0xFF;//記得在包含該頭文件前,定義引腳
LCD1602_RS=0; //記得在包含該頭文件前,定義引腳
LCD1602_RW=1; //記得在包含該頭文件前,定義引腳
LCD1602_E=1;  //記得在包含該頭文件前,定義引腳
do
   {temp1 = LCD1602_SJ;//記得在包含該頭文件前,定義引腳
    LCD1602_SJ=0xFF;
    }
while(temp1&0x80);
LCD1602_E=0;//記得在包含該頭文件前,定義引腳
YS_us(1);        //
}
/*------------------------------------------------
              LCD1602寫入命令函數
------------------------------------------------*/
void LCD1602_XZL(unsigned char ml)
{
LCD1602_PM(); //忙則等待
LCD1602_RS= 0; //記得在包含該頭文件前,定義引腳
LCD1602_RW= 0; //記得在包含該頭文件前,定義引腳
LCD1602_E = 1;//記得在包含該頭文件前,定義引腳
LCD1602_SJ=ml; //記得在包含該頭文件前,定義引腳
YS_us(1);//稍作延時給LCD反應的時間
LCD1602_E = 0;//記得在包含該頭文件前,定義引腳
if(ml==0x01|ml==0x02) YS_ms(2);//清屏和地址歸位大概需2ms時間處理
YS_us(35);//其他指令大概需35us
}
/*------------------------------------------------
              LCD1602寫入數據函數
------------------------------------------------*/
void LCD1602_XSJ(unsigned char sj)
{
LCD1602_PM(); //忙則等待
LCD1602_RS=1; //記得在包含該頭文件前,定義引腳
LCD1602_RW=0; //記得在包含該頭文件前,定義引腳
LCD1602_E= 1;//記得在包含該頭文件前,定義引腳
LCD1602_SJ=sj; //記得在包含該頭文件前,定義引腳
YS_us(1);//稍作延時給LCD反應的時間
LCD1602_E= 0;//記得在包含該頭文件前,定義引腳
}  

/*------------------------------------------------
              LCD1602初始化函數
------------------------------------------------*/
void LCD1602_CSH(void)
{
  LCD1602_XZL(0x38);    /*顯示模式設置*/
  LCD1602_XZL(0x08);    /*顯示光標移動設置*/   
  LCD1602_XZL(0x01);    /*顯示開及光標設置*/
  LCD1602_XZL(0X06);
  LCD1602_XZL(0X0c);
  }


#endif

LCD1602顯示函數

#ifndef __LCD1602_XSK_C__
#define __LCD1602_XSK_C__

/************************************************
*******                                 *********
*******       六哥LCD1602顯示函數庫     *********
*******                                 *********
************************************************/


#include"yscx.C"
#include"LCD1602_JCK_cx.C"

//為保證顯示數制時的運行效率,制作了0—9,A—F的ascll碼表
unsigned char  code ascll1602[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};


/******************************************************
***************LCD1602數制顯示(十或十六)************
*******************************************************
sj:需要顯示的數據
ml:顯示地址設定
xsfs:顯示方式,進制和小數點的判斷依據,
*/
void LCD1602_SZXS(signed long sj,unsigned char xsfs,ml)///wei為1輸出十六進制,否則輸出十進制
{
unsigned long xc;     //顯示緩存                                 
unsigned char a;
bit xsd,fs,bf=0;
xsd=0;
fs=0;

LCD1602_XZL(0x04);//設置光標向左移
LCD1602_XZL(ml);

if(xsfs>10)
    {a=16;             //輸出十六進制
     LCD1602_XSJ(0x48);//顯示H
     xsfs=0;}          //
   else
      {a=10;   //否則輸出十進制
       if(xsfs!=0) xsd=1;//顯示小數點使能
       if(sj<0)
          {sj=~sj+1;
           fs=1;}       //顯示負號使能
       }
xc=sj;

if(xc!=0)       //顯示數據不為0;則顯示
    {while(xsd)            //判是否需要顯示小數
        {if(xc!=0)         //是否還需要計算
            {ml=xc%a;
             if(bf|ml!=0)  //小數部分為0不需要顯示
                {LCD1602_XSJ(ascll1602[ml]); //取數的ascll碼并顯示
                 bf=1;     //小數部分不為0標志,小數部分數字有效
                 }
             xc/=a;        //取剩下的數
             }
           else if(bf) LCD1602_XSJ(0x30);//判是否需要補0
             else;            //小數部分無效,不需要補0

         xsfs--;
         if(xsfs==0)                    //小數點位數減一
            {xsd=0;                     //小數計算部分結束標志
             if(bf) LCD1602_XSJ(0x2e);  //小數部分存在有效數字則顯示小數點
             }
         }
     }
////////////整數顯示部分////////////////////////////////////////////
do
   {LCD1602_XSJ(ascll1602[xc%a]); //取數的ascll碼并顯示
    xc/=a;        
    }
while(xc!=0);
      
if(fs) LCD1602_XSJ(0x2d);//判是否需要顯示負號

LCD1602_XZL(0x06);//還原光標移動方向

}



/********************************
     LCD1602LCD1602字符顯示程序
*********************************/


void LCD1602_ZFXS(unsigned char *SJ,t,ml)/*h:行,SJ:字符串指針,t:間隔時間*/
{
LCD1602_XZL(ml); //寫指令  

while(*SJ)//是否顯示完
    {
     LCD1602_XSJ(*SJ);//寫數據
     SJ++;        //取下一個字符
     YS_ms(t);    //延時
     }
}

#endif


LCD12864基礎驅動函數并行

#ifndef __LCD12864_JCK_C__
#define __LCD12864_JCK_C__
/************************************************
**                                             **
**            六哥LCD12864基礎函數庫            **
**                                              **
**************************************************/

//使用請注意定義引腳
//通訊方式為并口PSB=1,在設計電路時就把PSB端焊好,節省I/O
#include"yscx.c"

/********************測忙碌**********************/
//測忙碌子程序
//RS=0,RW=1,E=H,D0-D7=狀態字
/************************************************/
void LCD12864_PM(void)
{
unsigned char temp1;//狀態信息(判斷是否忙)
LCD12864_RS=0;    // 記得在包含該頭文件前,定義引腳
LCD12864_RW=1;    // 記得在包含該頭文件前,定義引腳
LCD12864_E=1;    //記得在包含該頭文件前,定義引腳
do
   {temp1 = LCD12864_SJ;//記得在包含該頭文件前,定義引腳
    LCD12864_SJ=0xFF;
    }
while(temp1&0x80);
LCD12864_E=0;      //記得在包含該頭文件前,定義引腳
YS_us(1);        //

}
/********************寫命令**********************/
//寫命令子程序
//
/************************************************/
void LCD12864_XZL(unsigned char ml)/*寫命令*/
{
LCD12864_PM();
LCD12864_RS=0; //記得在包含該頭文件前,定義引腳
LCD12864_RW=0; //記得在包含該頭文件前,定義引腳
LCD12864_E=1;  //記得在包含該頭文件前,定義引腳
LCD12864_SJ=ml;//記得在包含該頭文件前,定義引腳
YS_us(0);//稍作延時給LCD反應的時間
LCD12864_E=0;  //記得在包含該頭文件前,定義引腳
if(ml==0x01|ml==0x02) YS_ms(3);//清屏和地址歸位大概需3ms時間處理
YS_us(50);//其他指令大概需50us
}
/********************寫數據**********************/
//寫數據子程序
//
/************************************************/
void LCD12864_XSJ(unsigned char sj)
{
LCD12864_PM();
LCD12864_RS=1; //記得在包含該頭文件前,定義引腳
LCD12864_RW=0; //記得在包含該頭文件前,定義引腳
LCD12864_E=1;  //記得在包含該頭文件前,定義引腳
LCD12864_SJ=sj;//記得在包含該頭文件前,定義引腳
YS_us(0);//稍作延時給LCD反應的時間
LCD12864_E=0;  //記得在包含該頭文件前,定義引腳
}

/********************初始化**********************/
//復位、通訊方式選擇
/************************************************/
void LCD12864_CSH(void)
{
  //通訊方式為并口PSB=1,在設計電路時就把PSB端焊好,節省I/O
//LCD12864_XZL(0x34); //34H--擴充指令操作
LCD12864_XZL(0x30);  //功能設置,一次送8位數據,基本指令集
LCD12864_XZL(0x0C);  //0000,1100 整體顯示,游標off,游標位置off
LCD12864_XZL(0x01);  //0000,0001 清DDRAM
LCD12864_XZL(0x02);  //0000,0010 DDRAM地址歸位
LCD12864_XZL(0x80);  //1000,0000 設定DDRAM 7位地址000,0000到地址計數器AC
LCD12864_XZL(0x06);
}


#endif


LCD12864基礎驅動函數串行

#ifndef __LCD12864_JCK_CX_C__
#define __LCD12864_JCK_CX_C__
/************************************************
**                                             **
**            六哥LCD12864基礎函數庫            **
**                  串行                        **
**************************************************/

//使用請注意定義引腳
//通訊方式為串行通信PSB=0,在設計電路時就把PSB端焊好,節省I/O
#include"yscx.c"
/*******************串行通信*********************
分別發送三個字節,11111AB0,DDDD0000,SSSS000,
  A:即表示并行的RW,1為讀,0為寫
  B:即表示并行的RS,1為數據,0為指令
  D:即表示并行的高四位數據
  S:即表示并行的低四位數據
注:串行要把PSB端為低電平
*************************************************/
void LCD12864_CXTX(unsigned char fs,sj)
{
unsigned char i;
LCD12864_E=0;//時鐘SCLK
LCD12864_RS=1;///CS片選

do       ////LCD判忙=============
   {
    for(i=0;i<8;i++)
       {
        YS_us(1);//MCU與LCD速率匹配
        if(i<6) LCD12864_RW=1;//讀LCD數據,前6位為1;后兩位為0
          else  LCD12864_RW=0;//命令格式11111100B,0xfc
        YS_us(1);//MCU與LCD速率匹配
        LCD12864_E=1;//時鐘SCLK
        YS_us(1);//MCU與LCD速率匹配
        LCD12864_E=0;//時鐘SCLK
        }

    YS_us(5);//給LCD反應的時間
    LCD12864_E=1;//時鐘SCLK
    YS_us(1); //給LCD反應的時間     
    }
while(LCD12864_RW);//判忙只需要取最高位,而不管后面7位

LCD12864_E=0;//時鐘SCLK
LCD12864_RS=0;///CS片選
YS_us(1);//給LCD反應的時間
LCD12864_RS=1;///CS片選

for(i=0;i<24;i++)//、、、、送3字節
    {
     LCD12864_RW=fs&0x80;//數據SID
     fs<<=1;
     YS_us(1);    //MCU與LCD速率匹配
     LCD12864_E=1;       //時鐘SCLK
     YS_us(1);    //MCU與LCD速率匹配
     if(i==7) fs=sj&0xf0; //取數據高四位
     if(i==15) fs=sj<<4;  //取數據低四位
     LCD12864_E=0;       //時鐘SCLK
     YS_us(1);    //MCU與LCD速率匹配
     }
LCD12864_RS=0;///CS片選
LCD12864_E=1;//恢復高電平不影響其他用途
LCD12864_RW=1;//恢復高電平不影響其他用途
}
/********************寫命令**********************/
void LCD12864_XZL(unsigned char ml)/*寫命令*/
{
LCD12864_CXTX(0xf8,ml);//命令格式11111000B,0xf8
if(ml==0x01|ml==0x02) YS_ms(4);//清屏和地址歸位大概需4ms時間處理
YS_us(50);//其他指令大概需50us     
}
/********************寫數據**********************/
void LCD12864_XSJ(unsigned char sj)
{
LCD12864_CXTX(0xfa,sj);//命令格式11111010B,0xfa
}
/********************初始化**********************/
//復位、通訊方式選擇
/************************************************/
void LCD12864_CSH(void)
{
//LCD12864_XZL(0x34);//34H--擴充指令操作
LCD12864_XZL(0x30);  //功能設置,一次送8位數據,基本指令集
LCD12864_XZL(0x0C);  //0000,1100 整體顯示,游標off,游標位置off
LCD12864_XZL(0x01);  //0000,0001 清DDRAM
LCD12864_XZL(0x80);  //1000,0000 設定DDRAM 7位地址000,0000到地址計數器AC
LCD12864_XZL(0x06);
}


#endif



LCD12864顯示函數
#ifndef __LCD12864_XSK_C__
#define __LCD12864_XSK_C__
/************************************************
*******                                 *********
*******       六哥LCD12864顯示函數庫     *********
*******                                 *********
************************************************/

//使用請注意定義引腳


#include"LCD12864_JCK_cx.C"//包含基礎庫

//為保證顯示數制時的運行效率,制作了0—9,A—F的ascll碼表
unsigned char  code ascll12864[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};



/*****************************************************
**********LCD12864設置顯示地址函數*********************
******************************************************/
unsigned char LCD12864_SZDZ(unsigned char x,y)//
{
switch(y)
    {case 0:x|=0x80;break;
     case 1:x|=0x90;break;
     case 2:x|=0x88;break;
     case 3:x|=0x98;break;
     default:;
     }
return(x);
}


/*****************************************************
**********LCD12864數制顯示函數************************
******************************************************
sj:需要顯示的數據,取值范圍:十進制:-2147483648-2147483647,十六進制:0H-7FFFFFFFH
xsfs:顯示方式,進制和小數點的判斷依據,
x:顯示列,取值范圍0-7
y:顯示行,取值范圍0-3
*/
void LCD12864_SZXS(signed long sj,unsigned char xsfs,x,y)
{
unsigned long xc;     //顯示緩存
unsigned char d[13];
bit xsd,fs,bf=0;
xsd=0;
fs=0;

LCD12864_XZL(0x04);//設置光標左移
LCD12864_XZL(LCD12864_SZDZ(x,y));//寫入顯示地址

y=0;

if(xsfs>10)  
      {x=16;         //輸出十六進制
       d[y]=0x48;    //十六進制顯示H
       y++;
       }         //
   else
      {if(sj<0)       //十進制正負數判斷
          {sj=~sj+1;
           fs=1;}     //負號顯示使能      
       if(xsfs!=0) xsd=1;//小數點顯示使能
       x=10;
       }                //
xc=sj;

if(xc!=0)       //顯示數據不為0;則顯示
    {while(xsd)                     //判是否需要顯示小數
        {if(xc!=0)                  //是否還需要計算
            {sj=xc%x;
             if(bf|sj!=0)           //小數部分為0不需要顯示
                {d[y]=ascll12864[xc%x];
                 y++;               //取數的ascll碼并顯示
                 bf=1;              //小數部分不為0標志,小數部分數字有效
                 }
             xc/=x;                  //取剩下的數
             }
           else if(bf)
                   {d[y]=0x30;       //判是否需要補0
                    y++;}
             else;                   //小數部分無效,不需要補0

         xsfs--;
         if(xsfs==0)                    //小數點位數減一
            {xsd=0;                     //小數計算部分結束標志
             if(bf)
                {d[y]=0x2e;  //小數部分存在有效數字則顯示小數點
                 y++;}
             }
         }
     }

do
   {d[y]=ascll12864[xc%x];     //取數的ascll碼
    y++;   
    xc/=x;
    }         
while(xc!=0);

if(fs)
    {d[y]=0x2d;  //取負號ascll碼
     y++;}   

if(y&&0x01)       //如果顯示的位數為奇數
    {d[y]=0x20;    //顯示一個空格
     y++;}

x=y;
y=1;
///////////////顯示數據//////////////
do            
   {
    LCD12864_XSJ(d[y]);//顯示一個地址的前一個字符
    y--;   
    LCD12864_XSJ(d[y]);//顯示一個地址的后一個字符
    y+=3;              //跳到下一個要顯示的兩個字符
    }
while(y<x);        //判斷是否顯示完畢

LCD12864_XZL(0x06);//設置光標右移  

}


/*****************************************************
**********LCD12864字符顯示函數************************
******************************************************
*zfc:需要顯示的字符串指針,字符數不得超過64個
x:顯示列,取值范圍0-7
y:顯示行,取值范圍0-3
*/
void LCD12864_ZFXS(unsigned char *zfc,x,y)
{
unsigned char k1,k2,k3;
k3=x*2;

k1=16-k3;
k2=32-k3;
k3=48-k3;

switch(y)       //設置顯示地址x和換行標志y
    {case 0:x|=0x80;y=0;break;
     case 1:x|=0x90;y=16;break;
     case 2:x|=0x88;y=32;break;
     case 3:x|=0x98;y=48;break;
     default:;}

LCD12864_XZL(x);//寫顯示地址


while(*zfc)
    {
     if(y==k1) LCD12864_XZL(0X90);//換行判斷
      else if(y==k2) LCD12864_XZL(0X88);//換行判斷
       else if(y==k3) LCD12864_XZL(0X98);//換行判斷
        else;         
     LCD12864_XSJ(*zfc);//寫顯示數據
     y++;
/////////////判中文字符/////////
     if(*zfc>0x7f) zfc++;
       else
          {zfc++;           
           if(*zfc>0x7f && y&0x01)
              {LCD12864_XSJ(0x20);
               y++;}
            }
     }         
}


#endif

延時函數
#ifndef __yscx_C__
#define __yscx_C__
#include<intrins.h>
/*晶振頻率33Mhz的stc15系列1T單片機適用*/
/**************************************************
          x*us延時函數
    精度極高,幾乎可以忽略延時誤差
***************************************************/
void YS_us(unsigned char t)
{
for( ;t>0;t--)
    {   
     _nop_();//16*nop
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();//16*nop
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();//16*nop
     }
_nop_();//12*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//12*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//12*nop
}

/*---------------------------------------------------
          x*1ms延時函數
----------------------------------------------------*/
void YS_ms(unsigned char t)  
{
for( ;t>0;t--)
    {   
     YS_us(250);
     YS_us(250);
     YS_us(250);
     YS_us(249);
     }
}
#endif

   




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:373976 發表于 2018-7-20 09:06 | 只看該作者
這例程寫的不錯,很有功底。很有技巧性。
回復

使用道具 舉報

板凳
ID:375751 發表于 2018-7-20 12:50 | 只看該作者
這例程寫的不錯
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲成人一区 | avav在线看 | 午夜私人影院 | 在线国产一区二区 | 国内av在线 | www.久久艹 | 亚洲啊v在线 | 亚洲免费视频在线观看 | 亚洲成av| 欧美日韩综合 | 99一区二区 | 亚州午夜精品 | 欧美日韩视频一区二区 | 一区二区免费视频 | www.色综合 | 一级在线视频 | 国产精品国产三级国产aⅴ原创 | 一区免费| 精品综合久久 | 免费国产视频在线观看 | 久久久91精品国产一区二区三区 | 欧美成人精品在线 | 久久精品国产一区二区三区不卡 | 中文字幕一区二区三区在线观看 | 精品一二三区在线观看 | 国产亚洲精品91 | 欧美一区二区免费电影 | 亚洲成av人片在线观看 | 国产91久久久久 | 中文字幕国 | 韩日免费视频 | 成人精品一区二区三区 | 中文字幕 在线观看 | 亚洲精品天堂 | 国产亚洲精品久久午夜玫瑰园 | 日本字幕在线观看 | 黑人精品| 色综合av | 国产成人啪免费观看软件 | 黄色毛片在线观看 | 亚洲午夜在线 |