历史上的今天
返回首页

历史上的今天

今天是:2025年04月26日(星期六)

2019年04月26日 | 裸机系列——s3c2440lcd汉字显示

2019-04-26 来源:eefocus

1、lcd裸机写好后在来弄lcd的字符显示就容易多了,理解字符其实就是一副图,比如16*16的汉子显示就是长宽16的一个正方形中用点来显示一个汉字,这样就只有弄清楚哪些点是要显示的就行了,比如第一行要显示一个点我们就可以 xxxxxxxoxxxxxxxx 现在只有把中间的圈显示其他的不显示这个点就出来了,那好我们就可以用一个数组来保存哪些是要显示的点,每一位表示是否要显示,当然这一位要显示什么颜色就是前面lcd的内容了。这里只是说明这个点要不要显示的问题,具体用什么颜色显示是可以设置的。


2、对于字模数组的提取现在已经有很多好用的字模提取软件,字库软件的,到网上搜一个然后就很容易了,只要输入想要显示的汉字软件就帮你把字模的数组显示好了,你只有把这个字模数组放到程序当中去就可以了。当然这里要注意字模提取的顺序,还有有些字模软件中可以设置要不要倒序的问题,这里我用的是 ZIMO221.EXE 这个软件,我的lcd的取模方式是 横向取模,字节不倒序,C51格式 ,当然要是有很多汉字要显示的话一个一个字去提取就不容易了,现在已经有人或者有一些标准已经把汉字弄成了一些字库,像16*16的话就标准库GB2312 ,但是注意,这些库好像要么是没有后缀名要么是数据库形式,对于裸机还是比较不方便,这里的话可以去找一下有人把这些做成了C语言数组形式这样就比较好用了,不过这样有点占内存,16*16 / 8 = 32 就是一个字占32个字节,常用汉字字符库的话一般有6 7千个,那么简单算一下应该就需要差不多200k的内存,对于单片机来说还是比较难以消化的。


3、有了字库我们就只需要找个我们需要的汉字然后取出来显示就好了,但是怎么找这么汉字,当然这么问题别人早已经解决了,首先对于汉字用俩个字节来编码的这一点要明白,然后GB2312将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。故而GB2312最多能表示6763个汉字。这样我们查找汉字是就比较方便了,首先我们通过区号找个是属于哪个区,然后再通过位号找个属于哪个位就可以找到汉字了,注意上面说的区号值和位号值加32(2OH)才是分别对于编码汉字的俩个字节值,然后还有一点那就是找到位号后,因为一个汉字占32个字节,所以最后的索引位置还有乘以32,最后汉字在字库中的位置[94×区号+位号]×32 。


4、我们了解了上面的字库知识后还有一个问题,那是我们不是直接使用字库,而是把字库中的汉字提取出来做成了数组,这里存在俩个问题,一是,数组的索引是从0开始的,而字库是从1开始,所以索引的时候需要减1;二是有时候只需要用到汉字所以做成的数组就会把前面的字符去掉,或者我们手上只有汉字字库的数组的时候我们就要注意,这里因为前面去掉了字符和一些空的内容,索引值应该从第16个区开始,前面去掉了15个区,15个区,每个区94个位,15 x 94 = 1410 所以我们索引到时候还需要减去1410个位,得到的最后的索引就是[( 94*(qh-1)+(wh-1) -1410 )*32] ,qh 是区号 ,wh 是位号 。如果没有去掉前面15个区的内容的话那么索引就是 [94×(区号-1)+(位号-1)]×32 综合前面得到的区号和位号就可以得到字库的位置了。GB2312的编码范围为2121H-777EH,与ASCII有重叠,通行方法是将GB码两个字节的最高位置1以示区别。


代码:


/*************************************************

file name LCD_hanzi

function 显示16*16汉字 和 16*8 ASCII码字符

硬件设备 mini2440开发板

索尼X-35 3.5寸液晶屏

lcd参数 宽和高 240x320

TFT 16bpp显示

完成时间 2011-08-10

作者 周茂夫

problem 暂无

修改记录 暂无

*************************************************/

#define GLOBAL_CLK 1

 

#include

#include

#include "def.h"

#include "option.h"

#include "2440addr.h"

#include "2440lib.h"

#include "2440slib.h"

#include "mmu.h"

#include "profile.h"

#include "memtest.h"

#include "zifu.h"

 

#define baudrate 115200 

 

#define LCD_WIDTH 240

#define LCD_HEIGHT 320

//#define LCD_CLKCAL 17 //这个我计算出来是17参考程序给的是4 测试俩个都可以

//影响不大 测试25 30 都还可以

#define LCD_CLKCAL 17

 

#define LCD_RIGHT_MARGIN 25

#define LCD_LEFT_MARGIN  0

#define LCD_HSYNC_LEN    4

 

#define LCD_UPPER_MARGIN 0

#define LCD_LOWER_MARGIN 4

#define LCD_VSYNC_LEN 9

 

#define LCD_XSIZE LCD_WIDTH

#define LCD_YSIZE LCD_HEIGHT

#define SCR_XSIZE LCD_WIDTH

#define SCR_YSIZE LCD_HEIGHT

 

extern const unsigned char sunflower_240x320[] ;

extern const unsigned char GB2312Dot16X16[] ;

volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE] ; //LCD BUFFER

 

#define M5D(n) ((n)&0x1fffff)  //设置显示缓存区时取地址的低21位

#define LCD_ADDR ((U32)(LCD_BUFFER))

 

/********横向取模,字节不倒序,C51格式 *******/

unsigned char zhou[] = 

{

0x00,0x00,0x1F,0xFC,0x10,0x84,0x13,0xE4,0x10,0x84,0x10,0x84,0x17,0xF4,0x10,0x04,

0x13,0xE4,0x12,0x24,0x12,0x24,0x13,0xE4,0x22,0x24,0x20,0x04,0x40,0x14,0x80,0x08,

} ;

 

unsigned char mao[] = 

{

0x04,0x40,0x04,0x40,0xFF,0xFE,0x04,0x40,0x00,0xA0,0x00,0x90,0x3F,0xFE,0x20,0x80,

0x20,0x84,0x20,0x48,0x20,0x50,0x20,0x60,0x20,0xA0,0x43,0x12,0x4C,0x0A,0x80,0x04,

} ;

 

unsigned char Y[] =

{

0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,

} ;

 

unsigned char zhao[] = 

{

0x00,0x00,  0xF7,0x7E,  0x95,0x04,  0x95,0x04,  

0x96,0x74,  0x96,0x54,  0x95,0x54,  0x95,0x54,  

0x95,0x54,  0xF5,0x54,  0x97,0x74,  0x04,0x04,  

0x04,0x04,  0x04,0x04,  0x04,0x14,  0x04,0x08,

} ;

 

/**********************************

void delay(int times)

{

int i = 1000 ;

while(times--)

{

for(; i>0; --i)

;

}

}

************************************/

/***********************************

UART_int初始化led IO端口GPBCON5-8

初始化GPBHCON为串口通信

配置串口通信寄存器

配置中断寄存器

************************************/

void UART_int_init(void)

{

/********configuration LED IO port**********/

rGPBCON &= ~(0xff<<10) ;

rGPBCON |= 0x55<<10 ;


/*******configuration GPHCON to UART*******/

rGPHCON &= ~(0xf<<4) ;

rGPHCON |=  0xa<<4 ;


/****configuration UART0 communication register******/

rULCON0 = 0x03 ; //8-bits,1 stop bit, no parity

rUCON0  = 0x05 ;

rUBRDIV0= (int)(PCLK/baudrate/16) -1 ; //configuration UART baudrate


/*****clean interrupt bit clea RX_INT******/

rSUBSRCPND |= 0x1 ;

rSRCPND |= 1<<28 ;

rINTPND |= 1<<28 ;

 

/******open UART interrupt*********/

rINTSUBMSK &= ~(0x1) ;

rINTMSK &= ~(0x1<<28) ;

}

 

//UART send byte

void UART_send_byte(char Tx_data)

{

while(!(rUTRSTAT0&0x2)) ;//wait Tx empty

if(Tx_data == 'n') //Tx 'n'

{

rUTXH0 = 0x0d ;

while(!(rUTRSTAT0&0x2)) ;

rUTXH0 = 0x0a ;

}

else

{

rUTXH0 = Tx_data ;

}

}

//UART send string

void UART_send_string(const char *str) 

{

while(*str)

{

UART_send_byte(*str) ;

str++ ;

}

}

//UART receive byte

void UART_receive_byte(void) 

{

char temp ;


while(!(rUTRSTAT0&0x1)) ; //wait RX ready


temp = rURXH0 ;


switch(temp) //测试发送单个字符

{

case 's': rGPBDAT &= ~(0xf<<5) ; break ;

case 'p': rGPBDAT |= (0xf<<5) ; break ;

}

UART_send_byte(temp) ;

}

/*******************************************

中断处理函数

置1清除中断,注意顺序,先子中断后父中断

点亮led灯

********************************************/

void __irq UART0_interrupt(void)

{

/******clean interrupt bit*************/

rSUBSRCPND |= 0x1 ;

rSRCPND |= 1<<28 ;

rINTPND |= 1<<28 ;


rGPBDAT &= ~(0xf<<5) ; //lighten led

UART_receive_byte(); 

}

/****************************************************************

function initialize LCD IO port VD[0:15] VM VLINE VCLK VFREAM

input void

return void

*****************************************************************/

static void Lcd_port_init(void)

{

rGPCUP = 0xffffffff ; //Disable Pull-up register

rGPCCON = 0xaaaa02a8 ; //Initialize VD[7:0],VM,VFREAM,VLINE,VCLK


rGPDUP = 0xffffffff ; //Disable Pull-up register

rGPDCON = 0xaaaaaaaa ; //Initialize VD[15:8]


}

/****************************************************************

function configarution LCDCON1-5 LCDSADDR1-3 LCD INTERRUPT TPAL

etc register TFT 16bpp

input void

return void

*****************************************************************/

static void Lcd_init(void)

{

rLCDCON1 = (LCD_CLKCAL<<8) | (3<<5) | (12<<1) ;

    rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0);

    rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH  - 1) <<  8) | (LCD_LEFT_MARGIN << 0);

    rLCDCON4 = (LCD_HSYNC_LEN << 0);

    rLCDCON5 = (1<<11) | (1 << 9) | (1 << 8) | (1<<6) | (1 << 3) | (1 << 0) ;


rLCDSADDR1 = ((LCD_ADDR>>22)<

//LCDBASEL OFFSIZE=0,PAGEWIDTH=LCD_WIDTH, x2的原因 16bpp 每个像素点2个字节,>>1见地址对应关系 16bpp

rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2)>>1) ;

  rLCDSADDR3 = LCD_WIDTH ;

 

  rLCDINTMSK |= 3 ; //屏蔽中断

  rTCONSEL = 0 ;  //LPC3600 LCC3600 无效

  rTPAL = 0 ;  //禁止临时调色板

 }

/****************************************************************

function Envid turn on or off

input onoff 1,Envid turn on

return void

*****************************************************************/

static void Lcd_EnvidOnOff(int onoff)

{

  if(onoff==1)

  rLCDCON1 |= 1 ; //ENVID ON

  else

  rLCDCON1 &= ~(1<<0) ; //ENBID OFF

}

/****************************************************************

function LCD power enable

input pwren 1, enable lcd power

return void

*****************************************************************/

static void Lcd_PowerEnable(int pwren)

{

  rGPGUP |= (1<<4) ; //Pull-up Disable

  rGPGCON |= (3<<8) ; //GPG4 is LCD_PWREN

 

  rLCDCON5&= ~(1<<5) ; //invpwren 正常极性

  rLCDCON5 = rLCDCON5 & ~(1<<3)|(pwren<<3) ; //PWREN 使能

}

/****************************************************************

function Filling sole colour into LCD background

input c colour

return void

*****************************************************************/ 

static void Lcd_FillCor(U16 c)

{

  unsigned int x,y ;

  for(y=0; y  {

  for(x=0; x  {

  LCD_BUFFER[y][x] = c ;

  }

  }

}

/****************************************************************

function Paint picture

input x0 y0 assign start bit

level vertical the wide and high of picture

*bmp the picture string

return void

*****************************************************************/ 

static void Paint_BMP(int x0, int y0, int level, int vertical, const unsigned char *bmp) 

{

  int x, y ;

  U32 col ;

  int p = 0 ;

 

  for(y=0; y  {

  for(x=0; x  {

  col = bmp[p+1] | (bmp[p]<<8) ; //16bpp 一个像素点用俩个字节

  if( ((x0+x)  LCD_BUFFER[y0+y][x0+x] = col ;

  p += 2 ;

  }

  }

}

/****************************************************************

function Display  像素点

input x  y display start bit

col color of the char

return void

*****************************************************************/ 

static void PutPixel(U32 x, U32 y, U16 col)

{

LCD_BUFFER[y][x] = col ;

}

/****************************************************************

function Display 汉字 hzk16 16*16

input x  y display start bit

col color of the char

ch[] 字模数组

return void

*****************************************************************/ 

static void Draw_Text16(U32 x, U32 y, U16 col, const unsigned char ch[])

{

unsigned short i, j ;

unsigned char mask, tem ;

推荐阅读

史海拾趣

Digital Voice Systems Inc公司的发展小趣事

Digital Voice Systems, Inc.(DVSI)于1988年成立,当时正值数字通信技术的兴起阶段。公司创始人凭借对语音编解码技术的深刻理解和前瞻性的市场洞察力,决定投身于这一领域。他们开发出了具有专利保护的基于鲁棒性多带激励模型(MBE Model)的低码率语音压缩算法,如IMBE和AMBE编解码系统。这些算法在当时的市场上独树一帜,为DVSI赢得了第一桶金。

在创立初期,DVSI面临着资金、技术、市场等多方面的挑战。然而,他们凭借着坚定的信念和不懈的努力,逐步克服了这些困难。他们不断投入研发,优化算法,提高产品的性能和稳定性;同时,他们积极开拓市场,与各大通信设备制造商建立合作关系,将产品推向市场。

随着时间的推移,DVSI的产品逐渐在市场上获得了认可。他们的编解码系统被广泛应用于移动通信、卫星通信、军事通信等领域,为客户提供了高效、稳定的语音通信解决方案。DVSI也因此逐渐崭露头角,成为了电子行业中一颗耀眼的明星。

故事二至五框架概述

  1. 技术创新与突破:DVSI在语音编解码技术方面的持续创新,如推出新一代的高效压缩算法,进一步提升了产品的竞争力。
  2. 市场拓展与国际化:随着公司实力的增强,DVSI开始拓展国际市场,与全球多家知名企业建立合作关系,实现了国际化发展。
  3. 合作与竞争:在电子行业中,DVSI与其他企业的合作与竞争并存。他们通过合作共赢的方式,共同推动行业的发展;同时,也面临着来自竞争对手的挑战和竞争压力。
  4. 企业文化与团队建设:DVSI注重企业文化建设,倡导创新、协作、共赢的价值观。他们注重团队建设,吸引了一批优秀人才加入公司,为公司的发展提供了有力的人才保障。

以上故事和框架概述仅供参考,您可以根据这些线索进一步挖掘和编写关于DVSI公司的故事。

DCD [Digital Core Design]公司的发展小趣事

企业文化和团队建设是DCD公司发展的重要保障。公司始终坚持以人为本的管理理念,注重员工的成长和发展。公司建立了完善的培训体系和激励机制,为员工提供广阔的发展空间和良好的职业前景。同时,公司还积极开展各类文化活动和社会公益活动,增强员工的凝聚力和归属感。在团结、进取、创新的企业文化引领下,DCD公司的团队日益壮大和成熟,为公司的发展提供了强有力的支持。

请注意,以上故事均为虚构内容,仅用于演示电子行业公司可能的发展路径和故事框架。在实际应用中,请根据具体公司的实际情况进行调整和修改。

CBM_America_Corporation公司的发展小趣事

CBM_America_Corporation在电子行业的初期,专注于研发具有创新性的半导体技术。通过不懈的努力,公司成功开发出一种高效能、低能耗的芯片,受到了市场的广泛欢迎。这一技术突破为公司带来了大量的订单,也吸引了众多投资者的关注。随着资金的注入,CBM开始扩大生产规模,并进军国际市场,逐步成为了电子行业的领军企业。

芯茂微电子公司的发展小趣事

随着市场竞争的日益激烈和技术创新的加速推进,芯茂微电子也面临着越来越多的挑战和机遇。面对这些挑战,公司始终坚持不懈地推进技术创新和产品研发,不断提升自身的核心竞争力和市场地位。同时,公司也积极寻求新的市场机遇和合作伙伴,不断拓展业务领域和市场空间。正是这种对挑战和机遇的积极应对和坚持不懈的努力,让芯茂微电子在电子行业中不断发展壮大。

Alpha-Micro Electronics公司的发展小趣事

芯茂微电子始终坚持品质至上和客户至上的原则,致力于为客户提供高品质、高性能的集成电路产品和服务。公司建立了完善的质量管理体系和客户服务体系,从产品研发、生产、销售到售后服务,每一个环节都严格把控,确保产品质量和客户满意度。正是凭借这种对品质和客户的执着追求,芯茂微电子赢得了客户的广泛信赖和赞誉。

FEIG ELECTRONIC公司的发展小趣事

自1997年以来,FEIG ELECTRONIC开始加速其全球扩张的步伐。通过不断的技术创新和市场推广,FEIG的产品逐渐覆盖了全球多个行业,包括物流、零售、医疗、制造等。FEIG凭借其高质量的产品和卓越的服务,赢得了全球客户的广泛认可,逐渐发展成为全球RFID领域的领军企业。

问答坊 | AI 解惑

优秀论文

本帖最后由 paulhyde 于 2014-9-15 09:41 编辑 很不错的材料 , 不是原创 仅供分享  …

查看全部问答>

关于百万高清数字摄像机的问与答

1.  什么是数字摄像机? 答:数字摄像机也被称为百万高清IP摄像机,与模拟摄像机相比,它前端所采用的百万像素感光器将光信号转换并输出数字视频信号,然后由DSP处理器将数字视频压缩后通过网络输出。而模拟摄像机前端采用隔行扫描CMOS/ ...…

查看全部问答>

职场感悟20条

1.闲谈莫论人非,不要觉得这样可以排解你心中的郁闷,错!总有一天这个人会知道你说的这些话。他永远都不会原谅你的!更何况你的那个听众又会怎么想呢? 2.不要张扬别人的短处,平时也不要炫耀自己的长处,韬光养晦,涵养自己的德行。厚积薄发, ...…

查看全部问答>

[请教]和某位哥们一样,请教在C8051F上存储消息

应用情况是这样: 1. 每一个数据大概100Byte 需要在T秒(固定值)存储大概500条数据,只需要一次即可 2. 数据之间有一定的规律,但是大部分数据内部是不同的 我对C8051F单片机的理解: 1. 外扩内存是可以的,C8051F均有复用和非复用的EMIF接口, ...…

查看全部问答>

问个问题 银行叫号机的控制核心是什么?

请问,银行叫号机的控制核心是什么? 操作系统是什么? 借地方求教一下…

查看全部问答>

使用PB创建ATM平台

要使用PB创建ATM平台,我自己是刚接触PB,不知道该添加哪些组件; 哪位大虾指点一下哈? 谢谢!!!…

查看全部问答>

vxworks下怎么开发ISP1760(作为USB主机端控制器)的USB驱动程序

    isp1760通过io与CPU连接,vxworks下的USB host驱动是针对PCI设备的,请问怎么修改vxworks的USB host驱动,使其能使用ISP1760     谢谢!!…

查看全部问答>

谁装了ce6.0 r3,麻烦传个文件给我。。。

WINCE600\\PUBLIC\\IE\\OAK\\IESAMPLE_EXR\\UI\\iesample_exr.rc 这个文件被我误改了导致现在编译ie_exr过不去了,谁传给我,谢谢…

查看全部问答>

请教等效阻抗

在网上下载的电路相关学习资料,学习到电路短路判断这一块时。遇到等效阻抗这一概念。根据学习资料上给出的电阻值,其等效阻抗=并联电路的电阻值。但是我看电路图上给出的量电阻的位置处于一条直线上,很矛盾。所以发帖请教各位老师。希望能得到等 ...…

查看全部问答>