S3C2440 LCD字符显示 最近找到一些关于S3C2440 LCD字符显示的讲解,虽然也看过网上的好多,但大部分只是代码,发现一个说的挺清楚的,拿出来大家一起分享一下。 其实每一字符就是一幅图像,字符的大小对应于图像的大小,字符的笔画对应于图像的内容。那么如何把字符转换为图像呢?简单的方法是使用“字模提取”之类的软件,它能够把任意的字符转换为一个字节型的数组,数组元素中的每一位代表LCD上的一个像素点,当为1时,表示该位置为字符的一个笔画,需要上色,而为0时,表示不是笔画,学过12864无字库液晶的相信肯定会使用LCD字符显示。比较简单,贴两个函数仅供参考。 1. /************************************************************** 2. * 在LCD屏幕上指定坐标点写ASCII码(8X16) 3. * 取模方式为 阴码 逐行式 顺向 十六进制数 C51格式 (使用软件为(PCtoLCD2002)) 4. * 参数x,y为字符左上点坐标 5. * c 为字体颜色 bk_c为字体背景色 6. * st 为1时不使用背景色 为0时使用背景色 7. * pZK 为字符的数组 8. **************************************************************/ 9. void Lcd_PutASCII(unsigned int x,unsigned int y,unsigned int c,unsigned int bk_c,unsigned int st,unsigned char *pZK) 10. { 11. unsigned short int i,j; 12. unsigned char mask,buf; 13. 14. for( i = 0 ; i < 16 ; i++ ) 15. { 16. mask = 0x80; 17. buf = pZK; 18. for( j = 0 ; j < 8 ; j++ ) 19. { 20. if( buf & mask ) 21. { 22. PutPixel(x+j,y+i,c); 23. } 24. else 25. { 26. if( !st ) 27. { 28. PutPixel(x+j,y+i,bk_c); 29. } 30. } 31. 32. mask = mask >> 1; 33. } 34. } 35. } 36. 37. /************************************************************** 38. * 在LCD屏幕上指定坐标点写汉字(16X16) 39. * 取模方式为 阴码 逐行式 顺向 十六进制数 C51格式 (使用软件为(PCtoLCD2002)) 40. * 参数x,y为汉字左上点坐标 41. * c 为字体颜色 bk_c为字体背景色 42. * st 为1时不使用背景色 为0时使用背景色 43. * pZK 为汉字的数组 44. **************************************************************/ 45. void Lcd_PutHZ(unsigned int x,unsigned int y,unsigned int c,unsigned int bk_c,unsigned int st, unsigned char *pZK ) 46. { 47. unsigned short int i,j; 48. unsigned char mask,buf; 49. 50. for( i = 0 ; i < 16 ; i++ ) 51. { 52. //左 53. mask = 0x80; 54. buf = pZK[i*2]; 55. for( j = 0 ; j < 8 ; j++ ) 56. { 57. if( buf & mask ) 58. { 59. PutPixel(x+j,y+i,c); 60. } 61. else 62. { 63. if( !st ) 64. { 65. PutPixel(x+j,y+i,bk_c); 66. } 67. } 68. mask = mask >> 1; 69. } 70. 71. //右 72. mask = 0x80; 73. buf = pZK[i*2 + 1]; 74. for( j = 0 ; j < 8 ; j++ ) 75. { 76. if( buf & mask ) 77. { 78. PutPixel(x+j + 8,y+i,c); 79. } 80. else 81. { 82. if( !st ) 83. { 84. PutPixel(x+j + 8,y+i,bk_c); 85. } 86. } 87. mask = mask >> 1; 88. } 89. } 90. }
如 果要在程序中显示大量的中文字符,是不是要把这些字符都取模啊?回答是肯定的,但前人已经为我们完成了这一步,做成了数据库,并且进行了编码,只要按照编 码规则调用该库文件,就可以检索到相要的字符。下面就来说说编码规则:每个汉字是由两个字节表示的,前一个字节表示的区号,后一个字节表示的位号,那么汉 字在汉字库中的位置为:94×(区号-1)+(位号-1)。94表示的是每个区里一共有94个汉字,减1表示的是数组是从0开始,而区号和位号是从1开始的。具体到汉字在某一数据库中的位置,还需要乘以一个汉字字模所占的字节数,即[94×(区号-1)+(位号-1)]×一个汉字字模所占字节数。如一个字模大小为16×16的宋体数据库,库里每个汉字所占的字节为16×16÷8=32,则每个汉字在该宋体数据库中的位置为:[94×(区号-1)+(位号-1)]×32。ASCII码的字符调用比汉字字符要简单,只要把它乘以字模所占字节数即可找到该字符所在字库的位置,如8×16的ASCII字库,ASCII码在该字库的位置为ASCII×16。如果中文字符和ASCII码混合在一样,如何区分它们呢?其实也很简单,ASCII码的最高位是0,而中文的最高位是1,因此当读取到的一个字节的最高位是0,则该字节为ASCII码,它的下一个字节与这个字节无关;当取得到的字节的最高位是1,则表示的是中文字符,并且该字节与它的下一个字节组合在一起表示完整的一个汉字。 每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。
贴出使用字库显示汉字和字符的代码 1. /************************************************************** 2. 在LCD屏幕上指定坐标点写ASCII码 3. **************************************************************/ 4. void Lcd_PutASCII(unsigned int x,unsigned int y,unsigned char ch,unsigned int c,unsigned int bk_c,unsigned int st) 5. { 6. unsigned short int i,j; 7. unsigned char *pZK,mask,buf; 8. 9. 10. 11. pZK = &__VGA[ch*16]; 12. for( i = 0 ; i < 16 ; i++ ) 13. { 14. mask = 0x80; 15. buf = pZK; 16. for( j = 0 ; j < 8 ; j++ ) 17. { 18. if( buf & mask ) 19. { 20. PutPixel(x+j,y+i,c); 21. } 22. else 23. { 24. if( !st ) 25. { 26. PutPixel(x+j,y+i,bk_c); 27. } 28. } 29. 30. mask = mask >> 1; 31. } 32. } 33. } 34. 35. /************************************************************** 36. 在LCD屏幕上指定坐标点写汉字 37. **************************************************************/ 38. void Lcd_PutHZ(unsigned int x,unsigned int y,unsigned short int QW,unsigned int c,unsigned int bk_c,unsigned int st) 39. { 40. unsigned short int i,j; 41. unsigned char *pZK,mask,buf; 42. 43. pZK = &__CHS[ ( ( (QW >> 8) - 1 )*94 + (QW & 0x00FF)- 1 )*32 ]; 44. for( i = 0 ; i < 16 ; i++ ) 45. { 46. //左 47. mask = 0x80; 48. buf = pZK[i*2]; 49. for( j = 0 ; j < 8 ; j++ ) 50. { 51. if( buf & mask ) 52. { 53. PutPixel(x+j,y+i,c); 54. } 55. else 56. { 57. if( !st ) 58. { 59. PutPixel(x+j,y+i,bk_c); 60. } 61. } 62. mask = mask >> 1; 63. } 64. 65. //右 66. mask = 0x80; 67. buf = pZK[i*2 + 1]; 68. for( j = 0 ; j < 8 ; j++ ) 69. { 70. if( buf & mask ) 71. { 72. PutPixel(x+j + 8,y+i,c); 73. } 74. else 75. { 76. if( !st ) 77. { 78. PutPixel(x+j + 8,y+i,bk_c); 79. } 80. } 81. mask = mask >> 1; 82. } 83. } 84. } 85. 86. //---------------------- 87. void Lcd_printf(unsigned int x,unsigned int y,unsigned int c,unsigned int bk_c,unsigned int st,char *fmt,...) 88. { 89. char __LCD_Printf_Buf[256];//可以显示128个汉字或字符 90. va_list ap; 91. unsigned char *pStr = (unsigned char *)__LCD_Printf_Buf; 92. unsigned int i = 0; 93. 94. va_start(ap,fmt); 95. vsprintf(__LCD_Printf_Buf,fmt,ap); 96. va_end(ap); 97. 98. while(*pStr != 0 ) 99. { 100. switch(*pStr) 101. { 102. case '\n' : 103. { 104. 105. break; 106. } 107. 108. default: 109. { 110. if( *pStr > 0xA0 & *(pStr+1) > 0xA0 ) //中文输出 111. { 112. Lcd_PutHZ( x , y , (*pStr - 0xA0)*0x0100 + *(pStr+1) - 0xA0 , c , bk_c , st); 113. 114. pStr++; 115. i++; 116. 117. x += 16; 118. } 119. else //英文输出 120. { 121. Lcd_PutASCII( x , y , *pStr , c , bk_c , st ); 122. 123. x += 8; 124. 125. } 126. 127. break; 128. } 129. } 130. 131. pStr++; 132. i++; 133. 134. if( i > 256 ) break; 135. } 136. 137. }
|