⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd._c

📁 ICCAVR编写128*64液晶程序测试已经通过
💻 _C
字号:
#include <iom16.h>
#include "lcd.h"
#include "delay.h"
#include "font.h"
unsigned char CurOffset,CurRow,CurPage,CurCol;//当前指针位置

//--------------复位函数---------------------
void LCD_reset(void)
{
   LCD_RST_DDR    |=  LCD_RST_BIT;
   CLEAR_LCD_RST;
   delay_nms(10);
   SET_LCD_RST;
}

//-------------忙信号检测函数----------------
void LCD_BUSY(unsigned char lr) //判断忙标志
{
   //unsigned char status;
   asm("cli");
   if(lr==RIGHT)
   {
      CLEAR_LCD_CS2; //cs2=0
      SET_LCD_CS1;   //cs1=1
   }
   else
   {
      SET_LCD_CS2;   //cs2=1
      CLEAR_LCD_CS1; //cs1=0
   }
   SET_LCD_CMD;
   LCD_DIR_PORT = 0x00;
   LCD_OP_PORT = 0xff;
   SET_LCD_READ;
   SET_LCD_E;
   delay_nus(250);
   delay_nus(250);
   while((LCD_IP_PORT) & LCD_STATUS_BUSY)
   {
      CLEAR_LCD_E;
      delay_nus(250);
	  delay_nus(250);
      SET_LCD_E;
      delay_nus(250);
	  delay_nus(250);
   }
   CLEAR_LCD_E;
   SET_LCD_WRITE;
   LCD_OP_PORT = 0xff;
   asm("sei");
  
}

//------------写指令(数据)函数---------------------
void write_LCD(unsigned char lr,unsigned char cd,unsigned char data) 
{	
  asm("cli");
   LCD_BUSY(lr);
   if(cd==CMD)
      SET_LCD_CMD;
   else
      SET_LCD_DATA;
   SET_LCD_WRITE;
   SET_LCD_E;
   LCD_DIR_PORT = 0xff;
   LCD_OP_PORT = data;
   delay_nus(250);
   delay_nus(250);
   CLEAR_LCD_E;
   LCD_OP_PORT = 0xff;
   asm("sei");
  
}

//--------------读数据函数-------------------
unsigned char read_LCD(unsigned char lr)	  
{
   unsigned char data;
   
   asm("cli");
   LCD_BUSY(lr);
   SET_LCD_DATA;
   LCD_DIR_PORT = 0x00;
   LCD_OP_PORT = 0xff;
   SET_LCD_READ;
   SET_LCD_E;
   delay_nms(1);
   data=LCD_IP_PORT;
   CLEAR_LCD_E;
   SET_LCD_WRITE;
   
   LCD_BUSY(lr);
   SET_LCD_DATA;
   LCD_DIR_PORT = 0x00;
   LCD_OP_PORT = 0xff;
   SET_LCD_READ;
   SET_LCD_E;
   delay_nus(250);
   delay_nus(250);
   data=LCD_IP_PORT;
   CLEAR_LCD_E;
   SET_LCD_WRITE;
   delay_nus(250);
   delay_nus(250);
   asm("sei");
   return data;
}

//-----------------行列页选择函数------------------ 
void set_start_line_L(unsigned char line) /*设置显示起始行*/ //0-63
{
   write_LCD(LEFT,CMD,0xc0|line);
}

void set_start_line_R(unsigned char line) /*设置显示起始行*/ //0-63
{
   write_LCD(RIGHT,CMD,0xc0|line);
}

void set_page_L(unsigned char page)	/*设置X地址 设置页*/  //0-7
{
   write_LCD(LEFT,CMD,0xb8|page);
}
void set_page_R(unsigned char page)	/*设置X地址 设置页*/ //0-7
{
   write_LCD(RIGHT,CMD,0xb8|page);
}

void set_col_addr_L(unsigned char col) /*设置Y地址*/ //0-63
{
   write_LCD(LEFT,CMD,0x40|col);
}

void set_col_addr_R(unsigned char col) /*设置Y地址*/ //0-63
{
   write_LCD(RIGHT,CMD,0x40|col);
}


//------------液晶初始化函数-----------------------
void LCD_Init(void) 
{
   LCD_DIR_PORT = 0xff;
   LCD_OP_PORT = 0xff;
   LCD_EN_DDR    |=  LCD_EN_BIT;
   LCD_DI_DDR    |=  LCD_DI_BIT;
   LCD_CS1_DDR   |=  LCD_CS1_BIT;
   LCD_CS2_DDR   |=  LCD_CS2_BIT;
   LCD_RW_DDR    |=  LCD_RW_BIT;
   LCD_RW_PORT   &= ~LCD_RW_BIT;
   LCD_reset();
   set_start_line_L(0);             /*显示起始行为0*/
   set_start_line_R(0);             /*显示起始行为0*/
   write_LCD(LEFT,CMD,DISPLAY_ON);  /*  开显示  */
   write_LCD(RIGHT,CMD,DISPLAY_ON); /*  开显示  */
}


//-----------清屏函数---------------------------
void LCD_clr(void)                 
{
   unsigned char pages,i;
   for(pages=0;pages<8;pages++)
   {
      set_page_L(pages);            /* X 页地址 */
      set_page_R(pages);            /* X 页地址 */
      for(i=0;i<64;i++)
      {
         set_col_addr_L(i);//Y
         set_col_addr_R(i);//Y
         write_LCD(LEFT,DATA,0x0);
         write_LCD(RIGHT,DATA,0x0);
      }
   }
}


//---------当前行列获得函数-----------------------
unsigned char GetPage(void) /*得到当前页*/
{
   return CurPage;
}

unsigned char GetCol(void) /*得到当前列*/
{
   return CurCol;
}

//-----------------页置函数-----------------
void SetPageCol(unsigned char upage, unsigned char ucol) 
{
   CurPage = upage;
   CurCol = ucol;
   if(ucol<64)
   {
      set_page_L(upage);
      set_col_addr_L(ucol);
   }
   else
   {
      set_page_R(upage);
      set_col_addr_R(ucol-64);
   }
}

//---------------行列设置函数---------------------------
void SetRowCol(unsigned char urow, unsigned char ucol) 
{
   unsigned char page;
   CurRow = urow;
   CurCol = ucol;
	
   switch(urow)
   {
      case 1:
             page=0;
             CurOffset=1;
             break;
      case 2:
             page=1;
             CurOffset=2;
             break;
      case 3:
             page=3;
             CurOffset=1;
             break;
      case 4:
             page=4;
             CurOffset=2;
             break;
      case 5:
             page=6;
             CurOffset=1;
             break;
   }
   SetPageCol(page,ucol);
}


//----------------字符显示函数------------------
void disp_char(unsigned char c)
{
   unsigned char k,j,uPage,uCol,ch_r,ch_w;
   unsigned char width;
   unsigned char len;
   uPage = GetPage();
   uCol = GetCol();
   len=sizeof(ASC_16)/sizeof(ASC_16[0]);
   for(k=0;k<len;k++)
   {
      if(c == ASC_16[k].Index[0] )
         break;
   }
   if(k<len)
   {
      if(c=='-'||c==':')
         width=ASC_CHR_WIDTH-2;
      else if(c=='|')
         width=ASC_HZ_WIDTH-ASC_CHR_WIDTH;
      else
         width=ASC_CHR_WIDTH;
		
      if(CurOffset==1) //下半部是写半个字节
      {
         for(j=0;j<width;j++)
         {
            SetPageCol(uPage,uCol+j);
            ch_w=ASC_16[k].Msk[j];
            if(uCol+j<64)
               write_LCD(LEFT,DATA,ch_w);
            else
               write_LCD(RIGHT,DATA,ch_w);
         }
         SetPageCol(uPage+1,uCol);
			
         for(j=0;j<width;j++)
         {
            SetPageCol(uPage+1,uCol+j);
            if(uCol+j<64)
               ch_r=read_LCD(LEFT);
            else
               ch_r=read_LCD(RIGHT);
            ch_r&=0xf0;
            ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j]&0x0f;
            ch_w|=ch_r;
            SetPageCol(uPage+1,uCol+j);
            if(uCol+j<64)
               write_LCD(LEFT,DATA,ch_w);
            else
               write_LCD(RIGHT,DATA,ch_w);
         }
      }
      else //上半部是写半个字节
      {
         for(j=0;j<width;j++)
         {
            SetPageCol(uPage,uCol+j);
            if(uCol+j<64)
               ch_r=read_LCD(LEFT);
            else
               ch_r=read_LCD(RIGHT);
            ch_r&=0x0f;
            ch_w=ASC_16[k].Msk[j];
            ch_w=ch_w<<4;
            ch_w|=ch_r;
            SetPageCol(uPage,uCol+j);
            if(uCol+j<64)
               write_LCD(LEFT,DATA,ch_w);
            else
               write_LCD(RIGHT,DATA,ch_w);
         }
         SetPageCol(uPage+1,uCol);
         for(j=0;j<width;j++)
         {
            SetPageCol(uPage+1,uCol+j);
				
            ch_r=ASC_16[k].Msk[j];
            ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j];
            ch_r=ch_r>>4;
            ch_w=ch_w<<4;
            ch_w|=ch_r;
            SetPageCol(uPage+1,uCol+j);
            if(uCol+j<64)
               write_LCD(LEFT,DATA,ch_w);
            else
               write_LCD(RIGHT,DATA,ch_w);
         }
      }
   }
   SetPageCol(uPage,uCol+width);
}


//---------------汉字显示函数------------------
void disp_hz(unsigned char *hz)
{
   unsigned char k,j,uPage,uCol,ch_r,ch_w;
   uPage = GetPage();
   uCol = GetCol();
   for(k=0;k<sizeof(GB_16)/sizeof(GB_16[0]);k++)
   {
      if(hz[0] == GB_16[k].Index[0] && hz[1] == GB_16[k].Index[1])
         break;
   }

   if(CurOffset==1)
   {
      for(j=0;j<ASC_HZ_WIDTH;j++)
      {
         SetPageCol(uPage,uCol+j);
         ch_w=GB_16[k].Msk[j];
         if(uCol+j<64)	write_LCD(LEFT,DATA,ch_w);
         else write_LCD(RIGHT,DATA,ch_w);
      }
      SetPageCol(uPage+1,uCol);

      for(j=0;j<ASC_HZ_WIDTH;j++)
      {
         SetPageCol(uPage+1,uCol+j);
         if(uCol+j<64)
            ch_r=read_LCD(LEFT);
         else
            ch_r=read_LCD(RIGHT);
         ch_r&=0xf0;
         ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j]&0x0f;
         ch_w|=ch_r;
         SetPageCol(uPage+1,uCol+j);
         if(uCol+j<64)
            write_LCD(LEFT,DATA,ch_w);
         else
            write_LCD(RIGHT,DATA,ch_w);
      }
      SetPageCol(uPage,uCol+ASC_HZ_WIDTH);
   }

   else //汉字上半部是写半个字节
   {
      for(j=0;j<ASC_HZ_WIDTH;j++)
      {
         SetPageCol(uPage,uCol+j);
         if(uCol+j<64)
            ch_r=read_LCD(LEFT);
         else ch_r=read_LCD(RIGHT);
         ch_r&=0x0f;
         ch_w=GB_16[k].Msk[j];
         ch_w=ch_w<<4;
         ch_w|=ch_r;
         SetPageCol(uPage,uCol+j);
         if(uCol+j<64)
            write_LCD(LEFT,DATA,ch_w);
         else
            write_LCD(RIGHT,DATA,ch_w);
      }
      SetPageCol(uPage+1,uCol);
      for(j=0;j<ASC_HZ_WIDTH;j++)
      {
         SetPageCol(uPage+1,uCol+j);

         ch_r=GB_16[k].Msk[j];
         ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j];
         ch_r=ch_r>>4;
         ch_w=ch_w<<4;
         ch_w|=ch_r;
         SetPageCol(uPage+1,uCol+j);
         if(uCol+j<64)
            write_LCD(LEFT,DATA,ch_w);
         else
            write_LCD(RIGHT,DATA,ch_w);
      }
      SetPageCol(uPage,uCol+ASC_HZ_WIDTH);
   }
}


//-----------字符串显示函数----------------
void disp_str(unsigned char *p)
{
   unsigned char i=0;
   while(p[i]>0)
   {
      if(p[i] < 128)
      {	/* ASCII */
         disp_char(p[i]);
      }
      else
      {	/* 中文 */
         disp_hz(&p[i]);
         i++;
      }
      i++;
   }
}


//-------------------绘点函数----------------------------------              
//XX--(0-128) YY--(0-63) FLAG=1绘点   FLAG=0 清点
void GUI_Point(unsigned char xx,unsigned char yy,unsigned char flag)
{
   unsigned int y,ch;
   ch=yy%8;  //余数

   y=1;
   for(;ch!=0;)
   {
      y=y*2;
      ch--;
   }
   if(xx<64)
   {
      set_page_L(yy/8);
      set_col_addr_L(xx);
      ch=read_LCD(LEFT);
      set_col_addr_L(xx);
      if(flag)
         write_LCD(LEFT,DATA,ch|y);
      else
         write_LCD(LEFT,DATA,ch&(~y));
   }
   else
   {
      set_page_R(yy/8);
      set_col_addr_R(xx-64);
      ch=read_LCD(RIGHT);
      set_col_addr_R(xx-64);
      if(flag)
         write_LCD(RIGHT,DATA,ch|y);
      else
         write_LCD(RIGHT,DATA,ch&(~y));
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -