LCD(五)ST7565 132*65单色点阵驱动芯片

NRF51822——LCD128X64驱动

LCD(一)显示原理 

 

1.概述

ST7565R是132*65点阵驱动IC,通常用来做128*64的LCD模块。在 LCD 上排列着 128×64 点阵,128 个列信号与驱动 IC 相连,64 个行信号也与驱动 IC 相连,IC 邦定在 LCD 玻璃上( COG工艺)

在128*64的LCD模块可以显示:

  • 128*64 点阵的单色图片
  • 显示4行,每行 8 个16*16 点阵的汉字
  • 显示8行,每行16 个 8*8 点阵的英文、数字、符号

2.硬件设计

 2.2 SPI 接口
2.3 点阵与 DD RAM 地址的对应

它的难点在于页(Y轴)。 

页定义:PAGE,与平时所讲的“页”并不是一个意思,在此表示 8 个行就是一个“页”,一个 128*32 点阵的屏分为 8 个“页”,从第 0“页”到第 7“页”。

ST7565是“纵向8点下高位”类型的LCD,一个8bit数据对应LCD纵向的8个格子。

例如:要在Y=6地方亮一个点,把二进制01000000写到ST7565里,实际在纵向倒数第二个点显示一个点。 

如下图,这里Y=6

理论解释完了,接下来看看本例中实现的结果,看下图:

代码如下,SPI_Write()就是写ST7565函数,通过LCD_CMD/LCD_CANVAS来区分是写控制命令还是图像数据。这里的字模来自Lcmzimo字模工具。 

//汉字 16*16 的定义
unsigned int CHINESE_16_16[] = {32/*数据总数*/,16/*宽*/,16/*高*/};
//汉字 24*24 的定义
unsigned int CHINESE_24_24[] = {72/*数据总数*/,24/*宽*/,24/*高*/};
//ASCII 16*8 的定义
unsigned int ASCII_W8_H16[] = {16/*数据总数*/,8/*宽*/,16/*高*/};
//ASCII 24*12 的定义
unsigned int ASCII_W12_H24[] = {36/*数据总数*/,12/*宽*/,24/*高*/};
// *****************************************************
//画字函数
//参数x:X轴坐标,0~127
//参数y_pag:纵向页数,0~7,每一页等于8个纵向像素
//参数font:font的样式:{数据总数,高,宽}
//参数p:字模数组,当p=LCD_CLEAR,则是清除指定区域
// *****************************************************
void LCD_PutChar(unsigned char x,unsigned char y_pag,unsigned int *font,unsigned char *p)
{
  unsigned int size=font[0];//整个数组的大小
  unsigned int width=font[1];//字符的宽度
    //unsigned int height=font[2]; 留着以后有用
  unsigned int pagindex=1;//记录LCD页指针去到的页数
  unsigned int nextpage = width;
  
  unsigned char i,pag,colh,coll;
  pag = y_pag+0xb0;
  colh = x>>4; /*取y_pag的高4位*/
  colh = colh | 0xf0;
  colh = colh & 0x1f;
  coll = x & 0x0f; /*取y_pag的低4位*/
  SPI_Write(colh,LCD_CMD);
  SPI_Write(coll,LCD_CMD);
  SPI_Write(pag,LCD_CMD);
 
  for (i=0;i<size;i++)
  {
      if (i == nextpage)//当前页画完,则跳转到下一页继续画
      {
        SPI_Write(pag+pagindex,LCD_CMD);
        SPI_Write(colh,LCD_CMD);
        SPI_Write(coll,LCD_CMD);
   
        pagindex++;//换到下一页
        nextpage = pagindex * width;//定义下一页在size中的位置
      }
     
      if(p==0x00)
        SPI_Write(0X00,LCD_CANVAS);
      else
        SPI_Write(*p++,LCD_CANVAS);
  }
}
// *****************************************************
//画点函数
//原理:x直接设置列,Y/8=页数,Y%8=点在纵8格的位置,Y=0,Y|=BIT7,Y=Y>>(7-Y%8)
//举例:(5,6),在列5,Y坐标在第0页的最后一点,即Y=0100 0000(倒向的二进制) 等价于 Y=0,Y|=BIT7,Y左移1位
//参数x:X轴坐标,0~127
//参数y:Y轴坐标,0~63
//参数ph:点的高度,为0时则为清除点
// *****************************************************
void LCD_DrawPoint(unsigned char x,unsigned char y,unsigned int ph)
{
  unsigned char i,pag,colh,coll; 
  pag = y/8;//判断Y所在的页
  pag = pag  +0xb0;    //0xb0是设置页面地址命令
  
  colh = x>>4; /*取x的高4位*/
  colh = colh | 0xf0;
  colh = colh & 0x1f;
  coll = x & 0x0f; /*取x的低4位*/
  SPI_Write(colh,LCD_CMD);    //设置列地址的MSB
  SPI_Write(coll,LCD_CMD);    //设置列地址的LSB
  SPI_Write(pag,LCD_CMD);     //设置页面地址
  
  if(ph==LCD_CLEAR)
  {
    SPI_Write(LCD_CLEAR,LCD_CANVAS);
    return;
  }
    
  unsigned int point=0;
  for(i=0;i<ph;i++)
    point|=(BIT7>>i);//点加高
  point=point>>(8-ph-y%8);//加高之后移位 
  SPI_Write(point,LCD_CANVAS);
}
unsigned char hz16_16[]={//"你" 
0x40,0x20,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,0x00,
0x00,0x00,0xFF,0x00,0x00,0x08,0x04,0x43,0x80,0x7F,0x00,0x01,0x06,0x0C,0x00,0x00
};
unsigned char hz24_24[]={//"好"
0x00,0x40,0x40,0x40,0xFF,0xFE,0x42,0x40,0xE0,0xE0,0x40,0x00,0x08,0x08,0x08,0x08,
0xC8,0x88,0x68,0x38,0x1C,0x08,0x00,0x00,0x00,0x00,0x70,0x7F,0xCF,0x80,0x00,0xF0,
0x7F,0x0F,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x18,0x18,0x10,0x00,
0x00,0x40,0x20,0x10,0x0C,0x07,0x03,0x07,0x1E,0x1C,0x00,0x00,0x20,0x20,0x60,0xE0,
0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char ascii8_16[]={// -G-
0xF0,0xF8,0x0C,0x84,0x84,0x8C,0x98,0x00,0x03,0x07,0x0C,0x08,0x08,0x07,0x0F,0x00
};
unsigned char ascii12_24[]={// -V-	
0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x3F,0xFF,  
0xC0,0x00,0xC0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x3C,0x1F,0x03,
0x00,0x00,0x00,0x00,
};
unsigned char  *hzcode; 
   
void main()
{
  WDTCTL=WDTPW+WDTHOLD;        //停止WDT 
  LCD_Init();//初使化
  LCD_SetDisplay(LCD_CLEAR);  		
  
  //显示“你”
  hzcode= hz16_16;
  LCD_PutChar(0,0,CHINESE_16_16,hzcode);
  //显示“好”  
  hzcode= hz24_24;
  LCD_PutChar(16,1,CHINESE_24_24,hzcode);
  
  //显示分割线
  for(int x=0;x<127;x++)
    LCD_DrawPoint(x,32,1);
 
  
  //显示“G”
  hzcode= ascii8_16;
  LCD_PutChar(100,5,ASCII_W8_H16,hzcode);
  //显示“V” 
  hzcode= ascii12_24;
  LCD_PutChar(108,5,ASCII_W12_H24,hzcode);
     }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值