[讨论] 驱动ST7565显示汉字以及画点

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

如下图,这里Y=6

1.jpg

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

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

2.jpg


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

  1. //汉字 16*16 的定义
  2. unsigned int CHINESE_16_16[] = {32/*数据总数*/,16/*宽*/,16/*高*/};
  3. //汉字 24*24 的定义
  4. unsigned int CHINESE_24_24[] = {72/*数据总数*/,24/*宽*/,24/*高*/};
  5. //ASCII 16*8 的定义
  6. unsigned int ASCII_W8_H16[] = {16/*数据总数*/,8/*宽*/,16/*高*/};
  7. //ASCII 24*12 的定义
  8. unsigned int ASCII_W12_H24[] = {36/*数据总数*/,12/*宽*/,24/*高*/};
  9. // *****************************************************
  10. //画字函数
  11. //参数x:X轴坐标,0~127
  12. //参数y_pag:纵向页数,0~7,每一页等于8个纵向像素
  13. //参数font:font的样式:{数据总数,高,宽}
  14. //参数p:字模数组,当p=LCD_CLEAR,则是清除指定区域
  15. // *****************************************************
  16. void LCD_PutChar(unsigned char x,unsigned char y_pag,unsigned int *font,unsigned char *p)
  17. {
  18. unsigned int size=font[0];//整个数组的大小
  19. unsigned int width=font[1];//字符的宽度
  20. //unsigned int height=font[2]; 留着以后有用
  21. unsigned int pagindex=1;//记录LCD页指针去到的页数
  22. unsigned int nextpage = width;

  23. unsigned char i,pag,colh,coll;
  24. pag = y_pag+0xb0;
  25. colh = x>>4; /*取y_pag的高4位*/
  26. colh = colh | 0xf0;
  27. colh = colh & 0x1f;
  28. coll = x & 0x0f; /*取y_pag的低4位*/
  29. SPI_Write(colh,LCD_CMD);
  30. SPI_Write(coll,LCD_CMD);
  31. SPI_Write(pag,LCD_CMD);

  32. for (i=0;i
  33. {
  34. if (i == nextpage)//当前页画完,则跳转到下一页继续画
  35. {
  36. SPI_Write(pag+pagindex,LCD_CMD);
  37. SPI_Write(colh,LCD_CMD);
  38. SPI_Write(coll,LCD_CMD);

  39. pagindex++;//换到下一页
  40. nextpage = pagindex * width;//定义下一页在size中的位置
  41. }

  42. if(p==0x00)
  43. SPI_Write(0X00,LCD_CANVAS);
  44. else
  45. SPI_Write(*p++,LCD_CANVAS);
  46. }
  47. }
  48. // *****************************************************
  49. //画点函数
  50. //原理:x直接设置列,Y/8=页数,Y%8=点在纵8格的位置,Y=0,Y|=BIT7,Y=Y>>(7-Y%8)
  51. //举例:(5,6),在列5,Y坐标在第0页的最后一点,即Y=0100 0000(倒向的二进制) 等价于 Y=0,Y|=BIT7,Y左移1位
  52. //参数x:X轴坐标,0~127
  53. //参数y:Y轴坐标,0~63
  54. //参数ph:点的高度,为0时则为清除点
  55. // *****************************************************
  56. void LCD_DrawPoint(unsigned char x,unsigned char y,unsigned int ph)
  57. {
  58. unsigned char i,pag,colh,coll;
  59. pag = y/8;//判断Y所在的页
  60. pag = pag +0xb0;

  61. colh = x>>4; /*取x的高4位*/
  62. colh = colh | 0xf0;
  63. colh = colh & 0x1f;
  64. coll = x & 0x0f; /*取x的低4位*/
  65. SPI_Write(colh,LCD_CMD);
  66. SPI_Write(coll,LCD_CMD);
  67. SPI_Write(pag,LCD_CMD);

  68. if(ph==LCD_CLEAR)
  69. {
  70. SPI_Write(LCD_CLEAR,LCD_CANVAS);
  71. return;
  72. }

  73. unsigned int point=0;
  74. for(i=0;i
  75. point|=(BIT7>>i);//点加高
  76. point=point>>(8-ph-y%8);//加高之后移位
  77. SPI_Write(point,LCD_CANVAS);
  78. }

  79. unsigned char hz16_16[]={//"你"
  80. 0x40,0x20,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,0x00,
  81. 0x00,0x00,0xFF,0x00,0x00,0x08,0x04,0x43,0x80,0x7F,0x00,0x01,0x06,0x0C,0x00,0x00
  82. };

  83. unsigned char hz24_24[]={//"好"
  84. 0x00,0x40,0x40,0x40,0xFF,0xFE,0x42,0x40,0xE0,0xE0,0x40,0x00,0x08,0x08,0x08,0x08,
  85. 0xC8,0x88,0x68,0x38,0x1C,0x08,0x00,0x00,0x00,0x00,0x70,0x7F,0xCF,0x80,0x00,0xF0,
  86. 0x7F,0x0F,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x18,0x18,0x10,0x00,
  87. 0x00,0x40,0x20,0x10,0x0C,0x07,0x03,0x07,0x1E,0x1C,0x00,0x00,0x20,0x20,0x60,0xE0,
  88. 0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00};
  89. unsigned char ascii8_16[]={// -G-
  90. 0xF0,0xF8,0x0C,0x84,0x84,0x8C,0x98,0x00,0x03,0x07,0x0C,0x08,0x08,0x07,0x0F,0x00
  91. };
  92. unsigned char ascii12_24[]={// -V-
  93. 0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x3F,0xFF,
  94. 0xC0,0x00,0xC0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x3C,0x1F,0x03,
  95. 0x00,0x00,0x00,0x00,
  96. };

  97. unsigned char *hzcode;

  98. void main()
  99. {
  100. WDTCTL=WDTPW+WDTHOLD; //停止WDT

  101. LCD_Init();//初使化
  102. LCD_SetDisplay(LCD_CLEAR);

  103. //显示“你”
  104. hzcode= hz16_16;
  105. LCD_PutChar(0,0,CHINESE_16_16,hzcode);
  106. //显示“好”
  107. hzcode= hz24_24;
  108. LCD_PutChar(16,1,CHINESE_24_24,hzcode);

  109. //显示分割线
  110. for(int x=0;x<127;x++)
  111. LCD_DrawPoint(x,32,1);


  112. //显示“G”
  113. hzcode= ascii8_16;
  114. LCD_PutChar(100,5,ASCII_W8_H16,hzcode);
  115. //显示“V”
  116. hzcode= ascii12_24;
  117. LCD_PutChar(108,5,ASCII_W12_H24,hzcode);
  118. }


转载自hellogv博客:http://blog.csdn.net/hellogv/archive/2010/01/26/5259187.aspx

回复评论 (2)

不错
点赞  2010-1-27 10:06
这个真不错
点赞  2011-12-10 12:36
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复