本帖最后由 cgd 于 2014-6-2 19:01 编辑
一般不带字库的LCD屏显示汉字无疑是首先获得汉字的字模数据,然后根据字模在液晶上显示出来。
通常有两种方法,一种方法是把字模放在源程序中,也就是存在单片机的flash中(通常情况下);此种方法的优点是不需要额外的器件,缺点是存储数据量有限,生成字模数组比较麻烦,且不灵活。
另一种方法就是把字模数据(字库)存在大容量存储器中(SD卡,flash等),在需要显示的时候去存储器中查找。此方法优点是灵活性强,通常可以显示任意字符。缺点是需要大容量存储器,硬件成本高。
由于MSP-EXP430F5529评估板具有SD卡存储器,所以采用第二种方法来做个显示示例。
我们常用的简体字符集为GB2312字符集,附编码表:
附字库:
见附件。
汉字编码对应字库中起始地址的关系为:
offset =(字模所占字节数)*((HighByte-0xA1)*0x5E + (LowByte-0xA1));
示例代码(在MSP-EXP430F5529自带例程中添加):- ...
- f_mount(0, &fatfs);
- Dogs102x6_chineseDraw(0, 0, "床前明月光,");
- Dogs102x6_chineseDraw(1, 0, "疑是地上霜。");
- Dogs102x6_chineseDraw(2, 0, "举头望明月,");
- Dogs102x6_chineseDraw(3, 0, "低头思故乡。");
- while(1);
- ...
复制代码
- <P>void convert_buffer32(unsigned char *buffer);</P>
- <P>void Dogs102x6_chineseDraw(int raw, int col, unsigned char* buffer)
- {
- //打开字库文件
- FRESULT rc;
- FIL zkFile;
- DWORD offset=0, hi, lo;
- UINT len;
- unsigned i;
- unsigned char font[32];
- raw *= 2;
- rc = f_open (&zkFile, "st16.DZK", FA_READ);
- if (rc != FR_OK)
- return;
- while (*buffer)
- {
- hi = (DWORD)*buffer++;
- lo = (DWORD)*buffer++;
- if (hi < 0xA1U || lo < 0xA1U)
- break;
- offset = ((hi-0xA1U)*0x5EU+(lo-0xA1U))*(16*16/8);
- rc = f_lseek (&zkFile, offset);
- if (rc != FR_OK)
- break;
- rc = f_read (&zkFile, font, 32, &len);
- if (rc != FR_OK || len != 32)
- break;
- convert_buffer32(font);
- Dogs102x6_setAddress(raw, col);
- Dogs102x6_writeData(&font[0], 16);
- Dogs102x6_setAddress(raw+1, col);
- Dogs102x6_writeData(&font[16], 16);
- col+=16;
- }
- rc = f_close(&zkFile);
- if (rc != FR_OK)
- while(1);
- }</P>
- <P>
- /*
- [MSB .......... LSB]
- byte[0][1]
- byte[2][3]
- byte[4][5]
- byte[6][7]
- byte[8][9]
- byte[10][11]
- .
- .
- .
- .
- */
- void convert_buffer32(unsigned char *buffer)
- {
- unsigned char temp[32];
- unsigned char shift;
- int i, j;
- for(i=0; i<32; i++) temp = 0;
- shift = 0x80;
- for(i=0; i<8; i++)
- {
- for(j=0; j<16; j+=2)
- {
- temp <<= 1;
- if (buffer[j]&shift)
- temp |= 0x01;
- temp[8+i] <<= 1;
- if (buffer[j+1]&shift)
- temp[8+i] |= 0x01;
- temp[16+i] <<= 1;
- if (buffer[16+j]&shift)
- temp[16+i] |= 0x01;
- temp[24+i] <<= 1;
- if (buffer[16+j+1]&shift)
- temp[24+i] |= 0x01;
- }
- shift >>= 1;
- }
- memcpy(buffer, temp, 32);
- }</P>
复制代码
附图片一张:
|