STM32学习之路-LCD(4)<显示字符>

昨晚疯狂的打了一夜的LOL,感觉L多了,今天一天精神萎靡.还是继续把显示字符给看了,可是在犹豫要不要写这篇文章

事实上写的东西也就是copy别人家的代码,不想写那么多,就记录下自己困惑的地方吧.也许改天回来看的时候能让自己高速的明确

也也许能帮助到有些朋友..

看了奋斗给的样例和偷偷去下了正点原子的样例,事实上都是差点儿相同的,仅仅要略微改下都能够通用的,原理就在那里,跑不了.

奋斗给的样例,都是人家的

void lcd_wr_zf(u16 StartX, u16 StartY, u16 X, u16 Y, u16 Color, u8 Dir, u8 *chr)
{	unsigned int temp=0,num,R_dis_mem=0,Size=0,x=0,y=0,i=0;

	if(Dir==2) LCD_WR_CMD(0x0003,0x1010);   //图像显示方向为右下起  行递减  列递增  AM=0  I/D[1:0]=00	<--
	else if(Dir==3) LCD_WR_CMD(0x0003,0x1028);   //图像显示方向为右上起  行递减  列递增  AM=1  I/D[1:0]=10	V
  	if(Dir==0){
		LCD_WR_CMD(0x0003,0x1030);		  //图像显示方向为左上起  行递增  列递增  AM=0  I/D[1:0]=11  -->
		LCD_WR_CMD(0x0210, StartX); 	  //水平显示区起始地址 0-239
  	LCD_WR_CMD(0x0211, StartX+X-1);   //水平显示区结束地址 0-239
  	LCD_WR_CMD(0x0212, StartY);       //垂直显示区起始地址 0-399
  	LCD_WR_CMD(0x0213, StartY+Y-1);   //垂直显示区结束地址 0-399
		LCD_WR_CMD(0x0200, StartX);		  //水平显示区地址
  	LCD_WR_CMD(0x0201, StartY);		  //垂直显示区地址
		LCD_WR_REG(0x0202);               //准备写数据显示区
		Size=X*Y;						  //字符串或字符占用的像素尺寸
		while(i<Size){
			temp=*chr++;				  //一个字节代表8个像素,因此加1代表索引到下8个像素
			for(num=0; num<8; num++){	  //数组的每一个字节代表了8个像素
				if((temp&0x80)>0){		  //对字节的各位进行推断,为1的用带入參数的16位颜色值标示,写入到像素位置。						 

					LCD_WR_Data(Color);
				}
				else{
					LCD_WR_CMD(0x0200, StartX+x);		//水平显示区地址
  				LCD_WR_CMD(0x0201, StartY+y);		//垂直显示区地址
					LCD_WR_REG(0x0202);					//准备读数据显示区
					R_dis_mem=LCD_RD_data();		  	//读取背景色,为叠加产生透明效果作准备
					LCD_WR_Data(R_dis_mem); 		//对字节的各位进行推断。为0的用当前背景像素16位颜色值标示。
				}
				temp=temp<<1; 		  				//字节各位的移出
				x++;
				if(x>=X){x=0; y++;}				    //计算像素递增为当前的x和y,为当前像素读背景颜色做准备
				i++;
			}				  

		}
	}
	else if(Dir==1){
		LCD_WR_CMD(0x0003,0x1018);   	  		//图像显示方向为左下起  行递增  列递减  AM=1  I/D[1:0]=01	A
		LCD_WR_CMD(0x0210, StartY); 	  		//水平显示区起始地址 0-239
  	LCD_WR_CMD(0x0211, StartY+Y-1);    		//水平显示区结束地址 0-239
  	LCD_WR_CMD(0x0212, 399-(StartX+X-1));   //垂直显示区起始地址 0-399
  	LCD_WR_CMD(0x0213, 399-StartX);    		//垂直显示区结束地址 0-399
		LCD_WR_CMD(0x0200, StartY);		  	  	//水平显示区地址
  	LCD_WR_CMD(0x0201, 399-StartX);	 	  	//垂直显示区地址
		LCD_WR_REG(0x0202);                   	//准备写数据显示区

		Size=X*Y;						  		//字符串或字符占用的像素尺寸
		while(i<Size){
			temp=*chr++;				  		//一个字节代表8个像素,因此加1代表索引到下8个像素
			for(num=0; num<8; num++){	  		//数组的每一个字节代表了8个像素
				if((temp&0x80)>0){		  		//对字节的各位进行推断。为1的用带入參数的16位颜色值标示。写入到像素位置。						 

					LCD_WR_Data(Color);
				}
				else{
					LCD_WR_CMD(0x0200, StartY+y);		//水平显示区地址
  					LCD_WR_CMD(0x0201, 399-(StartX+x));	//垂直显示区地址
					LCD_WR_REG(0x0202);					//准备读数据显示区
					R_dis_mem=LCD_RD_data();		  	//读取背景色。为叠加产生透明效果作准备
					LCD_WR_Data(R_dis_mem); 		//对字节的各位进行推断,为0的用当前背景像素16位颜色值标示。
				}
				temp=temp<<1; 		  				//字节各位的移出
				x++;
				if(x>=X){x=0; y++;}				    //计算像素递增为当前的x和y,为当前像素读背景颜色做准备
				i++;
			}
		}
	}
}

程序没难么难理解的地方。慢慢看也就能懂了. 仅仅是感觉奋斗给的样例不够模块化,搞得一个函数要写这么行,事实上是能够分成几部分功能函数来实现的...

当然奋斗这个样例中的字符数组是直接用取模工具取得的,这种做是能够显示汉字,而经常使用的字符、数字、符号有个ASCII字符表,这里就截一部分图给看吧

这表百度一下都有的.

(仅仅是部分图)

大小16x8的

上面两幅图代表了两种表,都差点儿相同,就是大小不一样而已..

这里须要我们注意的是偏移量,上面是偏移量,按我自己的理解是一个字符真正開始的地方距离数组开头的长度,这里是32,为什么是32?

第0~32号及第127号(共34个)是控制字符或通讯专用字符,如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BEL(振铃)等;通讯专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;第33~126号(共94个)是字符,当中第48~57号为0~9十个阿拉伯数字;65~90号为26个大写英文字母。97~122号为26个小写英文字母,其余为一些标点符号、运算符号等

我没去下原始的ASCII表来看,但上面正点原子给的代码里的表应该是把前32个字符去掉了的..

所以正点原子给的代码中就有了num = num - ’ ‘这一行必须的代码,要不然就会出现乱码

void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
#ifdef USE_HORIZONTAL
#define MAX_CHAR_POSX 312
#define MAX_CHAR_POSY 232
#else
#define MAX_CHAR_POSX 232
#define MAX_CHAR_POSY 312
#endif
    u8 temp;
    u8 pos,t;
	u16 x0=x;
	u16 colortemp=POINT_COLOR;
    if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;
	//设置窗体
	num=num-' ';//得到偏移后的值
	if(!mode) //非叠加方式
	{
		for(pos=0;pos<size;pos++)
		{
			if(size==12)temp=asc2_1206[num][pos];//调用1206字体
			else temp=asc2_1608[num][pos];		 //调用1608字体
			for(t=0;t<size/2;t++)
		    {
		        if(temp&0x01)POINT_COLOR=colortemp;
				else POINT_COLOR=BACK_COLOR;
				LCD_DrawPoint(x,y);
				temp>>=1;
				x++;
		    }
			x=x0;
			y++;
		}
	}else//叠加方式
	{
		for(pos=0;pos<size;pos++)
		{
			if(size==12)temp=asc2_1206[num][pos];//调用1206字体
			else temp=asc2_1608[num][pos];		 //调用1608字体
			for(t=0;t<size/2;t++)
		    {
		        if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//画一个点
		        temp>>=1;
		    }
		}
	}
	POINT_COLOR=colortemp;
} 

測试:LCD_ShowString(30,50,"Mini STM32 ^_^");

好了~ LCD篇差点儿相同也要学完了, 就剩下FSMC的一些问题了.

时间: 2024-10-13 22:23:55

STM32学习之路-LCD(4)&lt;显示字符&gt;的相关文章

STM32学习之路-LCD(3)&lt;显示图片&gt;

祝大家端午和六一快乐!原本今天是想休息休息的,但是实在无奈没什么事干.所以就来学习学习LCD显示图片的函数 函数是照搬奋斗的例子,算是些笔记吧.不过奋斗的例子注释的不是很详细.今天去看了正点原子的论坛,唉..瞬间感觉正点原子做得真的很好 能把所有的资料都开源,并且论坛上大多问题都耐心的解答了.这实在是非常非常好的售后服务了!!自己也偷偷的去下了写资料来看看,(*^__^*) 嘻嘻-- 好,进入主题: 开发板:奋斗V5 LCD:3寸 400X240 直接上代码吧 void lcd_DrawPict

STM32学习之路-LCD(2)&lt;LCD初始化&gt;

这些天一直在研究LCD的初始化函数,因为不过是用IO口模拟时序还是用FSMC来驱动LCD,都必须要弄好LCD的初始化 其实LCD的初始化就是跟着LCD IC的datasheet来写寄存器,大部分都使用上面的默认值,网上有很多修改的例子,这里就不 放出来了.但是我想写下一些比较重要的东西. 这是从网上下载来的一个文件的前半部分: 当然,别的型号的IC也是有这些东西的,不过可能有些地址不同而已. R0,这个命令有两个功能,如果对它写,则最低位为OSC,用于开启和关闭振荡器.而如果对它读操作, 则返回

STM32学习之路-LCD驱动(1)&lt;基础知识&gt;

[1]以下关于 JVM 的叙述,哪些项正确? A.JVM 运行于操作系统之上,它依赖于操作系统 B.JVM 运行于操作系统之上,它与操作系统无关 C.JVM 支持 Java 程序运行,它能够直接运行 Java 字节码文件 D.JVM 支持 Java 程序运行,它能够直接运行 Java 源代码文件 扩展名为.java的是源代码文件(文本文件):开发时编写代码的文件 扩展名为.class的是字节码文件(二进制):系统运行时执行的文件 [2]下列选项中正确的表达式是: A.byte b = 128; 

STM32学习之路-外部中断(2)

OK,继续上篇的内容. 配置好外部中断源以后, 就得使能外部中断线了. 为了方便看再借下这个图: 对外部中断的使能其实就是配置上面这些寄存器.即使能哪EXIT线,选择上面模式,是中断还是事件,选择下降沿还是上升沿. 具体怎么写寄存器这就不研究了, = = 太麻烦了.. 直接用STM32的库就行了,来看看它的代码吧 这是EXTI结构体的初始化函数, void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) { EXTI_InitStruct->

STM32学习之路-按键中断测试(外部中断)

终于有时间再来学习STM32了~ 这几天都在忙着该死的考试.直接进入正题 开发板:奋斗V5 这个按键中断测试的要求是:按键2(K2)按下,LED2(V7)亮, 再一次按下就灭,循环.. 好,先看看按键和LED的原理图 好吧~ 虽然图截得不是很好看,但是能看到K2接的是PC2, LED2接的是PD6 ok,剩下的就是配置工作了.. 先来理一理思路: (1)初始化系统时钟 (2)初始化外部时钟(你所用到的东西) (3)配置LED (4)配置中断优先级 (5)配置外部中断线 (6)中断处理函数 恩,差

STM32学习之路-不得不说的SysTick时钟

SysTick时钟,俗称"嘀嗒定时器",这家伙能按固定的时间产生一次中断,通常是多长时间产生一次中断呢?官方给出的一个时间是1ms 那么,它是怎么准确的产生1ms的呢.. 先来看看这家伙在时钟树的哪里吧 是它,是它,就是它,红色框里的东东,可以看到,它是由HCLK/8得到的,也就是:72MHz/8=9MHz 我们还能在STM32手册上找到这么一句话:系统嘀嗒校准值固定位9000,当系统嘀嗒时钟设为9MHz,产生1ms时间基准. 让我们来看看9000是怎么来的,这里要看下SysTick寄

STM32学习之路-外部中断(1)

今天起得比较晚,又浪费了点时间,真可耻.. 下午又为校赛出了俩题,至此,校赛的四道题目已经完毕.又检查了一番,没有错误,就等待着明天的汇总了~. AC自动机的题目今天就刷了三道,还是没有完成之前的目标.现在vj也进不去了,想通宵,都不给机会~~ 只能等明天再刷完了,拖延不是一个好习惯. ----------------------------------------------------------------------------------------------------------

STM32学习之路-中断优先级&lt;NIVC(2)&gt;

优先级的问题可以分为以下情况: 抢占优先级和响应优先级 (1)抢占优先级高的可以打断抢占优先级低的,形成嵌套. (2)抢占优先级相同时,看响应优先级.如果两个中断前后发生的话,后来的中断不能打断前一个中断 只能等,如果两个中断同时发生的话,则响应优先级高的先响应. (3)抢占级别和响应级别都一样时,按照中断的地址来响应,地址低的先响应 这样就解决了优先级的问题. 哪个级别高呢?  0>1>2>...... STM32共有5组分别是0-4组,还是借那个图 可以看到第4组所有的位都用来设置抢

STM32学习之路-点亮LED

STM32学习笔记—点亮led灯 STM32的I/O口有很多的功能,所以称为GPIO(GENERAL PURPOSE) 其中GPIO又分为A,B,C,D,E,F,G不同的组,每个组端口又分为0~15,共16个不同的引脚,不同的芯片引脚数量也不同,所用的学习板为STM32F103RBT6; I/O口的八种模式: 输入浮空:                  模拟输入: 输入上拉:                  输入下拉: 开漏输出:                  推挽输出: 推挽式复用功能