1.硬件平臺(tái)
2.實(shí)現(xiàn)功能
1.SD卡設(shè)備檢測(cè),文件系統(tǒng)移植,用戶存儲(chǔ)小說和字庫文件;
2.字庫信息加載檢測(cè),自動(dòng)完成字庫信息加載與更新。本次采用GBK字庫,字體大小有16*16、24*24、32*32三個(gè)字庫;
3.觸摸屏校準(zhǔn),上電檢測(cè)觸摸屏校準(zhǔn)信息;手動(dòng)進(jìn)入觸摸屏校準(zhǔn)模式
4.小說文件索引,小說文本切換;
5.小說翻頁,字體大小選擇,顏色選擇,返回主目錄;
3.示例效果
?SD卡檢測(cè)和觸摸屏校準(zhǔn)
?字庫檢測(cè)與更新
目錄和小說顯示界面
顏色切換
字體選擇
4.軟件設(shè)計(jì)
?1.SD卡字庫更新加載
/***********************SD卡字庫更新***********************/
u8 SDcard_DownFont(const TCHAR* path,u32 addr,u16 font_size)
{
FIL fp;
u8 res;
UINT br;
u32 size;
u32 cnt=0;
u16 y=0;
float load=0,load2=0;
u8 buff[1024];
char buff2[20];
/*1.讀取文件大小*/
FILINFO file_info;
f_stat(path,&file_info);
size=file_info.fsize;
if(size==0)return 1;
//printf("文件大小:%u byte\r\n",size);
/*2.打開文件*/
res=f_open(&fp,path,FA_READ);
if(res)
{
// printf("文件打開失敗res=%d\r\n",res);
return 2;
}
W25Q64_WriteData(addr-10,(u8 *)" ",9);//清除標(biāo)志位
if(font_size==16)y=100;
else if(font_size==24)y=140;
else if(font_size==32)y=180;
LCD_Display_Str2(20,y,16,(u8 *)"更新進(jìn)度:",BLACK,WHITE);
LCD_Refresh();
while(1)
{
f_read(&fp,buff,1024,&br);
W25Q64_WriteData(addr+cnt,buff,br);
cnt+=br;
load=(cnt*1.0/size)*100;
if(load!=load2)
{
load2=load;
LCD_Display_Str2(30+strlen("更新進(jìn)度")/2*16,y,16,(u8 *)" ",WHITE,WHITE);
snprintf(buff2,sizeof(buff2),"%.1f %%",load2);
LCD_Display_Str2(30+strlen("更新進(jìn)度")/2*16,y,16,(u8 *)buff2,RED,WHITE);
LCD_Refresh();
}
//printf("更新進(jìn)度:%d\r\n",cnt);
if(br!=1024)break;
}
/*寫入標(biāo)志位*/
if(font_size==16)
{
strcpy((char *)buff,"GBK16_OK");
}
else if(font_size==24)
{
strcpy((char *)buff,"GBK24_OK");
}
else if(font_size==32)
{
strcpy((char *)buff,"GBK32_OK");
}
W25Q64_WriteData(addr-10,buff,9);//GBK16_OK
f_close(&fp);//關(guān)閉文件
return 0;
}
2.獲取小說文件信息
/*SD卡操作函數(shù)*/
typedef struct FILE_info
{
char file_name[100];
u32 file_size;
u16 y;/*在屏幕位置*/
struct FILE_info *next;
struct FILE_info *pre;
}FILE_INFO;
FILE_INFO *story_head=NULL;
/*創(chuàng)建鏈表*/
FILE_INFO *List_CreateHead(FILE_INFO *head)
{
if(head!=NULL)return head;
head=malloc(sizeof(FILE_INFO));
head->next=NULL;
head->pre=NULL;
return head;
}
/*添加節(jié)點(diǎn)*/
FILE_INFO *List_AddNode(FILE_INFO *head)
{
if(head==NULL)return NULL;//鏈表頭不存在
FILE_INFO *phead=head;
while(phead->next!=NULL)
{
phead=phead->next;
}
FILE_INFO *new_node=malloc(sizeof(FILE_INFO));
new_node->pre=phead;
phead->next=new_node;
new_node->next=NULL;
return new_node;
}
/*遍歷節(jié)點(diǎn)*/
void List_PrintNode(FILE_INFO *head)
{
u16 x=20,y=50;
LCD_Display_Str2(LCD_WIDTH/2-24,10,16,(u8 *)"書 架",BLACK,WHITE);
if(head==NULL)return ;//鏈表頭不存在
FILE_INFO *phead=head;
while(phead->next!=NULL)
{
phead=phead->next;
phead->y=y;
LCD_Display_Str2(x,phead->y,16,(u8 *)phead->file_name,DARKBLUE,WHITE);//顯示字符串
y+=35;
//printf("%s,%d\r\n",phead->file_name,phead->file_size);
}
LCD_Refresh();
}
u16 List_CheckNode(FILE_INFO *head,u16 y,u8 *file_name)
{
if(head==NULL)return 0;//鏈表頭不存在
FILE_INFO *phead=head;
while(phead->next!=NULL)
{
phead=phead->next;
if(y<=phead->y+26 && y>=phead->y-5)
{
strcpy((char *)file_name,phead->file_name);
return phead->y;
}
}
return 0;//未找到
}
/*************************************目錄遍歷(讀取小說文件信息)************************/
u8 FATFS_printDir(const TCHAR* path)
{
DIR dp;
u8 res;
u8 stat=0;
story_head=List_CreateHead(story_head);//創(chuàng)建鏈表頭
res=f_opendir(&dp,path);
FILINFO file_info;
if(res)
{
printf("打開目錄失敗res=%d\r\n",res);
free(story_head);//釋放鏈表頭
return 1;
}
FILE_INFO *temp=NULL;
while(1)
{
res=f_readdir(&dp,&file_info);
if(res!=FR_OK || file_info.fname[0]==0)break;
if(strstr(file_info.fname,".txt"))
{
temp=List_AddNode(story_head);
if(temp==NULL)
{
stat=2;//動(dòng)態(tài)分配空間失敗
goto AA;
}
//printf("文件名:%s,",file_info.fname);
strcpy(temp->file_name,file_info.fname);//文件名
if(file_info.fattrib == AM_ARC)//普通文件
{
temp->file_size=file_info.fsize;//文件大小
//printf("文件大小:%u byte\r\n",file_info.fsize);
}
}
}
AA:
f_closedir(&dp);//關(guān)閉目錄
List_PrintNode(story_head);
return stat;
}
3.讀取小說內(nèi)容,翻頁,字體選擇、顏色切換
/*打開小說*/
u8 buff_read[4098];
const u16 font_corlour[]={BLACK,BLUE,RED,LIGHTGREEN};
void FATFS_ReadFile(const char *file_name)
{
FIL fp;//文件指針
u8 res=0;
UINT br;
u32 font_buff[20];//保存每頁字節(jié)數(shù)據(jù)
u16 font_cnt=0;
u16 font_len=0;
u16 font_size=16;//字體大小
u16 x=0,y=20;
u8 corlour=0;
char name[100];
snprintf(name,sizeof(name),"0:/Text/%s",file_name);
res=f_open(&fp,name,FA_READ);//打開文件
if(res)
{
printf("文件打開失敗res=%d\r\n",res);
return ;
}
u8 *p;
u16 x1,y1;
u8 stat=0;
while(1)
{
if(stat)
{
buff_read[0]=stat;
stat=0;
res=f_read(&fp,&buff_read[1],4095,&br);
br++;
buff_read[br]='\0';
}
else
{
res=f_read(&fp,buff_read,4096,&br);
buff_read[br]='\0';
}
p=buff_read;
while(*p)
{
font_len=LCD_Display_Str(x,y,font_size,p,font_corlour[corlour]);//顯示字符串
LCD_Refresh();
while(1)
{
res=XPT2046_ReadXY();//觸摸屏檢測(cè)
if(res)
{
x1=xpt2046_info.x;
y1=xpt2046_info.y;
while(T_PEN==0){}//等待松開
//printf("x1=%d,y1=%d\r\n",x1,y1);
if((x1>=212 && x1<=320) && (y1>=416 && y1<=480))//返回
{
LcdFill(0,0,320,480,WHITE);
List_PrintNode(story_head);
return ;
}
else if((x1>=106 && x1<=210) && (y1>=416 && y1<=480))//字體顏色
{
corlour++;
if(corlour>=4)corlour=0;
LcdFill(0,0,320,410,WHITE);
break;
}
else if((x1>=1 && x1<=105) && (y1>=416 && y1<=480))//字體大小調(diào)節(jié)
{
if(font_size==16)font_size=24;
else if(font_size==24)font_size=32;
else if(font_size==32)font_size=16;
LcdFill(0,0,320,410,WHITE);
break;
}
else if(x1>160 && y1<=380)
{
p+=font_len&0x7fff;
if(*p!='\0')
{
font_buff[font_cnt++]=font_len&0x7fff;
LcdFill(0,0,320,410,WHITE);
break;
}
else
{
if(font_len&0x8000)
{
stat=*(p-1);
}
LcdFill(0,0,320,410,WHITE);
break;
}
}
else if(x1<160 && y1<=380)
{
if(p!=buff_read && font_cnt>0)
{
font_cnt--;
p-=font_buff[font_cnt];
LcdFill(0,0,320,410,WHITE);
break;
}
}
}
}
}
font_cnt=0;
memset(buff_read,0,sizeof(buff_read));
if(br!=4096)break;
}
}
4.主函數(shù)main.c,硬件初始化,觸摸屏校準(zhǔn),字體檢測(cè)與更新,主界面顯示
#include "stm32f10x.h"
#include "beep.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "w25q64.h"
#include "at24c08.h"
#include "timer.h"
#include
#include "xpt2046.h"
#include "nt35310.h"
#include "sram.h"
#include
#include "ff.h"http://文件系統(tǒng)頭文件
#include "sdcard.h"
u8 SDcard_DownFont(const TCHAR* path,u32 addr,u16 font_size);//字庫更新
u8 FATFS_printDir(const TCHAR* path);//遍歷目錄
u16 List_CheckNode(FILE_INFO *head,u16 y,u8 *file_name);//查找文件
void FATFS_ReadFile(const char *file_name);//讀文件
FATFS fs;
int main()
{
u16 y=0;
char buff[30];
u8 res=0;
Beep_Init();
Led_Init();
Key_Init();
Usartx_Init(USART1,115200,72);
printf("串口初始化完成\r\n");
W25Q64_Init();
IIC_Init();
LCD_Init();
Sram_Init();
XPT2046_Init();//初始化
Touch_Calibration();
AA:
LCD_Clear(WHITE);//清屏函數(shù)
LCD_Refresh();
LCD_Display_Str2(20,20,16,(u8 *)"SD卡狀態(tài)",RED,WHITE);
res=f_mount(&fs,"0:",1);//磁盤掛載
if(res)
{
printf("SD卡掛載失敗ERR=%d\r\n",res);
snprintf(buff,sizeof(buff),"err%d",res);
LCD_Display_Str2(20+strlen("SD卡狀態(tài)")*12+20,20,16,(u8 *)buff,RED,WHITE);
LCD_Display_Str2(20,50,16,(u8 *)"請(qǐng)檢查SD卡是否插入!",RED,WHITE);
LCD_Refresh();
Delay_Ms(500);
goto AA;
}
else LCD_Display_Str2(20+strlen("SD卡狀態(tài)")*12+20,20,16,(u8 *)"OK",RED,WHITE);
/*字庫檢測(cè)*/
LCD_Display_Str2(LCD_WIDTH/2-strlen("字庫檢測(cè)")/2*16,40,16,(u8 *)"字庫檢測(cè)",RED,WHITE);
LCD_Refresh();
GBK_16:
W25Q64_ReadData(GBK_16_ADDR-10,(u8*)buff,9);//GBK16_OK
if(strstr(buff,"GBK16_OK"))
{
LCD_Display_Str2(20,60,16,(u8 *)"GBK16 OK",RED,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(20,60,16,(u8 *)"GBK16 NO",RED,WHITE);
LCD_Display_Str2(LCD_WIDTH/2-strlen("更新GBK16字庫")/2*16,80,16,(u8 *)"更新GBK16字庫",RED,WHITE);
LCD_Refresh();
if(SDcard_DownFont("0:/font/GBK_16.DZK",GBK_16_ADDR,16))//字庫更新
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,80,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(10,80,16,(u8 *)"請(qǐng)將GBK_16.DZK放到/font/目錄下,重啟!",BLACK,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,80,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(20,100,16,(u8 *)" ",WHITE,WHITE);
LCD_Refresh();
goto GBK_16;
}
}
/*GBK24_OK*/
GBK_24:
W25Q64_ReadData(GBK_24_ADDR-10,(u8*)buff,9);
if(strstr(buff,"GBK24_OK"))
{
LCD_Display_Str2(20,100,16,(u8 *)"GBK24 OK",RED,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(20,100,16,(u8 *)"GBK24 NO",RED,WHITE);
LCD_Display_Str2(LCD_WIDTH/2-strlen("更新GBK24字庫")/2*16,120,16,(u8 *)"更新GBK24字庫",RED,WHITE);
LCD_Refresh();
if(SDcard_DownFont("0:/font/GBK_24.DZK",GBK_24_ADDR,24))//字庫更新
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,120,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(10,120,16,(u8 *)"請(qǐng)將GBK_24.DZK放到/font/目錄下,重啟!",BLACK,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,120,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(20,140,16,(u8 *)" ",WHITE,WHITE);
LCD_Refresh();
goto GBK_24;
}
}
/*GBK32_OK*/
GBK_32:
W25Q64_ReadData(GBK_32_ADDR-10,(u8*)buff,9);
if(strstr(buff,"GBK32_OK"))
{
LCD_Display_Str2(20,140,16,(u8 *)"GBK32 OK",RED,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(20,140,16,(u8 *)"GBK32 NO",RED,WHITE);
LCD_Refresh();
LCD_Display_Str2(LCD_WIDTH/2-strlen("更新GBK32字庫")/2*16,160,16,(u8 *)"更新GBK32字庫",RED,WHITE);
LCD_Refresh();
if(SDcard_DownFont("0:/font/GBK_32.DZK",GBK_32_ADDR,32))//字庫更新
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,160,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(10,160,16,(u8 *)"請(qǐng)將GBK_32.DZK放到/font/目錄下,重啟!",BLACK,WHITE);
LCD_Refresh();
}
else
{
LCD_Display_Str2(LCD_WIDTH/2-strlen(" ")/2*16,160,16,(u8 *)" ",WHITE,WHITE);
LCD_Display_Str2(20,180,16,(u8 *)" ",WHITE,WHITE);
LCD_Refresh();
goto GBK_32;
}
}
Delay_Ms(1000);
Delay_Ms(1000);
Delay_Ms(1000);
LCD_Clear(WHITE);//清屏函數(shù)
LCD_Refresh();
FATFS_printDir("0:/Text/");
while(1)
{
res=XPT2046_ReadXY();
if(res)
{
//printf("x,y=%d,%d\r\n",xpt2046_info.x,xpt2046_info.y);
y=List_CheckNode(story_head,xpt2046_info.y,(u8 *)buff);
if(y)
{
LcdFill(0,y-8,320,y+24,LIGHTGREEN);
LCD_Display_Str2(20,y,16,(u8 *)buff,DARKBLUE,LIGHTGREEN);//顯示字符串
LCD_Refresh();
while(T_PEN==0){}//等待松開
LcdFill(0,0,320,480,WHITE);
OLED_DrawRectangle(1, 415, 319,479,BLACK);//繪制矩形
OLED_DrawRectangle(2, 416, 318,478,BLACK);//繪制矩形
LCD_DrawLine(105, 415, 105, 479,BLACK);
LCD_DrawLine(106, 415, 106, 479,BLACK);
LCD_DrawLine(211, 415, 211, 479,BLACK);
LCD_DrawLine(212, 415, 212, 479,BLACK);
LCD_Display_Str2(5,415+20,24,(u8 *)"字體大小",BLACK,WHITE);//顯示字符串
LCD_Display_Str2(106+5,415+20,24,(u8 *)"字體顏色",BLACK,WHITE);//顯示字符串
LCD_Display_Str2(212+29,415+20,24,(u8 *)"返回",BLACK,WHITE);//顯示字符串
LCD_Refresh();
FATFS_ReadFile(buff);
}
}
}
}
-
lcd
+關(guān)注
關(guān)注
34文章
4426瀏覽量
167484 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
355985 -
閱讀器
+關(guān)注
關(guān)注
0文章
301瀏覽量
27921 -
TFT
+關(guān)注
關(guān)注
10文章
385瀏覽量
111089
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論