哔哩哔哩视频链接:https://www.bilibili.com/video/BV1Y64y1f7Ji/代码资料链接:https://download.csdn.net/download/mbs520/13510169
百度网盘资料链接:https://pan.baidu.com/s/1NHRFNa8Qn7M286kv4WnHKA
提取码:abcd
电子小说阅读器v1.2版本:https://www.cirmall.com/circuit/25747/
取走记得点赞
项目说明:
用到的主要技术:
功能要求:
开机Logo
电子书列表扫描
电子书列表显示及小说选择菜单
阅读功能:
1、普中STM32F4ZGT6最小系统板一块(或者其他STM32F4板子)
(注意要买能插LCD屏的)
作用:主控芯片、处理各种数据
2、800*480 4.3寸电容触摸LCD屏(我用的正点原子的屏)
作用:显示与触摸控制
3、一张32G以下的SD卡和一个读卡器
1、把屏幕插到开发板上即可
(一)、txt文件数据的读取
1、谈谈txt文件
学过C语言的文件IO都知道,用open函数打开后,用read函数读取的第一个字节开始就是文本内容,txt文件是文档文件,对于我们程序员来说文档文件是最容易操作的文件类型之一,因为它不像图片那样还需要考虑头部的一大堆信息
2、读取txt文件数据
利用FATFS文件系统提供的函数f_open 、f_read即可对数据进行读取出来,当然读取出来的都是文字的编码,可以先用串口函数打印出来看看数据对不对 printf("%s\r\n",buf);
(二)汉字的显示(具体代码参考正点原子“汉字显示实验”)
1、汉字的显示原理
1)学习过屏幕驱动的应该都知道,屏幕的显示无非就是在屏幕上打相应颜色的点,比如要显示一个字符 ‘A’ 那么我只需要知道 ‘A’ 相应的点阵数据就可以把它显示出来,汉字也一样。
2、汉字库的存储
2)但是汉字与字符不同的是,汉字有1万多个,字符却只有100多个,并且汉字的显示明显比字符的点阵复杂程度高,比如说字体是12的字符占用点阵是12x6,每个字符需要12x6/8=9个字节的存储空间。字体是12 的汉字占用12x12的点阵,每个汉字需要12x12/8=18个字节存储空间,这还是最小字体,大的字体所需要的存储空间只会成倍增加
3)一般12号字体的汉字库需要500K字节、16号字体700K、24号字体1.6M、32号字体3M,这对于单片机来说数据量太大了,内部FLASH512K~1M表示压力很大
4)需要把汉字库通过SD卡再保存到外部FILASH才行,w25q128无疑是个好选择,它拥有16M的存储空间,SPI通信协议,读写速度也是相当快。
(三)txt文件数据显示到MCU屏
1、数据编码格式的问题
有关显示汉字就必然会涉及编码格式的问题,不同的编码格式对应的汉字编码是不同的,比如UTF-8编码的文件用GB2312编码打开就会乱码。
同理,比如文档的格式是UTF-8编码,但是我的字库是GBK编码,读出来的数据直接显示到屏幕就必然会乱码
1、SD卡根目录文件拷贝
4、进入主界面
啥都没有,先导入图书
图书要从SD卡中导入,txt文件在资料里已经打包好了,直接导入
5、导入图书
找到0:/TXT目录下的.txt文件,选择导入
导入“斗罗大陆.txt”,主界面开始显示
图片是系统自动匹配,检测是否有与小说同名图片文件,比如“斗罗大陆.txt” 对应 “斗罗大陆.jpg”
如果没有匹配图片会显示默认图片
6、删除图书
点击左下角删除图书,再点击 X 即可移除图书操作,只是移除,并不是真正删除。
7、阅读界面
阅读界面都是根据页数匹配相应文字,因为读写速度问题加上需要算法识别加载,翻页加载过程都会有一段时间
8、目录功能
自动检测目录,通过检测“第” 与 “章”加上相应算法就可以检测显示目录,并记录偏移,可以跳转,上划可以显示下一页目录
9、设置字体、背景
可以设置显示背景,字体颜色,字体大小来适应自己喜欢的阅读方式
1)24号字体 、白天
2)24号字体、护眼
3)12号字体、护眼
代码过长,只展示部分代码:
#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"
#include "piclib.h"
#include "string.h"
#include "math.h"
#include "touch.h"
u8 menu_num;//当前主菜单页数
u32 page;//当前页数
//char chapter_name[50];//当前章节名
u32 page_offset[1000];//保存页数偏移
//u32 page_off_mult;//页数偏移倍数
u8 txt_num;//当前书架图书数量
u8 txt_path_name[30][60];//导入图书路径
u32 bookmark[30]; //保存对应书签 也就是页数 下次进入直接偏移页数
char txt_name[4][30]={
"","","",""};//显示4本图书名字
u8 pname[60]; //正在打开的文件名路径
int SIZE=24; //初始化字体
char buff[2500];//一页数据 缓冲文档
int page_mul_cnt=0;//存取次数 一次1000页
int now_page_mul;//当前1000页的倍数
u32 data_offset;//读取偏移 读写flash用
//显示主界面
void menu(void);
//获取触摸键值
u16 get_ts_val(int key);
//读取文件数据到LCD
int read_to_lcd(void);
//更新小说名
u8 lcd_dis_files(u8 * path);
//阅读模式
void read_mode(void);
//设置字体格式
int setting(void);
//设置界面
void show_setting(void);
//目录功能
u32 txt_dir_scan(void);
//文件系统功能 导入小说
void fatfs_choose(void);
//读取数据到flash
void file_data_to_w25q(void);
//根据页码得到页数
u32 ident_get_page(u32 page_offset);
//遍历文件 显示到屏幕
u8 mf_scan_file(u8 * path);
//刷新显示书架名字
void re_dis_txtname(int i);
//带路径的文件名 转 不带路径文件名
char* path_change(char *oldpath);
//根据页数得到页码
u32 ident_get_offset(u32 page);
//更新内存1000页页码
void update_page_offset(void);
//读出书签数据
void read_bookmark(void);
//保存书签数据到flash
void save_bookmark(void);
//保存书名数据到flash
void save_bookinfo(void);
//删除小说
void del_txt(u8 *path);
//删除小说控制界面
void del_txt_ctrl(void);
int main(void)
{
DIR picdir; //图片目录
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //LCD初始化
KEY_Init(); //按键初始化
tp_dev.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()); //检查字库
delay_ms(150);
piclib_init(); //初始化画图
delay_ms(150);
LCD_Clear(GBLUE);//清屏
ai_load_picfile("0:/SYSTEM/PICTURE/logo.gif",0,0,lcddev.width,lcddev.height,1);//显示图
read_bookmark();//读出图书 书签数据
memset(page_offset,0,1000*4);//清空页码数组
menu_num=1;//显示第一页
//lcd_dis_files("0:/TXT");//更新系统书名
menu();//显示主界面
while(1)
{
key = get_ts_val(1);
if(key!=0)
{
printf("key=%d\n",key);
switch(key)//选择要打开的图书
{
case 1: if(txt_num-4*(menu_num-1)>=1){
strcpy((char *)pname,(char *)txt_path_name[0+(menu_num-1)*4]);//把要打开的书籍名称赋值
page = bookmark[0+(menu_num-1)*4];//根据flash保存的书签初始化进入的页数
if(page >= 0xffff)page=0;
read_mode();//进入阅读模式
bookmark[0+(menu_num-1)*4] = page;//退出保存书签
save_bookmark();
}break;
case 2: if(txt_num-4*(menu_num-1)>=2){
strcpy((char *)pname,(char *)txt_path_name[1+(menu_num-1)*4]);
page = bookmark[1+(menu_num-1)*4];
if(page >= 0xffff)page=0;
read_mode();//进入阅读模式
bookmark[1+(menu_num-1)*4] = page;
save_bookmark();
}break;
case 3: if(txt_num-4*(menu_num-1)>=3){
strcpy((char *)pname,(char *)txt_path_name[2+(menu_num-1)*4]);
page = bookmark[2+(menu_num-1)*4];
if(page >= 0xffff)page=0;
read_mode();//进入阅读模式
bookmark[2+(menu_num-1)*4] = page;
save_bookmark();
}break;
case 4: if(txt_num-4*(menu_num-1)>=4){
strcpy((char *)pname,(char *)txt_path_name[3+(menu_num-1)*4]);
page = bookmark[3+(menu_num-1)*4];
if(page >= 0xffff)page=0;
read_mode();//进入阅读模式
bookmark[3+(menu_num-1)*4] = page;
save_bookmark();
}break;
case 5: //导入图书
fatfs_choose();//文件系统选择文件导入
save_bookinfo();//保存书籍数据到flash
printf("当前图书数量:%d\r",txt_num);
break;
case 6: del_txt_ctrl();//删除图书
break;
case 111: if((txt_num-1)/4+1>menu_num)menu_num++;
printf("menu_num = %d\n",menu_num);//上一页
break;
case 222: if(1<menu_num)menu_num--;
printf("menu_num = %d\n",menu_num);//下一页
break;
}
menu();//显示主界面
data_offset=0;//偏移清零
page_mul_cnt=0;//1000页倍数清零
}
delay_ms(10);
}
}
基于stm32c8t6的坡道行驶巡线小车(2020年TI杯大学生电子设计竞赛 C题)https://blog.csdn.net/mbs520/article/details/115438122
基于STM32F4的音乐播放器
https://blog.csdn.net/mbs520/article/details/111313042
基于STM32F4的电子阅读器(首创)
https://blog.csdn.net/mbs520/article/details/110817173
基于51单片机WiFi视频小车(首创)
https://blog.csdn.net/mbs520/article/details/109843972
基于51单片机蓝牙小车
https://blog.csdn.net/mbs520/article/details/109775964
基于MSP430 坡道行驶电动小车(2020年TI杯大学生电子设计竞赛 C题)
https://blog.csdn.net/mbs520/article/details/109090072
基于stm32f4的智能门锁系统
https://blog.csdn.net/mbs520/article/details/106987758
基于51单片机超声波测距小车
https://blog.csdn.net/mbs520/article/details/106599219
基于51单片机定时宠物喂食系统
https://blog.csdn.net/mbs520/article/details/108292187
基于QT5 Linux平台 停车场管理系统
https://blog.csdn.net/mbs520/article/details/113481824
基于QT5 Linux平台 车载系统
https://blog.csdn.net/mbs520/article/details/112873809
基于Linux系统 媒体播放器
https://blog.csdn.net/mbs520/article/details/107880118
基于Linux系统 语音识别、人机对话
https://blog.csdn.net/mbs520/article/details/113179224
基于Linux系统小钢琴程序(暂无博客)
https://download.csdn.net/download/mbs520/12798287
基于Linux系统 QQ通讯录管理系统(暂无博客)