精华内容
下载资源
问答
  • 数码相框_在LCD显示英文字母、汉字点阵显示   主要内容: 写应用程序,使LCD显示汉字和字符   原理: 在SDRAM内存里划出一块空间为FrameBuffer显存,LCD控制器会从FrameBuffer里取出若干节的数据...

    数码相框_在LCD上显示英文字母、汉字的点阵显示

     

    主要内容:

    写应用程序,使LCD显示汉字和字符

     

    原理:

    在SDRAM内存里划出一块空间为FrameBuffer显存,LCD控制器会从FrameBuffer里取出若干节的数据(像素),发给LCD。

     

    ASCII码字库文件使用

    在内核里面应该有英文字母的点阵,在内核中搜索font,找到内核有一个font_8x16.c文件(位于drivers/video/console

    如下图所示,找到8*16的点阵存在fontdata_8x16[]数组里:

    我们以0x41(A)为例子,找到该点阵信息为:

    可以看到一个ASCII代表了16字节,后面我们直接将fontdata_8x16[]数组拷贝到应用程序里,用来显示ASCII

     

     

    HZK16汉字库文件使用

    (1)HZK16描述

    HZK16是按分区表排列的点阵文件,由于每个汉字是2个字节,每个字节的点阵是8*16

    所以HZK16里的每个汉字点阵大小:2*8*16=32字节

    (2)然后还要将编码转为点阵码。

     

     

    LCD设备fb0的file_operations是fb_fops(位于fbmem.c)

    fb_fops的write成员是fb_write()函数

    发现write()函数直接是对显存地址写数据,所以使用echo "hello" > /dev/fb0时会直接出现乱码(没有点阵信息)

    而ioctl成员是do_fb_ioctl()函数,我们需要通过ioctl()获取LCD驱动的数据:

    FBIOGET_VSCREENINFO:获取fb_info-> var成员(可变信息:xy分辨率,像素位数等)

    FBIOGET_FSCREENINFO:获取fb_info-> fix成员(固定信息:缓存地址,每行字节数)

     

     

    mmap

    mamp()函数:申请一段用户空间的内存区域,并映射到内核空间某个内存区域。

    返回值:失败返回-1,并设置errno值.成功,返回映射的地址指针.若指定start则返回0
    start:需要映射的内存起始地址,通常填NULL,表示让系统自动映射,映射成功后返回该地址.

    length:映射地址的大小,填LCD显存字节数即可,因为2440一个地址存8位.

    prot:对映射地址的保护(protect)方式,常用组合如下:

    • PROT_EXEC 映射区域可被执行
    • PROT_READ 映射区域可被读取
    • PROT_WRITE 映射区域可被写入
    • PROT_NONE 映射区域不可访问

    flag:填MAP_SHARED即可,表示共享此映射,对其它进程可见.

    fd:需要将内存映射到哪个文件描述符(以后便可以直接通过内存来直接操作该文件)

    offset:映射偏移值,填0即可.

    mmap的参数详情使用请参考:http://blog.csdn.net/dlutbrucezhang/article/details/9080173

     

     

    代码如下:

    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <linux/fb.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    
    #define FONTDATAMAX 4096
    
    static const unsigned char fontdata_8x16[FONTDATAMAX] = {
    
    	/* 0 0x00 '^@' */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    	0x00, /* 00000000 */
    
    …… …… ……(省略)
    
    };
    
    int fd_fb;
    struct fb_var_screeninfo var;	/* Current var */
    struct fb_fix_screeninfo fix;	/* Current fix */
    int screen_size;
    unsigned char *fbmem; //framebuffer的内存
    unsigned int line_width;//一行多少个字节
    unsigned int pixel_width;//每个像素多少个字节
    
    int fd_hzk16;//汉字库16
    struct stat hzk_stat;//HZK16文件的统计信息
    unsigned char *hzkmem; //汉字库的内存
    
    //屏幕上显示一个字符,color:0x00RRGGBB
    void lcd_put_pixel(int x, int y, unsigned int color)
    {
    	//y:有多少行,line_width:一行有多少个字节,
    	unsigned char *pen_8 = fbmem + y * line_width + x * pixel_width;
    	unsigned short *pen_16;
    	unsigned int *pen_32;
    
    	unsigned int red, green, blue;
    
    	//不同的像素宽度,用不同的变量来表示
    	pen_16 = (unsigned short *)pen_8;
    	pen_32 = (unsigned int *)pen_8;
    
    	//描点
    	switch (var.bits_per_pixel)
    	{
    		case 8:
    		{
    			*pen_8 = color;
    			break;
    		}
    		case 16://将RGB888 改为RGB565
    		{
    			/* 565 */
    			red    = (color >> 16) & 0xff;
    			green = (color >> 8)  & 0xff;
    			blue   = (color >> 0)  & 0xff;
    			//红颜色取出来8位,保留5位...
    			color = ((red >> 3) << 11) | ((green >>2) << 5) | (blue >> 3);//保留红色的5位,绿色的6位,蓝色的5位
    			*pen_16 = color;
    			break;
    		}
    		case 32:
    		{
    			*pen_32= color;
    			break;
    		}
    		default:
    		{
    			printf("can't surport %dbpp\n", var.bits_per_pixel);
    			break;
    		}
    	}
    }
    
    //显示ascii码
    void lcd_put_ascii(int x, int y, unsigned char c)
    {
    	//点阵dots,C是ASCII,每个ASCII占据16个字节(16行)
    	unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
    	int i, b;
    	unsigned char byte;
    	
    	for (i = 0; i < 16; i++)//每一行
    	{
    		byte = dots[i];//取出一个字节(一行)
    		for(b = 7; b >= 0; b--)//每一列,从高到低
    		{
    			if (byte & (1<<b))
    			{
    				/* show,如果是1, 表示要显示*/
    				lcd_put_pixel(x+7-b, y+i, 0xffffff);//LCD显示像素,白色
    			}
    			else
    			{
    				/* hide,不显示 */
    				lcd_put_pixel(x+7-b, y+i, 0);//LCD显示像素,黑色
    			}
    		}
    	}
    }
    
    //显示汉字GBK
    void lcd_put_chinese(int x, int y, unsigned char *str)
    {
    	//汉字库HZK16文件里面94个汉字,94个汉字,每个汉字16x16=2x8x16=32字节
    	//中:D6 D0,D6:区码,D0:位码,因为从A1开始的
    	unsigned int area    = str[0] - 0xA1;//表示某一块
    	unsigned int where  = str[1] -0xA1;//表示某一块哪一个
    	//每一块有94个字,每个字是32个字节
    	unsigned char *dots  = hzkmem + (area  * 94 + where) * 32;//点阵
    	unsigned char byte;
    	
    	int i, j, b;
    	for (i = 0; i < 16; i++)
    		for(j = 0; j < 2; j++)
    		{
    			//因为byte的类型是char类型(一个字节),取出一个字节的数据
    			byte = dots[i*2 + j];
    			for (b = 7; b >= 0; b--)//每一个像素
    			{
    				if (byte & (1<<b))
    				{
    					/* show,如果是1, 表示要显示*/
    					lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff);//LCD显示像素,白色
    				}
    				else
    				{
    					/* hide,不显示 */
    					lcd_put_pixel(x+j*8+7-b, y+i, 0);//LCD显示像素,黑色
    				}
    			}
    		}
    }
    
    int main(int argc, char **argv)
    {
    	unsigned char str[] = "中";
    
    	fd_fb = open("/dev/fb0", O_RDWR);
    	if (fd_fb < 0)
    	{
    		printf("can't open /dev/fb0\n");
    		return -1;
    	}
    
    	//获得可变的屏幕信息V,X和Y的分辨率,每一个像素用多少位来表示
    	if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
    	{
    		printf("can't get var\n");
    		return -1;
    	}
    
    	//获得固定的屏幕信息F
    	if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))
    	{
    		printf("can't get fix\n");
    		return -1;
    	}
    
    	line_width = var.xres * var.bits_per_pixel /8;//一行有多少个,占据多少字节
    	pixel_width = var.bits_per_pixel /8;//像素占据多少字节
    	screen_size = var.xres * var.yres * var.bits_per_pixel / 8; //每个像素占用多少字节
    	//mmap申请一段用户空间的内存区域,并映射到内核空间某个内存区域
    	fbmem = (unsigned char *)mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);//内存映射,第一个参数为NULL让系统给我们分配,
    	if (fbmem == (unsigned char *)-1)
    	{
    		printf("can't mmap\n");
    		return -1;
    	}
    
    	//汉字初始化,汉字库
    	fd_hzk16 = open("HZK16", O_RDONLY);//当前目录的汉字库16
    	if (fd_hzk16 < 0)
    	{
    		printf("can't open HZK16\n");
    		return -1;
    	}
    	//取HZK16文件的统计信息stat,文件大小st_size
    	if(fstat(fd_hzk16, &hzk_stat))
    	{
    		printf("can't get fstat\n");
    		return -1;
    	}
    	//用一块内存存储汉字库16的数据,像数组一样访问文件
    	hzkmem = (unsigned char *)mmap(NULL, hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);//内存映射,第一个参数为NULL让系统给我们分配,
    	if (hzkmem == (unsigned char *)-1)
    	{
    		printf("can't mmap for hzk16\n");
    		return -1;
    	}
    
    	/* 清屏,全部设为黑色*/
    	memset(fbmem, 0, screen_size);	
    
    	//字母“A” :x方向占据8个像素,y方向占据16个像素
    	//中文“中”:x方向占据16个像素,y方向占据16个像素
    	//屏幕中间显示字母
    	lcd_put_ascii(var.xres/2, var.yres/2, 'A');
    
    	printf("chinese code: %02x %02x\n", str[0], str[1]);//国标码,中,D6 D0
    	lcd_put_chinese(var.xres/2 + 8, var.yres/2, str);
    	
    	return 0;
    }
    
    
    

     

     

    6、编译运行

    编译代码后,然后使内核支持LCD启动

    make menuconfig

     

    进入Device Drivers -> Graphics support -> Support for frame buffer devices 

    <*>   S3C2410 LCD framebuffer support         //编译进内核
    <*>   Silicon Motion SM501 framebuffer support  //编译进内核

     

    并修改linux-3.4.2/drivers/video/Makefile

    #obj-$(CONFIG_FB_S3C2410)         += s3c2410fb.o
    obj-$(CONFIG_FB_S3C2410)          += 9th_lcd.o         //添加以前写的lcd驱动

     

    编译并启动内核后,运行程序:./show_font(结果显示:chinexe code:d6 d0)

    展开全文
  • !本博客是 《LCD1602自定义点阵字符》的学习笔记以及补(chao)充(xie) LCD1602能存8个自定义字符, 首地址分别为0X40,0X...存储和显示都是两步实现 一步write_command()确定地址 第二步write_data()确定操作数 w.

    !本博客是 《LCD1602自定义点阵字符》的学习笔记以及补(chao)充(xie)

    LCD1602能存8个自定义字符, 首地址分别为0X40,0X48,0X50,0X58,0X60,0X68,0X70,0X78;

    也就是说0x40到0x7F都是用来存自定义字符的

    每个字符都是5x7的点阵,以0x40为例
    在这里插入图片描述

    每个地址为一行(按字节寻址),但是每一行只有第五位有效,行也是前五行有效

    存储和显示都是两步实现
    一步write_command()确定地址
    第二步write_data()确定操作数

    write_command()和write_data()都是lcd1602经常写的函数,详见后面代码

    要存储自定义字符需要两步

    1. 向lcd1602发送命令,定位行
    2. 写入每行对应的数据

    比如将十储存到首地址为0x40

    write_command(0x40); // line1
    write_data(0x40);
    write_command(0x40); // line2
    write_data(0x40);
    write_command(0x40); // line3
    write_data(0x40);
    write_command(0x40); // line4
    write_data(0x40);
    write_command(0x40); // line5
    write_data(0x40);
    write_command(0x40); // line6
    write_data(0x40);
    write_command(0x40); // line7
    write_data(0x40);
    

    在这里插入图片描述

    显示自定义字符也是这个步骤

    1. write_command(0x80+[0x40第二行]+第几个字符);
    2. write_data(第几个自定义字符,也可以看ascii码表,前八个是自定义字符);

    在这里插入图片描述
    显示非自定义字符和自定义字符步骤一样

    可以取模软件将自定义字符存到一个数组里面,然后两个函数用于修改和显示自定义字符

    // custom_code is between on 0 and 7
    void ch_custom_char(uchar *char_lattice, uchar custom_code)
    {
      int i;
      for(i=0;i<8;i++)
      {
        write_command(0x40+custom_code*8+i); // set to the i-th line
        write_data(char_lattice[i]); // write a line bit
      }
    }
    
    void display_custom_char(uchar n, uchar custom_code)
    {
      write_command(0x80+n); // set to the n-th char
      write_data(custom_code); // display the custom_code char
    }
    

    还可以将显示字符串的函数完善一下,将自定义字符串也自动识别显示。
    我就懒得实现了。
    下面是一个算是完整能用的代码

    /* Main.c file generated by New Project wizard
     *
     * Created:   周四 5月 27 2021
     * Processor: 80C31
     * Compiler:  Keil for 8051
     */
    
    #include <reg51.h>
    #include<intrins.h>
    #define DATA_BUS  (P0) 
    // Define P3 pins
    sbit RS = P2^0;
    sbit RW=P2^1;
    sbit E=P2^2;
    // Define new types
    typedef unsigned char   uchar;
    typedef unsigned int    uint;
    
    // Function Prototypes
    void check_busy(void);
    void LCD_init(void);
    void write_command(uchar com);
    void string(uchar ad ,uchar *s);
    void lcd_test(void);
    void delay(uint);
    void write_data(uchar _data);
    void ch_custom_char(uchar *char_lattice, uchar custom_code);
    void display_custom_char(uchar n, uchar custom_code);
    uchar lu[] = {0x00,0x01,0x01,0x05,0x01,0x07,0x00};/*"业",2*/
    uchar ye2[] = {0x00,0x30,0x34,0xB4,0x28,0xFC,0x00};/*"业",2*/
    
    void main(void)
    {
      LCD_init(); 
      while(1)
      { //string(0x80,"1900301517!");
        //string(0xC0,"  LuHongye");
        ch_custom_char(lu,1);
        display_custom_char(0,0);
    	ch_custom_char(ye2,2);
        display_custom_char(1,2);
    
        delay(100); 
        write_command(0x01);
        delay(100);       
      }
     }
    
    /*******************************************
        LCD1602 Driver mapped as IO peripheral
    *******************************************/  
    // Delay
    void delay(uint j)
    { 
      uchar i = 60;
      for(; j>0; j--)
      {
        while(--i);
        i = 59;
        while(--i);
          i = 60;
      }
    }
    
    // Test the Busy bit
    void check_busy(void)
    { 
      do
      {
         DATA_BUS = 0xff;
         E = 0;
         RS = 0; 
         RW = 1;
         E = 1;
         _nop_();
      } while(DATA_BUS & 0x80);
      E = 0;
     }
    
    // Write a command
    void write_command(uchar com)
    { 
      check_busy();
      E = 0;
      RS = 0;
      RW = 0;
      DATA_BUS = com;
      E = 1;
      _nop_();
      E = 0;
      delay(1);
    }
    
    // Write Data
    void write_data(uchar _data)
    {
      check_busy();
      E = 0;
      RS = 1;
      RW = 0;
      DATA_BUS = _data;
      E = 1;
      _nop_();
      E = 0;
      delay(1);   
    }
    
    // Initialize LCD controller
    void LCD_init(void)
    {
      write_command(0x38); // 8-bits, 2 lines, 7x5 dots
      write_command(0x0C); // no cursor, no blink, enable display
      write_command(0x06); // auto-increment on
      write_command(0x01); // clear screen
      delay(1);
    }
    
    // Display a string
    void string(uchar ad, uchar *s)
    {
      write_command(ad);
      while(*s>0)
      {
        write_data(*s++);
        delay(100);
      }
    }
    // custom_code is between on 0 and 7
    void ch_custom_char(uchar *char_lattice, uchar custom_code)
    {
      int i;
      for(i=0;i<8;i++)
      {
        write_command(0x40+custom_code*8+i); // set to the i-th line
        write_data(char_lattice[i]); // write a line bit
      }
    }
    
    void display_custom_char(uchar n, uchar custom_code)
    {
      write_command(0x80+n); // set to the n-th char
      write_data(custom_code); // display the custom_code char
    }
    

    参考博客:《LCD1602自定义点阵字符》

    展开全文
  • 点阵LCD显示原理在数字电路中,所有的数据都是以01保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。而对于中文,常用却有6000...
  • 8x8LED点阵屏汉字滚动显示。有proteus仿真,C语言程序源代码。可以显示汉字,并且能实现简单的上、下、左、右四种显示方式。
  • 51单片机教程:8*8 点阵显示字符、数字、简单汉字

    万次阅读 多人点赞 2020-05-24 12:38:50
    点阵显示实验 一、什么是点阵? 我们用之前的方法一个IO口只能控制一个led,如果需要用更少的IO口控制更多的led怎么办呢,于是就有了点阵。 8X8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线列线的...

    点阵显示实验

    一、什么是点阵?
    我们用之前的方法一个IO口只能控制一个led,如果需要用更少的IO口控制更多的led怎么办呢,于是就有了点阵。
    8X8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮;如要将第一个点点亮,则1脚接高电平a脚接低电平,则第一个点就亮了;

    二、点阵原理图
    可以看到点阵是由led按照一定的排列组成
    在这里插入图片描述
    实物图:
    在这里插入图片描述
    我们可以打开protues,用led模仿一下点阵结构,了解一下原理
    在这里插入图片描述
    三、测试点阵
    1、 proteus里点阵是MATRIX,选择8*8就行了
    发现没有引脚标识,只能自己测试一下了、
    先接一个电源试一下
    (一定要自己测一下,proteus仿真布置的点阵每次方向都可能发生改变)
    在这里插入图片描述
    它不亮,说明下面的一排是正极,反接一下,可以看到第一个led已经亮了。
    在这里插入图片描述
    正极多接几个线试试,发现上面的是控制列,下面是控制行
    在这里插入图片描述
    画原理图,标记一下点阵的极性。方便写下代码
    在这里插入图片描述
    首先我们要知道点阵的显示原理,这个很重要
    1、点阵是扫描显示,也就是同一时刻只有一列或者一行有led显示
    2、视觉暂留效果,当扫描足够快的时候,人眼是看不到闪烁的
    3、点阵可以横向扫描,也可以纵向扫描

    图形显示:
    比如要显示 : ‘F’ ,以横向扫描为例,从上到下显示

    在这里插入图片描述
    1、显示第一行

    在这里插入图片描述
    2、显示第二行

    在这里插入图片描述
    3、显示第三行

    在这里插入图片描述
    4、显示第4行

    在这里插入图片描述
    5、显示第五行
    在这里插入图片描述
    这样把8行显示完就可以显示整个图形。

    四、取模软件
    上面的 ‘F’,利用取模软件生成数组,对于复杂的图形显示就方便的多,这里我使用的lcd图形生成,百度就能下载到,也可以点这个下载链接 取模软件合集.rar,可以下载取模软件合集(4个常用取模软件),解决任何取模难题。
    在这里插入图片描述
    这里取模设置横向取模,字节倒序,根据不同的电路要做不同设置,不然可能出现图形镜像或者反白等现象
    在这里插入图片描述
    五、编写程序
    1、显示字符

    #include <regx51.h>
    
    unsigned int wei[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; 		//扫描8位
    unsigned int duan[8] = {//用软件生成的
    /*--  调入了一幅图像宽度x高度=8x8:F --*/
    0x3E,0x02,0x02,0x3E,0x02,0x02,0x02,0x02,
    };
    
    void delayms(unsigned int m)   // 延时子程序
    {
     	int i,j;
    	for(i=0; i<m; i++)
    		for(j=0; j<120; j++);
    }
      
    void main(void)
    {	
    	int i;																		
    	while(1)
    	{
    		for(i=0; i<8; i++)	   //扫描8行数据
    		{
    			P2 = wei[i];		 //先发送位码
    			P3 = duan[i];	  //再发送断码
    			delayms(2);
    		}
    	}
    }

    代码效果
    在这里插入图片描述
    2、显示数字

    在这里插入图片描述

    #include <regx51.h>
    
    unsigned int wei[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; 		//扫描8位
    unsigned int duan[8] = {
    /*--  调入了一幅图像宽度x高度=8x8  : 1 --*/
    0x00,0x08,0x0C,0x08,0x08,0x08,0x08,0x1C,
    };
    
    void delayms(unsigned int m)   // 延时子程序
    {
     	int i,j;
    	for(i=0; i<m; i++)
    		for(j=0; j<120; j++);
    }
      
    void main(void)
    {	
    	int i;																		
    	while(1)
    	{
    		for(i=0; i<8; i++)	    //扫描8行数据
    		{
    			P2 = wei[i];		 //先发送位码
    			P3 = duan[i];	  //再发送断码
    			delayms(2);
    		}
    	}
    }

    代码效果:
    在这里插入图片描述
    3、显示简单汉字(标准汉字需要16*16点阵)
    在这里插入图片描述

    #include <regx51.h>
    
    unsigned int wei[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; 		//扫描8位
    unsigned int duan[8] = {
    /*--  调入了一幅图像宽度x高度=8x8  : 大 --*/
    0x00,0x08,0x7F,0x08,0x14,0x22,0x41,0x00,
    };
    
    void delayms(unsigned int m)   // 延时子程序
    {
     	int i,j;
    	for(i=0; i<m; i++)
    		for(j=0; j<120; j++);
    }
      
    void main(void)
    {	
    	int i;																		
    	while(1)
    	{
    		for(i=0; i<8; i++)	   //扫描8行数据
    		{
    			P2 = wei[i];		 //先发送位码
    			P3 = duan[i];	  //再发送断码
    			delayms(2);
    		}
    	}
    }

    代码效果:
    在这里插入图片描述
    下一篇:51单片机教程:51单片机驱动四个88点阵,拼凑1616点阵显示标准汉字

    展开全文
  • 代码随笔——点阵汉字LCD上的显示 注:本文约在半年到一年前写的。 其实我以前从没想过写Framebuffer的代码,网上流传较多的是LCD的移植(主要改参数),之后没下文了。不过,曾经兴致冲冲地想搞Qtopia移植,在...

    代码随笔——点阵汉字在LCD上的显示

    注:本文约在半年到一年前写的。

    其实我以前从没想过写Framebuffer的代码,网上流传较多的是LCD的移植(主要改参数),之后没下文了。不过,曾经兴致冲冲地想搞Qtopia移植,在这过程中碰到过一个叫Tslib的东西。后来Qtopia没搞成功,倒研究起Tslib来了——对它的底层原理还没看明白,对于一些代码技巧及代码结构组织还是研究了一点。这个过程,与前几个月研究u-boot,一年前研究rtp以及曾经研究过的enc28j60等等代码很是相似。我这个有个毛病,喜欢研究些小东西,一些有意思的东西。比如说,人家移植u-boot,就是移植到开发板上,出结果就行了,而我,会去看看那些内存地址啊,看看里面的代码啊什么的。——不务正业,从这里可见一斑。

     

    Tslib研究了一点点后,又对多通道的ADC感兴趣。经过查资料,发现网上也有很多人问怎么实现多通道采集数据,而且有些资料出奇的一致,都是转来转去的。我移植ADC驱动时是完全照抄别人的文章的,一般说来,ADC的移植跟TS的驱动差不多要一起搞,需要的文件有三个,其中一个是头文件,后来我才知道,那个头文件是“历史遗留”的,因此在2.4版本的内核中,ADC的驱动包括了read接口以及write接口,write函数就用到那个头文件的几个宏,里面的write接口正是多通道控制的关键——我们可以通过应用程序中调用write来指定哪一个通道,而这个应用程序也需要用到那个头文件的宏。但不知道怎么搞的,后来就把write给去掉了,而保留了头文件。或许有人觉得无需这样做。

    当时我就一心地写个多通道的代码出来。于是搞了两种版本,一个是使用“正宗”的接口:ioctl——这个接口更名副其实一点,另一个是write接口。经过曾经,两种版本都是可行的。但是,由于内核版本变化实在太快,很多接口函数和宏定义都发生变化,因此有人问我怎么不能编译通过,怎么不能XXX,这些问题我也不知道,因为内核不是我开发的,我也没深入研究过驱动。另外,我最怕别人动不动就问人,连最基本的自学技能(若干年后,我们大家都会知道,无论在大学还是工作,自学才是王道)都不知道。我高中时候英语很好,经常有人问我单词,我都劝他们先查字典,字典的解释是最权威的,但很多人不听。因为有个大活人在,方便快速。到大学后期,我慢慢地不想说什么的,都以“不知道”为由,拒绝很多问题。假如直接给别人源代码,别人会问你程序是怎么运行的,里面代码是什么意思,老师问到该怎么回答,怎么改进这些东西,等等。其实我挺喜欢帮助别人的,别人的一句“谢谢”就能满足我的虚荣心。

     

    后来,不知道怎么搞的,实然想在屏幕上显示汉字。于是乎,又去研究字库文件,研究别人的代码。我这个人比较笨,有些东西要慢慢地理解。比如说在屏幕上显示一个点阵汉字,我就从字库中找一个汉字,将那些十六进制数据一一改成二进制,再理解。当看到那些“1”组成了一个熟悉的汉字时,心情是非常激动的。当然,在研究区号、位号及汉字分布时,脑海中那些十六进制的知识又被复习了一遍。一开始是在Linux终端下使用printf打印的,但只能竖着打印,不能横着打印。我甚至想过要定位出坐标来,但是普通的C语言没这功能。后来某一天早上,实然看到自己买的一本关于ncurses编程的书,顿时大悟,何不用这个库来显示?这个库我很早就有耳闻了,只是现在应用场合不多(但在终端上,它具体非常强的优势),没去了解。后来一切似乎很顺利,显示完16点阵,再研究24点阵显示,研究完汉字显示,再研究中英混合显示,等等,似乎都很成功。当然前面所有这些都是在PC上模拟的,还没有真正在触摸屏上实现显示。不过,正是有了前面的基本知识,将那些东西搞到触摸屏上很简单。这个过程便是传说中的“移植”了,我只是简单修改了一下打印的函数。在PC上,可以用printf,可以用mwprintf,在LCD上就用画像素的函数。不过,有一个致命缺点:没有脱离Tslib的环境,而且就在ts_test.c文件中添加,因为我还没研究过auto tool(我已经下载了英文教程,还没看)。另外,对于Tslib画像素的流程还不了解。当然,经过自己的努力,最终还是能脱离了Tslib,形成自己独立的库文件。

     

    这个过程也在不断修改自己的代码,由于自己对代码的优化研究不深,因此谈不上速度的优化,只是在代码组织上作了调整。不过我还是对比了一下移位和乘除的差别。另外,将英文字符存放在数组中,汉字则采用字库文件。其实我很早就注意代码的组织了,用现在很流行的话,就是很注意代码的复用、重构。这些习惯使得有些函数不用修改,直接能使用。

     

    当显示出汉字时,觉得自己似乎也很成功,其时也不时注意周边的汉字字体,甚至还留意移动门口上方的点阵屏和公车的点阵屏。不过它们都是移动的,而我的是静止的。于是乎,又在想怎么让屏幕上的字也能移动。同样地,我也是先在PC上使用ncurses库来测试。在PC上测试没什么问题,可是到了屏幕上,就出现问题了:原来位置的像素还在,这样,汉字移动时,就看不清是什么字了。原来,我并没有清除屏幕。屏幕原来有什么,依然还有什么。到后来,找到一个ripple小项目,里面有与framebuffer相关操作的代码,于是就借鉴里面的代码(后来的代码都是在它的基础上修改添加的)。这才实现了清屏功能,或曰“刷新”。其它刷新很简单,就是将framebuffer所映射的某个内存(块)写0。在RGB中,全0是黑色。全F是白色。ripple项目原来的清屏函数是清除整个屏幕,后面我改进了一下,可以在指定行、列清除指定大小的屏幕。

    展开全文
  • 点阵LCD显示原理

    万次阅读 2014-11-18 19:29:27
    点阵LCD显示原理  在数字电路中,所有的数据都是以01保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。而对于中文,常用却...
  • ASCII字符点阵和汉字点阵显示

    万次阅读 2018-03-28 10:54:08
    字符编码方式有ASCII,GBK...标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符。  GBK码用两个字节表示一个汉字。  Un...
  •  在数字电路中,所有的数据都是以01保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。而对于中文,常用却有6000以上,于是我们的...
  • 本系统主要由三部分组成,分别为单片机,LCD模块FLASH字库,图1所示是该系统的硬件原理框图,由于显示所需要占用的资源过多(本设计采用的是16×16点阵,每个汉字存储需要32个字节),而单片机内部RAM资源及其有限
  • #include "lcd.h" #include "delay.h" static u8 INITIAL_COLUNM=0; void LCD_FUNCTION_Config(void) { GPIO_InitTypeDef LCD_Struct; RCC_APB2PeriphClockCmd(LCD12864_Periph,ENABLE); LCD_Struct.GPIO_...
  • LCD1602显示中文汉字

    万次阅读 多人点赞 2016-05-03 09:47:17
    小子在西藏 2011-11-25编写 ...LCD1602显示中文汉字     LCD1602相比大家都比较了解,但是我们一般只用来显示字符,数字。 最近在网上看许多人用LCD1602来显示汉字,觉得有趣 于是拜读了一些资料,教程
  • 理解OLED屏显和汉字点阵编码原理,使用STM32F103的SPI或IIC接口实现以下功能: 显示自己的学号姓名; 显示AHT20的温度湿度; 上下或左右的滑动显示长字符,比如“Hello,欢迎来到重庆交通大学物联网205实训室!...
  • 点阵显示原理 在数字电路中,所有的数据都是以01保存的,对控制器进行不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。而对于中文,常用却有6000以上,...
  • LCD屏汉字显示镜像且旋转90° LCD显示的底层是参考正点原子的例程,应该是汉字的取模方式原子的不一样吧,所以字符串都显示正常,汉字显示异常。 取模方式先不考虑。想到的原因可能是扫描方向,打点函数等问题,...
  • LCD显示模式

    2021-01-19 20:14:21
    由基本的LCD显示原理可知,LCD显示一个点重要的因素就是点的坐标...其中,段位式LCD和字符式LCD只能用于字符和数字的简单显示,不能满足图形、曲线和汉字显示的要求;而点阵LCD不仅可以显示字符、数字,还可以显示
  • 详解LCD1602液晶显示屏的使用

    万次阅读 多人点赞 2019-10-27 11:50:23
    作为各类单片机实物设计的常用显示屏LCD1602是一种专门用于显示字母、数字、符号等点阵LCD,其1602是指LCD显示的内容为16X2,即可以显示两行,每行16个字符(1个汉字占用2个字符)。 2.硬件参数 (1) LCD1602主要...
  • 由基本的LCD显示原理可知,LCD显示一个点最重要的因素就是点的坐标...其中,段位式LCD和字符式LCD只能用于字符和数字的简单显示,不能满足图形、曲线和汉字显示的要求;而点阵LCD不仅可以显示字符、数字,还可以显示
  • Arduino LCD1602不带IIC,显示汉字过程

    千次阅读 2019-12-15 22:46:39
    Arduino LCD1602不带IIC,显示汉字过程 小白记录一下过程,参考3个网址,感谢原作者。 参考网址: lcd1602显示自定义字符 https://www.arduino.cn/thread-47263-1-1.html LCD1602显示汉字 + 自制字库 ...
  • 一、LCD12864液晶的工作原理 液晶显示屏中的业态光电显示材料,利用液晶的电光效应把电信号转换成数字符、图像...图1-1 12864LCD液晶显示屏 二、方案设计 2.1 实物硬件设计 单片机控制液晶显示屏系统总共可分为六个
  • YM12864R点阵式液晶显示模块具有灵活的接口方式简单的操作指令,构成的全中文人机交互图形界面既可以显示8×4行16×16点阵汉字,也可以显示图形。模块内部设有2MB的中文字型CGROM64×256点阵的GDRAM绘图区域;...
  • LCD通过一个个像素点,要在LCD显示一个字符,需要以下两步: ① 占据屏幕上的一块地方,大小由字体大小说了算; ② 在占据的地方上依次控制每个像素点是否显示。 比如中文字符24×24字体大小表示水平需要24个...
  • LCD12864点阵型液晶显示器介绍

    千次阅读 2020-08-08 11:32:33
    基于51单片机的独立按键单击、双击,长按,多次按的项目工程前言一、LCD12864点阵型液晶显示器介绍二、LCD12864点阵型液晶显示器尺寸图(1)、声明程序变量思维导图(2)、程序子函数思维导图(3)、程序主函数思维...
  • STM32中LCD显示少量汉字

    万次阅读 2017-04-09 19:21:03
    STM32中LCD汉字显示
  • 这些液晶屏都是为显示设备上信息的,每种液晶显示屏都是有差异的,那么段码屏和点阵屏的区别如何呢?今天小编带大家走进LCD液晶屏模块厂家了解。 1、点阵液晶屏是什么意思 点阵液晶屏是按照一定顺序规则排列起来的...
  • 汉字点阵字库文件,正面的很多,可是反向的这类资源不常见
  • main函数 #include <ioCC2530.h> #include "LCD.h" void main() { //unsigned char i=0; LCD_Init(); //oled 初始化 LCD_CLS(); //全亮 LCD_welcome(); while(1) { } } 首先呢。我们
  •  由于点阵式液晶显示模块功耗低、体积小,且可以显示各种字符、汉字以及图形,因而可广泛应用于数字式仪表各种低功耗监测系统中。笔者利用该模块设计的冲击力监测系统能够实时显示冲击力的大小、速度、峰值及平均...
  • 51单片机驱动LCD12864中文字库显示

    千次阅读 2020-09-23 11:29:57
    51单片机驱动LCD12864中文字库显示1.LCD12864介绍2.LCD地址码、字符表、汉字码址表 1.LCD12864介绍 ① 可显示四行字符,每行可显示8个汉字或者16个数字和字母; ②可串行通信并行通信; ③ 串口接口管脚信号 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 920
精华内容 368
关键字:

lcd点阵显示汉字和数字