日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于STM32的小说阅读器

發(fā)布時(shí)間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于STM32的小说阅读器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基于STM32的小說閱讀器

1.硬件平臺

  • CPU:STM32F103ZE
  • 屏幕:3.5寸TFTLCD屏
  • 觸控:電阻式觸摸屏xpt2046
  • SD卡

2.實(shí)現(xiàn)功能

??1.SD卡設(shè)備檢測,文件系統(tǒng)移植,用戶存儲小說和字庫文件;
??2.字庫信息加載檢測,自動完成字庫信息加載與更新。本次采用GBK字庫,字體大小有16*16、24*24、32*32三個(gè)字庫;
??3.觸摸屏校準(zhǔn),上電檢測觸摸屏校準(zhǔn)信息;手動進(jìn)入觸摸屏校準(zhǔn)模式
??4.小說文件索引,小說文本切換;
??5.小說翻頁,字體大小選擇,顏色選擇,返回主目錄;

3.示例效果

?SD卡檢測和觸摸屏校準(zhǔn)

?字庫檢測與更新

?目錄和小說顯示界面

?顏色切換

?字體選擇

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_OKf_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;//動態(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();//觸摸屏檢測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),字體檢測與更新,主界面顯示

#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 <string.h> #include "xpt2046.h" #include "nt35310.h" #include "sram.h" #include <stdlib.h> #include "ff.h"//文件系統(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 *)"請檢查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);/*字庫檢測*/LCD_Display_Str2(LCD_WIDTH/2-strlen("字庫檢測")/2*16,40,16,(u8 *)"字庫檢測",RED,WHITE);LCD_Refresh();GBK_16:W25Q64_ReadData(GBK_16_ADDR-10,(u8*)buff,9);//GBK16_OKif(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 *)"請將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 *)"請將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 *)"請將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);}}} }

5.完整示例

https://download.csdn.net/download/weixin_44453694/84997777

總結(jié)

以上是生活随笔為你收集整理的基于STM32的小说阅读器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。