lcd_5110_solution.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. /*
  2. * lcd_5110_solution.c
  3. *
  4. * Created on: 2012-2-2
  5. * Author: Administrator
  6. */
  7. #include "lcd_5110_solution.h"
  8. #include "main.h"
  9. #include "Delay.h"
  10. #include "SPI-SD/Lcd/font.h"
  11. #include "SPI-SD/Fatfs/ff.h"
  12. char n5110_string[6][14]; //6行,每行13byte
  13. #define CMD 0x00
  14. #define DATA 0x01
  15. #define LCD_X 84
  16. #define LCD_Y 48
  17. #define MAX_HZ_POSX LCD_X
  18. #define MAX_HZ_POSY LCD_Y
  19. #define MAX_CHAR_POSX LCD_X
  20. #define MAX_CHAR_POSY LCD_Y
  21. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. /////* 以下是基本操作和初始化函数 *//////
  23. #if 0
  24. //write a byte
  25. void LcdWrite(alt_u8 data,alt_u8 d_c)
  26. {
  27. alt_u8 i;
  28. //chose the chip
  29. IOWR_ALTERA_AVALON_PIO_DATA(SCE_BASE, 0x00);
  30. //chose data mode or command mode
  31. IOWR_ALTERA_AVALON_PIO_DATA(D_C_BASE, d_c);
  32. //sent 8 bits
  33. for(i = 0;i < 8;i ++)
  34. {
  35. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x00);
  36. IOWR_ALTERA_AVALON_PIO_DATA(SDIN_BASE, data >> (7 - i));
  37. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x01);
  38. }
  39. //release the chip
  40. IOWR_ALTERA_AVALON_PIO_DATA(SCE_BASE, 0x01);
  41. }
  42. //initial the 5110
  43. void InitLcd()
  44. {
  45. usleep(1000);
  46. //sent a reset pulse(low) to reset all internal registers
  47. IOWR_ALTERA_AVALON_PIO_DATA(REST_BASE, 0x00);
  48. usleep(1);
  49. IOWR_ALTERA_AVALON_PIO_DATA(REST_BASE, 0x01);
  50. usleep(1);
  51. //chose the chip
  52. IOWR_ALTERA_AVALON_PIO_DATA(SCE_BASE, 0x00);
  53. usleep(1);
  54. //release the chip
  55. IOWR_ALTERA_AVALON_PIO_DATA(SCE_BASE, 0x01);
  56. usleep(1);
  57. //function set PD = 0 and V = 0, select extended instruction set(H = 1 mode)
  58. LcdWrite(0x21,CMD);
  59. //set VOP: VOP is set to a + 65 × b [V]
  60. LcdWrite(0xbf,CMD);
  61. //RECOMMENDED MUX RATE(1:24),you can chose other MUX RATE
  62. LcdWrite(0x15,CMD);
  63. //function set PD = 0 and V = 0, select normal instruction set(H = 0 mode)
  64. LcdWrite(0x20,CMD);
  65. //display control set normal mode (D=1andE=0)
  66. LcdWrite(0x0c,CMD);
  67. //clear screen
  68. LcdClearAll();
  69. }
  70. #else
  71. //write a byte
  72. void LcdWrite(alt_u8 data,alt_u8 d_c)
  73. {
  74. alt_u8 i;
  75. //chose the chip
  76. LCD_CE = 0; // 使能LCD
  77. //chose data mode or command mode
  78. LCD_DC = d_c?1:0; //0.命令;1.数据
  79. //sent 8 bits
  80. for(i = 0;i < 8;i ++)
  81. {
  82. SCLK = 0;
  83. SDIN = (data&(1<<(7-i)))?1:0;
  84. SCLK = 1;
  85. }
  86. //release the chip
  87. LCD_CE = 1; // 关闭LCD
  88. }
  89. //initial the 5110
  90. void InitLcd(void)
  91. {
  92. delay_ms ( 1 );
  93. //sent a reset pulse(low) to reset all internal registers
  94. LCD_RST = 0;
  95. delay_us ( 1 ); // 产生一个让LCD复位的低电平脉冲
  96. LCD_RST = 1;
  97. //chose the chip
  98. delay_us ( 1 );
  99. LCD_CE = 0;// 关闭LCD
  100. //release the chip
  101. delay_us ( 1 );
  102. LCD_CE = 1;// 使能LCD
  103. delay_us ( 1 );
  104. #if 0
  105. //function set PD = 0 and V = 0, select extended instruction set(H = 1 mode)
  106. LcdWrite(0x21,CMD);
  107. //set VOP: VOP is set to a + 65 × b [V]
  108. LcdWrite(0xbf,CMD);
  109. //RECOMMENDED MUX RATE(1:24),you can chose other MUX RATE
  110. LcdWrite(0x15,CMD);
  111. //function set PD = 0 and V = 0, select normal instruction set(H = 0 mode)
  112. LcdWrite(0x20,CMD);
  113. //display control set normal mode (D=1andE=0)
  114. LcdWrite(0x0c,CMD);
  115. //clear screen
  116. LcdClearAll();
  117. #else
  118. LcdWrite ( 0x21, 0 ); // 使用扩展命令设置LCD模式
  119. LcdWrite ( 0xc8, 0 ); // 设置偏置电压
  120. LcdWrite ( 0x06, 0 ); // 温度校正
  121. LcdWrite ( 0x13, 0 ); // 1:48
  122. LcdWrite ( 0x20, 0 ); // 使用基本命令
  123. LcdClearAll(); // 清屏
  124. LcdWrite ( 0x0c, 0 ); // 设定显示模式,正常显示
  125. #endif
  126. //开启背光灯
  127. BACKLIGHT = 1;
  128. }
  129. #endif
  130. //set the x axis and y axis
  131. void SetXY(alt_u8 x,alt_u8 y)
  132. {
  133. if(x > 83) x = 0;
  134. if(y > 5) y = 0;
  135. //set y axis
  136. LcdWrite(0x40 | y,CMD);
  137. //set y axis
  138. LcdWrite(0x80 | x,CMD);
  139. }
  140. //clear all screen
  141. void LcdClearAll()
  142. {
  143. alt_u16 i;
  144. SetXY(0,0);
  145. //write space continually
  146. for(i = 0;i < LCD_X * LCD_Y / 8;i ++)
  147. {
  148. LcdWrite(0,DATA);
  149. }
  150. }
  151. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. /////* 以下是高度为8的各种操作函数 *//////
  153. //* 包括6*8字符和字符串,6*8符号,10*8图标 *//
  154. //every row contains 14 characters,there are 6 rows (font = 6 * 8)//
  155. /////////////////////////////////////////////////////////////////////////////////////////////////////
  156. ///////// x /////////
  157. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 0
  158. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 1
  159. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 2
  160. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 3
  161. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 4
  162. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 5
  163. /////////////////////////////////////////////////////////////////////////////////////////////////////
  164. //write a char(6*8),don't need coordinates
  165. void WriteChar(alt_u8 value)
  166. {
  167. alt_u8 i;
  168. for(i = 0;i < 6;i ++)
  169. LcdWrite(ASCII_6_8[value - 0x20][i],DATA);
  170. }
  171. //write a char(6*8),need coordinates
  172. void PutChar(alt_u8 value,alt_u8 x,alt_u8 y)
  173. {
  174. if(x > 13) x = 0;
  175. SetXY(6 * x,y);
  176. WriteChar(value);
  177. }
  178. //write a string(6*8),don't need coordinates
  179. void WriteStr(char * str)
  180. {
  181. while(*str)
  182. {
  183. WriteChar(*str ++);
  184. }
  185. }
  186. //write a string(6*8),need coordinates,auto line breaks
  187. void PutStr(char * str,alt_u8 x,alt_u8 y)
  188. {
  189. if(x > 13) x = 0;
  190. SetXY(6 * x,y);
  191. WriteStr(str);
  192. }
  193. //draw a sign(6*8),don't need coordinates
  194. void WriteSign(char * sign)
  195. {
  196. alt_u8 i;
  197. for(i = 0;i < 6;i ++)
  198. LcdWrite(sign[i],DATA);
  199. }
  200. //draw a sign(6*8),need coordinates
  201. void DrawSign(char * sign,alt_u8 x,alt_u8 y)
  202. {
  203. SetXY(x,y);
  204. WriteSign(sign);
  205. }
  206. //draw a sign(10*8),don't need coordinates
  207. void WriteIcon(char * icon)
  208. {
  209. alt_u8 i;
  210. for(i = 0;i < 10;i ++)
  211. LcdWrite(icon[i],DATA);
  212. }
  213. //draw a sign(10*8),need coordinates,x is between 0 and 74
  214. void DrawIcon(char * icon,alt_u8 x,alt_u8 y)
  215. {
  216. //if need line breaks
  217. if(x > 74)
  218. {
  219. x = 0;
  220. y += 1;
  221. }
  222. SetXY(x,y);
  223. //draw a sign(10*8)
  224. WriteIcon(icon);
  225. }
  226. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227. /////* 以下是高度为16的各种操作函数 *//////
  228. //* 包括8*16字符和字符串,16*16汉字 *//
  229. //every row contains 10 characters,there are 3 rows (font = 8 * 16)//
  230. ///////////////////////////////////////////////////////////////////////////////////////////////////
  231. ///////// x ///////////
  232. //0 1 2 3 ... 81 82 83// y = 0
  233. //0 1 2 3 ... 81 82 83//
  234. //0 1 2 3 ... 81 82 83// y = 1
  235. //0 1 2 3 ... 81 82 83//
  236. //0 1 2 3 ... 81 82 83// y = 2
  237. //0 1 2 3 ... 81 82 83//
  238. ///////////////////////////////////////////////////////////////////////////////////////////////////
  239. //write a char(8*16)
  240. void WriteChar_8_16(alt_u8 value,alt_u8 x,alt_u8 y)
  241. {
  242. alt_u8 i;
  243. //draw the first row
  244. SetXY(x,y * 2);
  245. for(i = 0;i < 8;i ++)
  246. LcdWrite(ASCII_8_16[value - 0x20][i],DATA);
  247. //draw the second row
  248. SetXY(x,y * 2 + 1);
  249. for(i = 8;i < 16;i ++)
  250. LcdWrite(ASCII_8_16[value - 0x20][i],DATA);
  251. }
  252. //write a string(8*16),auto line breaks,x is between 0 and 76
  253. void WriteStr_8_16(char * str,alt_u8 x,alt_u8 y)
  254. {
  255. alt_u8 i = 0;
  256. while(*str)
  257. {
  258. //if need line breaks
  259. if(x + (8 * i) > 76)
  260. {
  261. x = 0;
  262. i = 0;
  263. y += 2;
  264. }
  265. //write a char(8*16)
  266. WriteChar_8_16(*str,x + (8 * i),y);
  267. str ++;
  268. i ++;
  269. }
  270. }
  271. //every row contains 5 characters,there are 3 rows (font = 16 * 16)//
  272. ///////////////////////////////////////////////////////////////////////////////////////////////////
  273. ///////// x ///////////
  274. //0 1 2 3 ... 81 82 83// y = 0
  275. //0 1 2 3 ... 81 82 83//
  276. //0 1 2 3 ... 81 82 83// y = 1
  277. //0 1 2 3 ... 81 82 83//
  278. //0 1 2 3 ... 81 82 83// y = 2
  279. //0 1 2 3 ... 81 82 83//
  280. ///////////////////////////////////////////////////////////////////////////////////////////////////
  281. //write a Chinese character(16*16)
  282. void WriteHanzi(char Hanzi[],alt_u8 x,alt_u8 y)
  283. {
  284. alt_u8 i;
  285. //write the first row
  286. SetXY(x,y * 2);
  287. for(i = 0;i < 16;i ++)
  288. LcdWrite(Hanzi[i],DATA);
  289. //write the second row
  290. SetXY(x,2 * y + 1);
  291. for(i = 16;i < 32;i ++)
  292. LcdWrite(Hanzi[i],DATA);
  293. }
  294. //write a Chinese sentence(16*16),auto line breaks,x is between 0 and 58
  295. void WriteHanziStr(char Hanzi[],alt_u8 x,alt_u8 y,alt_u8 num)
  296. {
  297. alt_u8 num_i,i = 0;
  298. for(num_i = 0;num_i < num;num_i ++)
  299. {
  300. //if need line breaks
  301. if(x + (16 * num_i) > 58)
  302. {
  303. x = 0;
  304. i = 0;
  305. y += 1;
  306. }
  307. //write a Chinese character(16*16)
  308. WriteHanzi(Hanzi + 32 * num_i,x + (16 * i),y);
  309. i ++;
  310. }
  311. }
  312. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  313. /////* 以下是画图的各种操作函数 *//////
  314. //* 包括84*48,高度为8的倍数的图片 *//
  315. /////////////////////////////////////////////////////////////////////////////////////////////////////
  316. ///////// x /////////
  317. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 0
  318. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 1
  319. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 2
  320. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 3
  321. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 4
  322. //0 1 2 3 4 5 6 7 8 9 10 11 12 13// y = 5
  323. /////////////////////////////////////////////////////////////////////////////////////////////////////
  324. //draw a picture(84*48),don't need coordinates
  325. void DrawPicture(char bitmap[])
  326. {
  327. alt_u16 i;
  328. for(i = 0;i < LCD_X * LCD_Y / 8;i ++)
  329. LcdWrite(bitmap[i],DATA);
  330. }
  331. //列行扫描(每列=8bit,n行)
  332. //draw a picture(width*height(a multiple of 8)),need coordinates
  333. void DrawBitmap(char bitmap[],alt_u8 x,alt_u8 y,alt_u8 width,alt_u8 height)
  334. {
  335. alt_u8 width_i,height_i;
  336. //draw the height_i row
  337. for(height_i = 0;height_i < height / 8;height_i ++)
  338. {
  339. SetXY(x,y + height_i);
  340. //draw a row(width column)
  341. for(width_i = 0;width_i < width;width_i ++)
  342. {
  343. LcdWrite(bitmap[width_i + height_i * width],DATA);
  344. }
  345. }
  346. }
  347. //列扫描
  348. void DrawBitmap_col(char bitmap[],alt_u8 x,alt_u8 y,alt_u8 width,alt_u8 height)
  349. {
  350. alt_u8 i,j,z;
  351. if(height%8 == 0) //必须是8bit的整数倍
  352. {
  353. for(i=0; i<width; i++)
  354. {
  355. for(j=0; j<height/8; j++)
  356. {
  357. SetXY(x+i, y+j);//换行列
  358. LcdWrite(bitmap[z++], DATA);//写最小一列(8bit)
  359. }
  360. }
  361. }
  362. }
  363. #define LCD_Clear(x) LcdClearAll()
  364. /*********************************************************************************
  365. 名称:void LCD_ShowCharString(uint16_t x, uint16_t y, const uint8_t *p, uint16_t PenColor, uint16_t BackColor)
  366. 参数:x,y 起始坐标
  367. p 指向字符串起始地址
  368. PenColor 字符颜色
  369. BackColor 背景颜色
  370. 功能:
  371. 备注:用16字体,可以调节 此函数不能单独调用
  372. *********************************************************************************/
  373. void LCD_ShowCharString(uint16_t x, uint16_t y, const uint8_t *p, uint16_t PenColor, uint16_t BackColor)
  374. {
  375. uint8_t size = 16; /*---字符大小默认16*8---*/
  376. if(x>MAX_CHAR_POSX){x=0;y+=size;} /*超出X轴字体最小单位,换行*/
  377. if(y>MAX_CHAR_POSY){y=x=0;LCD_Clear(WHITE);} /*超出Y轴字体最小单位,回到原点,并且清屏*/
  378. //LCD_ShowChar(x, y, *p, size, PenColor, BackColor); /*0表示非叠加方式*/
  379. PutChar(*p ,x, y);
  380. //WriteChar_8_16(*p ,x, y);
  381. }
  382. /*********************************************************************************
  383. *名称: u16 findHzIndex(u8 *hz)
  384. *参数:hz
  385. *功能:索引汉字存储的内存地址
  386. *备注:
  387. *********************************************************************************/
  388. u16 findHzIndex(u8 *hz) /* 在自定义汉字库在查找所要显示 */
  389. /* 的汉字的位置 */
  390. {
  391. u16 i=0;
  392. FNT_GB16 *ptGb16 = (FNT_GB16 *)GBHZ_16; /*ptGb16指向GBHZ_16*/
  393. while(ptGb16[i].Index[0] > 0x80)
  394. {
  395. if ((*hz == ptGb16[i].Index[0]) && (*(hz+1) == ptGb16[i].Index[1])) /*汉字用两位来表示地址码*/
  396. {
  397. return i;
  398. }
  399. i++;
  400. if(i > (sizeof((FNT_GB16 *)GBHZ_16) / sizeof(FNT_GB16) - 1)) /* 搜索下标约束 */
  401. {
  402. break;
  403. }
  404. }
  405. return 0;
  406. }
  407. #if 0
  408. /*********************************************************************************
  409. *名称:void WriteOneHz(uint16_t x0, uint16_t y0, uint8_t *pucMsk, uint16_t PenColor, uint16_t BackColor)
  410. *参数:x0,y0 起始坐标
  411. *pucMsk 指向
  412. PenColor 字符颜色
  413. BackColor 背景颜色
  414. *功能:
  415. *备注:此函数不能单独作为汉字字符显示
  416. *********************************************************************************/
  417. void WriteOneHz(u16 x0, u16 y0, u8 *pucMsk, u16 PenColor, u16 BackColor)
  418. {
  419. u16 i,j;
  420. u16 mod[16]; /* 当前字模 16*16 */
  421. u16 *pusMsk; /* 当前字库地址 */
  422. u16 y;
  423. u16 size = 16; /*汉字默认大小16*16*/
  424. pusMsk = (u16 *)pucMsk;
  425. for(i=0; i<16; i++) /* 保存当前汉字点阵式字模 */
  426. {
  427. mod[i] = *pusMsk; /* 取得当前字模,半字对齐访问 */
  428. mod[i] = ((mod[i] & 0xff00) >> 8) | ((mod[i] & 0x00ff) << 8);/* 字模交换高低字节*/
  429. pusMsk = pusMsk+1;
  430. }
  431. y = y0;
  432. LCD_WindowMax(x0,y0,x0+size,y0+size); /*设置窗口*/
  433. LCD_SetCursor(x0,y0); /*设置光标位置 */
  434. LCD_WriteRAM_Prepare(); /*开始写入GRAM*/
  435. for(i=0; i<16; i++) /* 16行 */
  436. {
  437. for(j=0; j<16; j++) /* 16列 */
  438. {
  439. if((mod[i] << j) & 0x8000) /* 显示第i行 共16个点 */
  440. {
  441. LCD_WriteRAM(PenColor);
  442. }
  443. else
  444. {
  445. LCD_WriteRAM(BackColor); /* 用读方式跳过写空白点的像素*/
  446. }
  447. }
  448. y++;
  449. }
  450. LCD_WindowMax(0x0000,0x0000,240,320); /*恢复窗体大小*/
  451. }
  452. #endif
  453. /*********************************************************************************
  454. *名称:void LCD_ShowHzString(u16 x0, u16 y0, u8 *pcStr, u16 PenColor, u16 BackColor)
  455. *参数:x0,y0 起始坐标
  456. pcStr 指向
  457. PenColor 字体颜色
  458. BackColor 字体背景
  459. *功能:显示汉字字符串
  460. *备注:这个函数不能单独调用
  461. *********************************************************************************/
  462. void LCD_ShowHzString(u16 x0, u16 y0, u8 *pcStr, u16 PenColor, u16 BackColor)
  463. {
  464. u16 usIndex;
  465. u8 size = 16;
  466. FNT_GB16 *ptGb16 = 0;
  467. ptGb16 = (FNT_GB16 *)GBHZ_16;
  468. if(x0>MAX_HZ_POSX){x0=0;y0+=size;} /*超出X轴字体最小单位,换行*/
  469. if(y0>MAX_HZ_POSY){y0=x0=0;LCD_Clear(WHITE);} /*超出Y轴字体最小单位,回到原点,并且清屏*/
  470. usIndex = findHzIndex(pcStr);
  471. //WriteOneHz(x0, y0, (u8 *)&(ptGb16[usIndex].Msk[0]), PenColor, BackColor); /* 显示字符 */
  472. WriteHanzi((char *)&(ptGb16[usIndex].Msk[0]), x0, y0);
  473. }
  474. /*********************************************************************************
  475. *名称:void LCD_ShowString(u16 x0, u16 y0, u8 *pcstr, u16 PenColor, u16 BackColor)
  476. *参数:x0 y0 起始坐标
  477. pcstr 字符串指针
  478. PenColor 字体颜色
  479. BackColor 字体背景色
  480. *功能:调用字符和汉字显示函数,实现字符串显示
  481. *备注:
  482. *********************************************************************************/
  483. void LCD_ShowString(u16 x0, u16 y0, u8 *pcStr, u16 PenColor, u16 BackColor)
  484. {
  485. while(*pcStr!='\0')
  486. {
  487. if (x0>MAX_HZ_POSX) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  488. {
  489. y0+=16;
  490. x0=0;
  491. }
  492. if (y0>MAX_HZ_POSY) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  493. {
  494. y0=0;
  495. }
  496. if(*pcStr>0x80) /*显示汉字*/
  497. {
  498. LCD_ShowHzString(x0, y0, pcStr, PenColor, BackColor);
  499. pcStr += 2;
  500. x0 += 16;
  501. }
  502. else /*显示字符*/
  503. {
  504. LCD_ShowCharString(x0, y0, pcStr, PenColor, BackColor);
  505. pcStr +=1;
  506. x0+= 8;
  507. }
  508. }
  509. }
  510. void RefreshLCD ( void )
  511. {
  512. #if LCD_def
  513. u8 i;
  514. for ( i = 0; i < 6; i++ )
  515. {
  516. PutStr(n5110_string[i], 0, i);
  517. }
  518. #endif
  519. }
  520. /*--------------下面三个函数 实现字库的调用及显示-------------------*/
  521. FATFS fs;
  522. FIL fsrc; /* file objects */
  523. UINT br; // File R/W count
  524. enum ziType{
  525. ziType_12,
  526. ziType_16,
  527. ziType_24,
  528. ziType_Max
  529. };
  530. static u8 SPI_FLASH_BufferRead(char* getStr, char* zi, char ziType)
  531. {
  532. FRESULT res;
  533. u8 error[]="Cann't file HZK bin.";
  534. u8 zi_h = zi[0];
  535. u8 zi_l = zi[1];
  536. unsigned long int findAddr, ziSize;
  537. if(ziType == ziType_12){//12*12 = 24
  538. findAddr = (unsigned long int)(((zi_h-0xa1)*94)+(zi_l-0xa1))*24;
  539. ziSize = 24;
  540. }
  541. else if(ziType == ziType_16){//16*16 = 32
  542. findAddr = (unsigned long int)(((zi_h-0xa1)*94)+(zi_l-0xa1))*32+(unsigned long int)0x2FEB0;
  543. ziSize = 32;
  544. }
  545. else if(ziType == ziType_24){//24*24 = 72
  546. findAddr = (unsigned long int)(((zi_h-0xa1)*94)+(zi_l-0xa1))*72+(unsigned long int)0x6FCF0;
  547. ziSize = 72;
  548. }
  549. else
  550. return 0;
  551. f_mount(0, &fs);
  552. //HZK16.bin
  553. /* Infinite loop */
  554. res = f_open(&fsrc, "/sys/HZK.bin", FA_OPEN_EXISTING | FA_READ); /* 在SD卡里搜索HZK16.bin*/
  555. if(res != 0)
  556. {
  557. PutStr((char *)error, 0, 0);
  558. return 0;
  559. }
  560. f_lseek(&fsrc, findAddr);
  561. f_read(&fsrc, getStr, ziSize, &br);
  562. f_close(&fsrc);
  563. f_mount(0, NULL);
  564. return 1;
  565. }
  566. static uint8_t Find_Chinese(uint8_t* str, uint8_t* p)
  567. {
  568. uint8_t High8bit,Low8bit;
  569. FRESULT res;
  570. uint8_t error[]="Please put the sys folder which include the font file HZK16.bin into the SD card root directory. ";
  571. High8bit=*str; /* 高8位数据 */
  572. Low8bit=*(str+1); /* 低8位数据 */
  573. f_mount(0, &fs);
  574. //HZK16.bin
  575. /* Infinite loop */
  576. res = f_open(&fsrc, "/sys/ZK_1212_1616_2424.bin", FA_OPEN_EXISTING | FA_READ); /* 在SD卡里搜索HZK16.bin*/
  577. if(res != 0)
  578. {
  579. LCD_ShowString(0,0,error,RED ,BLACK );
  580. return 0;
  581. }
  582. f_lseek(&fsrc,32*((High8bit-0xa0-1)*94+(Low8bit-0xa0-1)));
  583. f_read(&fsrc, p, 32, &br);
  584. f_close(&fsrc);
  585. f_mount(0, NULL);
  586. return 1;
  587. }
  588. /*********************************************************************************
  589. * 名 称:void PutChinese(u16 x, u16 y, u8 *c, u32 PenColor, u32 BackColor)
  590. * 入口参数:u16 x,u16 y 字符坐标位置
  591. u8 *c 汉字的指针
  592. u32 PenColor画笔颜色
  593. u32 BackColor背景颜色
  594. * 出口参数:无
  595. * 功 能:从SPI_FLASH里查找汉字基地址,
  596. 并将32字节的点阵数据送到LCD显示
  597. * 说 明:只能被GUI_Put调用
  598. *********************************************************************************/
  599. u8 buffer_r[32];
  600. u8 *c_r;
  601. void PutChinese(u16 x, u16 y, u8 *c, u32 PenColor, u32 BackColor)
  602. {
  603. //u16 i=0;
  604. //u16 j=0;
  605. u8 buffer[32];
  606. //u16 tmp_char=0;
  607. if(!Find_Chinese(c,buffer))
  608. {
  609. c_r = c;
  610. memcpy(buffer_r,buffer,32);
  611. WriteHanzi((char *)&buffer, x, y);
  612. #if 0
  613. LCD_WindowMax(x,y,x+16,y+16); /*设置窗口*/
  614. LCD_SetCursor(x,y); /*设置光标位置 */
  615. LCD_WriteRAM_Prepare();
  616. /* 16*16汉字点阵,共有16行 每行16个点,存储的时候是以字节为单位
  617. 需合并成字*/
  618. for (i=0;i<16;i++)
  619. {
  620. tmp_char=buffer[i*2];
  621. tmp_char=(tmp_char<<8);
  622. tmp_char|=buffer[2*i+1]; /*现在tmp_char存储着一行的点阵数据*/
  623. for (j=0;j<16;j++)
  624. {
  625. if((tmp_char<<j) & 0x8000)
  626. LCD_WriteRAM(PenColor);
  627. else
  628. LCD_WriteRAM(BackColor);
  629. }
  630. }
  631. LCD_WindowMax(0x00,0x00,240,320); /*恢复窗体大小*/
  632. #endif
  633. }
  634. }
  635. //逐行式 转列行式
  636. /*
  637. 0040 11
  638. 4048 11 11 11
  639. 37FC 1111 111111111111111111
  640. 1040 11 11
  641. 0044 11 11
  642. 0FFE 1111111111111111111111
  643. 0910 11 11 11
  644. 128C 11 11 11 1111
  645. 24F4 11 11 11111111 11
  646. E110 111111 11 11
  647. 2310 11 1111 11
  648. 24A0 11 11 11 11
  649. 2840 11 11 11
  650. 20A0 11 11 11
  651. 231E 11 1111 11111111
  652. 0C04 1111 11
  653. 汉字库格式:逐行式
  654. byte1 byte2 [1 2 3 4 5 6 7 8] [9 10 11 12 13 14 15 16]
  655. byte3 byte4
  656. ***** *****
  657. 转化:
  658. u16[0] [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  659. 转化:
  660. u16[0] [1]
  661. [2]
  662. [3]
  663. **
  664. [16]
  665. 转化:
  666. u8[0] u8[2] u8[4] u8[6] u8[8] u8[10] u8[12] u8[14]
  667. u8[1] u8[3] u8[5] u8[7] u8[9] u8[11] u8[13] u8[15]
  668. 转化:
  669. u8[0] u8[1] u8[2] u8[3] u8[4] u8[5] u8[6] u8[7]
  670. u8[8] u8[9] u8[10] u8[11] u8[12] u8[13] u8[14] u8[15]
  671. 5110显示格式:阴码,列行式,逆向(低位在前)
  672. 1.一列八点阵
  673. 2.低位在前
  674. byte1 [1] byte2 [9] byte3 [17] byte4 [25]
  675. [2] [10] [18] [26]
  676. [3] [11] [19] [27]
  677. [4] [12] [20] [28]
  678. [5] [13] [21] [29]
  679. [6] [14] [22] [30]
  680. [7] [15] [23] [31]
  681. [8] [16] [24] [32]
  682. */
  683. u8 ReturnHzNum(u8 in)
  684. {
  685. if(in<16)
  686. {
  687. if(in<8) return (2*in);
  688. else return (2*(in-8)+1);
  689. }
  690. return 0xFF;
  691. }
  692. void xing2lie(u8 inBuffer[])
  693. {
  694. u16 HzkBuffer[16]={0};
  695. u16 PlayBuffer[16]={0};
  696. u8 outBuffer2[32]={0};
  697. u8 res;
  698. u8 i, j;
  699. for (i=0;i<16;i++)
  700. {
  701. HzkBuffer[i] = inBuffer[i*2]<<8 | inBuffer[2*i+1];
  702. }
  703. for(i=0;i<16;i++)
  704. {
  705. for(j=0;j<16;j++)
  706. {
  707. res = HzkBuffer[j]>>(15-i)?1:0;
  708. PlayBuffer[i] |= res<<(15-j);
  709. }
  710. }
  711. for (i=0;i<16;i++)
  712. {
  713. outBuffer2[i*2] = (PlayBuffer[i]&0xFF00)>>8;
  714. outBuffer2[i*2+1] = PlayBuffer[i]&0x00FF;
  715. }
  716. memcpy(inBuffer, outBuffer2, 32);
  717. }
  718. char hz_1[][32]={
  719. // 我(0) 们(1)
  720. {0x04,0x20,0x04,0x20,0x44,0x42,0x44,0x41,0x7F,0xFE,0x84,0x80,0x84,0x80,0x04,0x08,
  721. 0x04,0x08,0xFF,0x10,0x04,0xE0,0x44,0x58,0x35,0x84,0x04,0x02,0x04,0x0F,0x00,0x00},/*"我",0*/
  722. {0x01,0x00,0x02,0x00,0x0F,0xFE,0x38,0x00,0xC0,0x00,0x0F,0xFE,0x80,0x00,0x70,0x00,
  723. 0x20,0x00,0x00,0x00,0x20,0x00,0x20,0x04,0x20,0x02,0x3F,0xFC,0x00,0x00,0x00,0x00},/*"们",1*/
  724. {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  725. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*"们",1*/
  726. };
  727. /*********************************************************************************
  728. * 名 称:void GUI_Put(u16 x, u16 y, u8 *str,u32 PenColor, u32 BackColor)
  729. * 入口参数:u16 x,u16 y 字符坐标位置
  730. u8 *c 汉字的指针
  731. u32 PenColor画笔颜色
  732. u32 BackColor背景颜色
  733. * 出口参数:无
  734. * 功 能:计算汉字显示坐标
  735. * 说 明:
  736. *********************************************************************************/
  737. char hzk_buffer[32];
  738. void DispOneChs12x12(u8 row,u8 addr,u8 *p);
  739. void GUI_Put(u16 x, u16 y, u8 *str,u32 PenColor, u32 BackColor)
  740. {
  741. //x:0~84 y:0~6
  742. do
  743. {
  744. if ( *str < 0x80) /* 显示字符,字符点阵直接从font.h里调用,大小为16*8 */
  745. {
  746. if (x>LCD_X) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  747. {
  748. y+=1;
  749. x=0;
  750. }
  751. if (y>LCD_Y) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  752. {
  753. y=0;
  754. }
  755. //6*8
  756. DrawBitmap((char *)&ASCII_6_8[*str - 0x20][0], x, y, 6, 8);
  757. x+=6;
  758. str++;
  759. }
  760. else /*大于等于0x80判断为汉字字符*/
  761. {
  762. if (x>LCD_X-12) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  763. {
  764. y+=1;
  765. x=0;
  766. }
  767. if (y>LCD_Y-1) /*保证剩余的空间能放下一个16*16的字,否则换行 */
  768. {
  769. y=0;
  770. }
  771. #if 0
  772. //16*16
  773. if(Find_Chinese(str, hzk_buffer))
  774. {
  775. xing2lie(hzk_buffer);
  776. DrawBitmap_col(hzk_buffer, x, y, 16, 16);
  777. //DrawBitmap(hzk_buffer, x, y, 16, 16);
  778. }
  779. #else
  780. if(SPI_FLASH_BufferRead(hzk_buffer,(char *)str,ziType_12))
  781. {
  782. //DrawBitmap(hzk_buffer, x, y, 16, 16);
  783. DispOneChs12x12(y, x, hzk_buffer);
  784. }
  785. #endif
  786. x+=12;//16;
  787. str += 2;
  788. delay_ms(500);
  789. }
  790. }while(*str!=0);
  791. }
  792. /**********************************************************************/
  793. u8 Y0Ram[84]; //第0行汉字的临时缓存
  794. u8 Y1Ram[84];
  795. u8 Y2Ram[84];
  796. u8 Y3Ram[84];
  797. #define Lcd5110SetXY(x,y) SetXY(x,y)
  798. #define Lcd5110WriteDta(x) LcdWrite(x,DATA)
  799. /*---------------------------------------------
  800. 在某行某地址显示中文字符,
  801. -----------------------------------------------*/
  802. void DispOneChs12x12(u8 row,u8 addr,u8 *p)
  803. {
  804. u8 i, LocalHalfWidth,LocalFullWidth; //半宽字体,全宽字体
  805. if (row==0)//按照4行显示,首行为0,地址就是0-3行,不是控制器的地址
  806. {
  807. Lcd5110SetXY(addr, row);// 列,页
  808. for (i=0; i<12;i++) //上半部分 12个像素
  809. {
  810. Lcd5110WriteDta(p[i]);
  811. }
  812. Lcd5110SetXY(addr, row+1);
  813. /*字体的下半部分需要存储起来*/
  814. for (i=12; i<24;i++) //下半部分 12个像素
  815. {
  816. Y0Ram[addr+i-12]=p[i]; //第0行的下半部分12个字节存起来,数组要保存文字的下半部分和这些数据在什么位置 0-83
  817. Lcd5110WriteDta(Y0Ram[addr+i-12] | Y1Ram[addr+i-12]<<4 );
  818. }
  819. }
  820. if (row==1)
  821. {
  822. Lcd5110SetXY(addr, row);// 列,页
  823. for (i=0; i<12;i++) //上半部分 12个像素
  824. {
  825. Y1Ram[addr+i]=p[i];//第1行上半部分存起来
  826. Lcd5110WriteDta(Y1Ram[ addr+i]<<4 |Y0Ram[addr+i]);
  827. }
  828. Lcd5110SetXY(addr, row+1);// 列,页
  829. for (i=12; i<24;i++) //下半部分 12个像素
  830. {
  831. Lcd5110WriteDta(p[i]<<4 | p[i-12]>>4 );
  832. }
  833. }
  834. if (row==2)//按照4行显示,首行为0,地址就是0-3行,不是控制器的地址
  835. {
  836. Lcd5110SetXY(addr, row+1);// 列,页
  837. for (i=0; i<12;i++) //上半部分 12个像素
  838. {
  839. Lcd5110WriteDta(p[i]);
  840. }
  841. Lcd5110SetXY(addr, row+2);
  842. /*字体的下半部分需要存储起来*/
  843. for (i=12; i<24;i++) //下半部分 12个像素
  844. {
  845. Y2Ram[addr+i-12]=p[i]; //第0行的下半部分12个字节存起来,数组要保存文字的下半部分和这些数据在什么位置 0-83
  846. Lcd5110WriteDta(Y2Ram[addr+i-12] | Y3Ram[addr+i-12]<<4 );
  847. }
  848. }
  849. if (row==3)
  850. {
  851. Lcd5110SetXY(addr, row+1);// 列,页
  852. for (i=0; i<12;i++) //上半部分 12个像素
  853. {
  854. Y3Ram[addr+i]=p[i];//第1行上半部分存起来
  855. Lcd5110WriteDta(Y3Ram[ addr+i]<<4 |Y2Ram[addr+i]);
  856. }
  857. Lcd5110SetXY(addr, row+2);// 列,页
  858. for (i=12; i<24;i++) //下半部分 12个像素
  859. {
  860. Lcd5110WriteDta(p[i]<<4 | p[i-12]>>4 );
  861. }
  862. }
  863. }