zl程序教程

您现在的位置是:首页 >  Java

当前栏目

(47)STM32——汉字显示实验(基于正点原子F407)

2023-02-18 16:23:34 时间

目录

学习目标

​编辑

原理

GBK码

生成字库

配置

存字库

显示汉字

代码

总结 


学习目标

        本节我们需要学习的是汉字显示实验,之前一直只能显示英文和数字,我们今天就来显示一下汉字。其实原理和显示字符差不多,只不过引入了一个字库的概念,好了,就让我们开始吧!

原理

        原理和我们的LCD1602是类似的,在此就不再赘述,链接如下。汉字在液晶上的显示其实就是一些点的显示与不显示,这就相当于我们的笔一样,有笔经过的地方就画出来,没经过的地方就不画。所以要显示汉字,我们首先要知道汉字的点阵数据,这些数据可以由专门的软件生成。只要知道了一个汉字点阵的生成方法,那么我们在程序里面可以把这个点阵数据解析成一个汉字。 (2条消息) (十四)51单片机——LCD1602实现滚动效果_花园宝宝小点点的博客-CSDN博客_lcd1602滚动显示

https://blog.csdn.net/weixin_66578482/article/details/126123515

GBK码

        每个GBK码由2个字节组成,第一个字节为0X81~0XFE,第二个自己二分为两部分:0X40~0X7E和0X80~0XFE。         我们把第一个字节代表的意义称为区,GBK里面总共有126个区(0XFE-0X81+1),每个区里面有190个汉字(0XFE-0X80+0X7E-0X40+2),总共就有126×190=23940个汉字。 也就是说:将汉字细分为区,又将区进行排列,然后如果想要获得汉字的点阵数据,就可以先确定汉字所在区、再确定每个汉字所在区里面的顺序。         我们的点阵库只要按照这个编码规则从0X8140开始,逐一建立,每个区的点阵大小为每个汉字所用的字节数×190。这样,我们就可以得到在这个字库里面定位汉字的方法: 当GBKL<0X7F时:Hp=((GBKH-0x81)×190+GBKL-0X40)×(size×2) 当GBKL>0X7F时:Hp=((GBKH-0x81)×190+GBKL-0X41)×(size×2)         其中GBKH、GBKL分别代表GBK的第一个字节和第二个字节,size代表汉字字体的大小(比如16字体、12字体等),Hp则为对应汉字点阵数据在字库里面的起始地址(假设从0开始存放)。

生成字库

        通过点阵字库生成器软件就行,注意我们的字体大小为12就行。

配置

存字库

  1. 做好字库
  2. 将字库GBK12,GBK16,GBK24依次写入SPI FLASH连续地址:update_font();
  3. 字库写入完毕之后,做标记:ftinfo.fontok=0XAA;

显示汉字

调用汉字Show_Str—>Show_Font—>Get_HzMat—>解析显示

代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"  
#include "sram.h"   
#include "malloc.h" 
#include "usmart.h"  
#include "sdio_sdcard.h"    
#include "malloc.h" 
#include "w25qxx.h"    
#include "ff.h"  
#include "exfuns.h"    
#include "fontupd.h"
#include "text.h"	

 
int main(void)
{        
	u32 fontcnt;		  
	u8 i,j;
	u8 fontx[2];//gbk码
	u8 key,t;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);  //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	LED_Init();					//初始化LED  
 	LCD_Init();					//LCD初始化  
 	KEY_Init();					//按键初始化  
	W25QXX_Init();				//初始化W25Q128
	usmart_dev.init(168);		//初始化USMART
	my_mem_init(SRAMIN);		//初始化内部内存池 
	my_mem_init(SRAMCCM);		//初始化CCM内存池 
	exfuns_init();				//为fatfs相关变量申请内存  
  	f_mount(fs[0],"0:",1); 		//挂载SD卡 
 	f_mount(fs[1],"1:",1); 		//挂载FLASH.
	while(font_init()) 			//检查字库
	{
UPD:    
		LCD_Clear(WHITE);		   	//清屏
 		POINT_COLOR=RED;			//设置字体为红色	   	   	  
		LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
		while(SD_Init())			//检测SD卡
		{
			LCD_ShowString(30,70,200,16,16,"SD Card Failed!");
			delay_ms(200);
			LCD_Fill(30,70,200+30,70+16,WHITE);
			delay_ms(200);		    
		}								 						    
		LCD_ShowString(30,70,200,16,16,"SD Card OK");
		LCD_ShowString(30,90,200,16,16,"Font Updating...");
		key=update_font(20,110,16,"0:");//更新字库
		while(key)//更新失败		
		{			 		  
			LCD_ShowString(30,110,200,16,16,"Font Update Failed!");
			delay_ms(200);
			LCD_Fill(20,110,200+20,110+16,WHITE);
			delay_ms(200);		       
		} 		  
		LCD_ShowString(30,110,200,16,16,"Font Update Success!   ");
		delay_ms(1500);	
		LCD_Clear(WHITE);//清屏	       
	}  
	POINT_COLOR=RED;       
	Show_Str(30,50,200,16,"探索者STM32F407开发板",16,0);				    	 
	Show_Str(30,70,200,16,"GBK字库测试程序",16,0);				    	 
	Show_Str(30,90,200,16,"陈怡是憨憨",16,0);				    	 
	Show_Str(30,110,200,16,"2022年10月23日",16,0);
	Show_Str(30,130,200,16,"按KEY0,更新字库",16,0);
 	POINT_COLOR=BLUE;  
	Show_Str(30,150,200,16,"内码高字节:",16,0);				    	 
	Show_Str(30,170,200,16,"内码低字节:",16,0);				    	 
	Show_Str(30,190,200,16,"汉字计数器:",16,0);

	Show_Str(30,220,200,24,"对应汉字为:",24,0); 
	Show_Str(30,244,200,16,"对应汉字(16*16)为:",16,0);			 
	Show_Str(30,260,200,12,"对应汉字(12*12)为:",12,0);			 
	while(1)
	{
		fontcnt=0;
		for(i=0x81;i<0xff;i++)
		{		
			fontx[0]=i;
			LCD_ShowNum(118,150,i,3,16);		//显示内码高字节    
			for(j=0x40;j<0xfe;j++)
			{
				if(j==0x7f)continue;
				fontcnt++;
				LCD_ShowNum(118,170,j,3,16);	//显示内码低字节	 
				LCD_ShowNum(118,190,fontcnt,5,16);//汉字计数显示	 
			 	fontx[1]=j;
				Show_Font(30+132,220,fontx,24,0);	  
				Show_Font(30+144,244,fontx,16,0);	  		 		 
				Show_Font(30+108,260,fontx,12,0);	  		 		 
				t=200;
				while(t--)//延时,同时扫描按键
				{
					delay_ms(1);
					key=KEY_Scan(0);
					if(key==KEY0_PRES)goto UPD;
				}
				LED0=!LED0;
			}   
		}	
	} 
}

总结 

        这次实验比较简单,基本知识在51的时候已经学了,所以理解起来比较方便。