⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text.c

📁 基于stm32的MP3播放器
💻 C
字号:
#include "TXT.H"
//电子书操作函数
//还没有加入向前翻页的操作,等搞完毕业论文再弄了。。。															    																					   
//正点原子@SCUT
//V1.2

//字体大小选择
u8 FSIZE=FONTSIZE16;//汉字大小,默认为16*16的	  
u32 FONT16CLUSTER=0;//16字体的首簇
u32 FONT12CLUSTER=0;//12字体的首簇
					 	                
//Cluster 簇的序号 返回为该簇号所对应的扇区地址
//得到Cluster
unsigned long GetSysFileSector(u8 uoh,unsigned int Cluster)
{
	unsigned long foffset=0;
	unsigned int i; 
	
	if(uoh==16)foffset=FONT16CLUSTER;//得到unicode码的首簇  
    else if(uoh==12)foffset=FONT12CLUSTER; 
	i=Cluster;
	while(i)
	{
	    //printf("foffset:%d\n",foffset);
	    foffset=FAT_NextCluster(foffset);
	    i--;
	}
	//printf("final foffset:%d\n",foffset);
	return fatClustToSect(foffset); 
}                       
//code 字符指针开始
//从字库中查找出字模
//code 字符串的开始地址,ascii码
//mat  数据存放地址 FSIZE*2 bytes大小
void Get_HzMat(unsigned char *code,unsigned char *mat)
{
	unsigned char qh,wh;
	unsigned char i;
	unsigned int  sector,cluster,secoff;
	unsigned long foffset; 
	if(*code<0xa1)if(*code++<0xa1)//非常用汉字
	{   
	    code--;
	    for(i=0;i<(FSIZE*2);i++)*mat++=0xff;//填充满格
	    return; //结束访问
	}          
	qh=(*code++)-0xa1;
	wh=(*code)-0xa1;   
	foffset=((unsigned long)94*qh+wh)*(FSIZE*2);//得到字库中的字节偏移量   
	sector=foffset/BytesPerSector;              //得到总的完整的扇区数(不要写成(unsigned int ) 
 	secoff= (unsigned int) foffset%BytesPerSector;//扇区内的字节数偏移
	wh=(unsigned char)sector%SectorsPerClust; 
	cluster=(unsigned int)sector/SectorsPerClust;//得到总的簇数
	
	foffset=GetSysFileSector(FSIZE,cluster); //取汉字库的clusor簇数的扇区地址 
	 
	if(BytesPerSector-secoff>=(FSIZE*2))//确定是否跨扇区?
	{          
		SD_Read_Bytes(foffset+wh,mat,secoff,(FSIZE*2));  //读取(FSIZE*2)字节
	}else
	{
		i=BytesPerSector-secoff; //读取的数据已跨扇区
		SD_Read_Bytes(foffset+wh,mat,secoff,i);
		if(++wh>SectorsPerClust)
		{  
			wh=0; 
			foffset=GetSysFileSector(0,++cluster);//读取的数据已经跨簇
		} 
		SD_Read_Bytes(foffset+wh,mat+i,0,(FSIZE*2)-i); //读取剩余的数据
	} 
}  
 		 
//显示一个指定大小的汉字
//x,y :汉字的坐标
//font:汉字ASCII码
//mode:0,全填充写入.1,有效部分写入(适合在图片上叠加汉字)
void show_font(u8 x,u16 y,u8 *font,u8 mode)
{
	u8 t1,t2;
	u8 temp=0;
	//扫描方式控制
	TFT_WR_CMD(0,0x00,0x84);	//上至下,左至右 型扫描	  
	//面板大小设置	  开辟1个FSIZE*FSIZE的空间
	TFT_WR_CMD(0,0x02,x);	//设置X坐标点
	TFT_WR_CMD(1,0x03,y);	//设置Y坐标点   
	TFT_WR_CMD(0,0x04,x+FSIZE-1);//结束列数	
	TFT_WR_CMD(1,0x05,y+FSIZE-1);//结束行数 
	TFT_WR_REG(0x0E);//开始写数据GRAM
	if(!mode)//非叠加模式
	{
		for(t1=0;t1<FSIZE;t1++)//共FSIZE个字节,每次读两个
		{
			temp=font[t1];
			for(t2=0;t2<8;t2++)
			{
				if(temp&0x01)TFT_WR_Data16(POINT_COLOR);
				else TFT_WR_Data16(BACK_COLOR);	 
				temp>>=1;
			}
			temp=font[t1+FSIZE];
			for(t2=0;t2<(FSIZE-8);t2++)//这里对16*16和其以下的字体合适
			{
				if(temp&0x01)TFT_WR_Data16(POINT_COLOR);//写入画笔色
				else TFT_WR_Data16(BACK_COLOR);//填充背景色 
				temp>>=1;
			}  
		}
	}else//叠加模式
	{
		for(t1=0;t1<FSIZE;t1++)//共FSIZE个字节,每次读两个
		{
			temp=font[t1];
			for(t2=0;t2<8;t2++)
			{
				if(temp&0x01)TFT_DrawPoint(x+t1,y+t2);//画一个点	 
				temp>>=1;
			}
			temp=font[t1+FSIZE];
			for(t2=0;t2<(FSIZE-8);t2++)//这里对16*16和其以下的字体合适
			{
				if(temp&0x01)TFT_DrawPoint(x+t1,y+t2+8);//画一个点    
				temp>>=1;
			}  
		}
	}
	//恢复原来的设置.
	TFT_WR_CMD(0,0x00,0x04);	//上至下,左至右 型扫描	       						   					     
	TFT_WR_CMD(0,0x04,239);//结束列数	
	TFT_WR_CMD(1,0x05,319);//结束行数  
	   
}
//在指定位置开始显示一个字符串
//非叠加方式显示
//支持自动换行
//(x,y):起始坐标
//str  :字符串
//mode :模式:
//bit 0:1,叠加模式;0,覆盖模式
//bit 1:1,自动换行;0,不自动换行;
void Show_Str(u8 x,u16 y,u8*str,u8 mode)
{												  	  
    u8 bHz=0;         //字符或者中文  	  
	unsigned char *mat; //保存点陈内容				    				  
	mat=jpg_buffer+512;//指向jpg_buffer的后半部分.前半部分用来存放文本文件了.  
    while(*str!=0)//数据未结束
    { 
        if(!bHz)
        {
	        if(*str>0x80)bHz=1;//中文 
	        else             //字符
	        {      
                if(x>(239-FSIZE/2))//换行
				{
					if(mode&0x02)//判断是不是要自动换行?
					{
						y+=FSIZE;
						x=0;
					}else return;
				}
		        if(y>(319-FSIZE))break;//越界返回      
		        if(*str==13)//换行符号
		        {         
		            y+=FSIZE;
					x=0;
		            str++; 
		        }  
		        else TFT_ShowChar(x,y,*str,FSIZE,mode&0x01);//有效部分写入 
				str++; 
		        x+=FSIZE/2; //字符,为全字的一半 
	        }
        }else
        {     
            bHz=0;//有汉字库    
            if(x>(239-FSIZE))//换行
			{
				if(mode&0x02)//判断是不是要自动换行?
				{
					y+=FSIZE;
					x=0;
				}else return;
			}
	        if(y>(319-FSIZE))break;//越界返回  
			Get_HzMat(str,mat);//得到点阵数据 (无字库不起动系统)   
	        show_font(x,y,mat,mode&0x01); //显示这个汉字,空心显示 
	        str+=2; 
	        x+=FSIZE; 			  //下一个汉字偏移
        }						 
    }   
}
//在指定宽度的中间显示字符串
//如果字符长度超过了len,则用Show_Str显示
//len:指定要显示的宽度
//针对1616字体!!!
void Show_Str_Mid(u8 x,u16 y,u8*str,u8 mode,u8 len)
{
	u16 strlenth=0;
   	strlenth=strlen((const char *)str);
	strlenth*=8;
	if(strlenth>len)Show_Str(x,y,str,mode);
	else
	{
		strlenth=(len-strlenth)/2;
	    Show_Str(strlenth+x,y,str,mode);
	}
}
//文本文件读取程序	 
//实现功能:把文件 FileName 打开.在液晶上显示出来 
//打开txt/lrc文件  							 
void Read_Book(FileInfoStruct *FileName)
{     							   
    u16 pointpos=0;   //指针位置   
    unsigned long offlenth=0;//文件读取的大小 
	//unsigned long marklenth=0;//文件上一页的标记位 
    u16 x=0,y=0;
    u8 *p=0;            //指向txt文件
    u8 temp[2]={0,0};   //换扇区使用 
    u8 bHz=0;           //字符或者中文  	  
	unsigned char *mat; //保存点陈内容	
				  
	u8 key;
	u8 enout=0;//能否退出的标志 
			   

	mat=jpg_buffer+512; //指向jpg_buffer的后半部分.前半部分用来存放文本文件了.  
	if((FileName->F_Type&0xF0)==0)return;//不是TXT类型的文件
	F_Open(FileName);//打开文件	 			    			    
    TFT_CLEAR(WHITE);//清屏
	POINT_COLOR=BLUE;//蓝色笔头	    
    while(1)
    {  
		F_Read(FileName,jpg_buffer);//读取数据				    
        p=jpg_buffer;//指向txt数据首地址
        do
        {    
	        while(*p!=0)//数据未结束
	        { 
		        if(!bHz)
		        {
			        if(*p>0x80)bHz=1;//中文字符 
			        else             //ASCII字符
			        {      
                        if(x>(240-FSIZE/2)){y+=FSIZE;x=0;}//一行已满,换行  
				        if(y>(320-FSIZE))break;//越界返回      
				        if(*p==13)//换行符号
				        {         
				            y+=FSIZE;
							x=0;
				            p++;pointpos++;//跳过 
				        }  
				        else TFT_ShowChar(x,y,*p,FSIZE,1); 
						p++;pointpos++; 
				        x+=FSIZE/2; //字符,为全字的一半 
			        }
		        }else
		        {     
		            bHz=0;//清除汉字标志 
		            if(x>(240-FSIZE)){y+=FSIZE;x=0;}//换行
			        if(y>(320-FSIZE))break;//越界返回  
			        //临界处理   
			        if(pointpos==511)//保存上一扇区的最后一个字节,退出        
			        {
			            temp[0]=*p; //记录最后的字节                
			            break;      //此扇区数据已经读完
			        }
			        if(temp[0])//上一次没有显示完
			        {                         
			            temp[1]=*p;//取第二扇区的第一个字节
			            Get_HzMat(temp,mat);//显示上一次的最后一个字 (无字库不起动系统)
			            p++;pointpos++;//偏移一个字节
			            temp[0]=0;     //清除标记
			        }
			        else Get_HzMat(p,mat);//得到点阵数据 (无字库不起动系统)   
			        show_font(x,y,mat,1); //显示这个汉字,空心显示 
			        p+=2;pointpos+=2;     //指针偏移 
			        x+=FSIZE; 			  //下一个汉字偏移
		        }
		        if(pointpos>511)break;
	        }  
            if(pointpos>=511)break;//一个扇区读取完毕,直接跳出,读下一个扇区,防止停顿
            
			Pen_Point.Key_Sta=Key_Up;//释放显示期间的触发 
			enout=0; //退出使能标志不使能
			while(1) //是否显示下一屏数据
            {	    
                if(Pen_Point.Key_Sta==Key_Down||NPEN)key=Touch_Key_Pro(2);//扩展按键扫描
                if(key==MOVE_DOWN||key==MOVE_RIGHT)//向下翻页
                {     
                    if(offlenth+pointpos+1>=FileName->F_Size)return;//文件读取结束(长度结束) 	    
                    if(y>(320-FSIZE)){x=0;y=0;}//非结尾返回,屏幕已满,清屏     
					TFT_CLEAR(WHITE);//清屏
					key=0;//清除此次按键		 
                    break;
                } 
				if(key==MOVE_LEFT)//滑动触摸
				{									   
					enout=1;//使能退出
					printf("前面的数据:\n");
					for(key=0;key<20;key++)printf("%x ",jpg_buffer[key]);
					F_Read(FileName,jpg_buffer);    //读取后512数据
 					printf("后面的数据:\n");
					F_PrevRead(FileName,jpg_buffer);//读取前512数据
					for(key=0;key<20;key++)printf("%x ",jpg_buffer[key]);
					printf(" \n");

					POINT_COLOR=RED;
					TFT_Fill(0,298,239,319,0X81BF);//填充底部颜色
					Show_Str(203,300,"返回",0x01); //叠加模式,非自动换行
					POINT_COLOR=BLUE; 
					key=0;//清除此次按键
				}
				if(enout&&key==CLICK_POINT&&Is_In_Area(200,300,239,319))return;//退出文件阅读...				  					  
                delay_ms(5); 
            }   
        }while(pointpos<511);  
        offlenth+=pointpos+1;//文件长度累加  
        pointpos=0;          //清除指针计数器		  	 
    } 
}  




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -