用ST7565来显示汉字以及画点,实例
Ofweek 2021-09-26

  最近需要用ST7565来显示汉字以及画点,发现网上关于ST7565驱动显示文字的例子也不少,不过画图方面的例子就很少了。ST7565是比较常见的128*64的LCD,我这里使用模拟SPI来写ST7565,ST7565是“纵向8点下高位”类型的LCD,难点在于页(Y轴)。

  如下图,这里Y=6

  

  一个8位数据对应LCD纵向的8个格子,例如:要在Y=6地方亮一个点,把二进制0100 0000写到ST7565里,实际在纵向倒数第二个点显示一个点。

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

  

  接下来贴上代码,由于每个厂家的ST7565的屏的接线都会有区别,所以这里就不给出写ST7565的实现,SPI_Write()就是写ST7565函数,通过LCD_CMD/LCD_CANVAS来区分是写控制命令还是图像数据。这里的字模来自Lcmzimo字模工具。

  view plaincopy to clipboardprint?

  //汉字 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;

  colh = x》》4; /*取x的高4位*/

  colh = colh | 0xf0;

  colh = colh & 0x1f;

  coll = x & 0x0f; /*取x的低4位*/

  SPI_Write(colh,LCD_CMD);

  SPI_Write(coll,LCD_CMD);

  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);

  }

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
热门推荐
  • 相关技术文库
  • 硬件
  • 原理图
  • 信号完整性
  • EMI
  • 工程师需了解的芯片datasheet

    注 | 文末留言有神器 本文主要介绍芯片datasheet的查找、使用方法以及重要性,不管是设计硬件电路还是编程,datasheet都是重要的资料, 芯片的使用方法都在datasheet里,这也是最权威的资料! Datasheet(数据手册)的快速阅读能力是每个工程师都应该具备的基本

    05-11
  • 三级管的无刷电机滤波应用

    如图1是无刷电机霍尔信号的滤波电路,为了保证波形质量,简单的阻容滤波并不能完全解决实际复杂的工作环境所带来的波形异常,量产的无刷驱动模块也有该电路。 为了保证滤波质量,在RC滤波后面加一个NPN三极管,利用三极管自身的响应速度达到高质量滤波目的。

    05-11
  • 为什么烧毁的总是相同的电容?

    我曾在一家光通信公司担任设计工程师,该公司生产的1000台设备安装在世界各地。现场的模块很多,送回公司返修的也很多,我的工作便是搞清这些模块出了什么故障。其中一次故障查找经历给我上了精彩的一课,我至今记忆犹新。 客户寄回来一个模块,其故障原因很

    05-11
  • 理解PID,探究微分、积分电路的本质

    很多朋友觉得PID是遥不可及,很神秘,很高大上的一种控制,对其控制原理也很模糊,只知晓概念性的层面,知其然不知其所以然,那么本期从另类视角来探究微分、积分电路的本质,意在帮助理解PID的控制原理(PID:P表示比例控制;I表示积分控制;D表示微分控制)

    05-10
  • 555定时器电路图汇总

    3*3*3光立方 警报器 闪光器 鸣笛警报器 闪烁电路 闪烁电路 激光射线 闩 电子骰子 LED调光器 555放大器 光检测器 机器枪 金属探测器 电机脉宽调制 LED闪光电路 音乐盒 玩具器官 警灯 另一个警灯 驱动双色LED 模型铁路时间 雨水警报 反应计时器 继电器 继电器

    05-07
  • 电解电容的计算与选择

    输入侧的电解电容计算 我们一般按照在最低输入电压下,最大输出的情况下,要求电解电容上的纹波电压低于多少个百分点来计算。当然,如果有保持时间的要求,那么需要按照保持时间的要求重新计算,二者之中,取大的值。 假如在最低输入电压下,电源的输入功率为

    05-07
  • 一个按键开关机的硬件软件设计

    要设计一个产品,只有一个按键,长按开机,再长按就关机(关机电路上的电源需要断开)。那么硬件需要怎么设计呢,软件又可以怎么做呢? 硬件电路设计如下。 硬件PCB设计如下。 硬件的工作原理是这样的,长按按键SW1时,MOS管Q1导通,电源VBAT+给系统供电,单片

    05-06
  • 电子硬件英文缩写术语解析

    常用控制接口 EN:Enable,使能。使芯片能够工作。要用的时候,就打开EN脚,不用的时候就关闭。有些芯片是高使能,有些是低使能,要看规格书才知道。 CS:Chip Select,片选。芯片的选择。通常用于发数据的时候选择哪个芯片接收。例如一根SPI总线可以挂载多个

    05-06
  • 二极管限幅电路的具体分析细节

    二极管最基本的工作状态是导通和截止两种,利用这一特性可以构成限幅电路。所谓限幅电路,就是指限制电路中某一点的信号幅度大小,当信号幅度大到一定程度时,不让信号的幅度再增大;当信号的幅度没有达到限制的幅度时,限幅电路不工作。具有这种功能的电路称

    05-07
  • 60%的EMI问题可以用这个来解决

    随着信号上升沿时间的减小,信号频率的提高,电子产品的EMI问题,也来越受到电子工程师的重视。高速pcb设计的成功,对EMI的贡献越来越受到重视,几乎60%的EMI问题可以通过高速PCB来控制解决。 1 高速信号走线屏蔽规则 如上图所示:在高速的PCB设计中,时钟等

    04-30
  • 几种常用的传感器数据处理

    在传感器使用中,我们常常需要对传感器数据进行各种整理,让应用获得更好的效果,以下介绍几种常用的简单处理方法: 1.加权平滑:平滑和均衡传感器数据,减小偶然数据突变的影响; 2.抽取突变:去除静态和缓慢变化的数据背景,强调瞬间变化; 3.简单移动平均线

    04-30
  • 工程师硬件面试的几个问题

    今天给大家分享一些硬件常见面试题。 问1 晶体管基本放大电路有共射、共集、共基三种接法,请简述这三种基本放大电路的特点。 共射:共射放大电路具有放大电流和电压的作用,输入电阻大小居中,输出电阻较大,频带较窄,适用于一般放大。 共集:共集放大电路

    04-29
下载排行榜
更多
EE直播间
更多
广告
X
广告