一、项目功能要求
" }7 R4 M5 x6 W& O项目说明:
1 D' w9 i$ A3 M" y项目偏软件,但是要依赖于自己对硬件的熟悉和驱动才能完成
& z& x0 O) a- ]0 j7 S& }用到的主要技术:
& I4 C0 z, B4 P% c% CSD卡驱动(难–不过可移植 SD卡驱动细节可在用完再了解其驱动协议)
+ p ^% Y' a0 c2 d0 r$ q- JFatFs文件系统移植使用
. ~- P) n- ~! F, {( {0 y1 ZLCD屏驱动(加载字库文件 做字库在LCD上的显示)
3 H% q, n; b7 I
& `* Y# R0 d# J! m. x/ E! K功能要求:
1 i- T2 x) n& ^9 i9 C% f7 L开机Logo
0 l: P# T, L! D电子书列表扫描
0 g( W6 _/ ]. N: n5 E电子书列表显示及小说选择菜单+ }1 V! i8 g/ i2 s& Z" \6 J
阅读功能:9 _$ A2 i# M: b# [4 {! v" |7 Z7 d
字体选择
& n5 A# L" g- ]* E9 s% P字体大小选择
( F) |* J. X8 F! y! K字体颜色设置
) C/ j/ i0 y5 q0 L" j阅读背景设置3 B7 b3 H# z) E2 i6 q+ y7 X
书签设置
# z3 a6 W: U/ S1 V- ~8 T能够记录每本电子书的退出时处于什么阅读位置 下次进入从该位置继续阅读; [1 c$ w9 U( C' r) Y) ]
目录生成功能(字符匹配)8 J, z e5 y: ~2 O5 D. ^
章节跳转功能(基于目录生成功能), m% k% D1 I L4 h
阅读翻页设置(滚动/切换)6 `9 L! Q: m& a3 j
8 P- n3 M# ?$ a8 L4 L' u f
二、材料准备
2 o( D, J& m3 s* n+ g- ^7 q1、普中STM32F4ZGT6最小系统板一块(或者其他STM32F4板子)) R* @, k+ O* g0 ?
(注意要买能插LCD屏的)( ^9 m1 g) a+ I0 U! Z. R
作用:主控芯片、处理各种数据# Q* {- D3 G' n( K* M1 v
2 ~* O/ `% A6 R# l
5 F8 D7 q/ {/ \1 p
- W( S5 r' f# E7 h2 Z' T3 C2、800*480 4.3寸电容触摸LCD屏(我用的正点原子的屏)
1 m5 ^( u+ Z# Q) ]3 k5 o7 Y作用:显示与触摸控制
; @3 T. D, X2 L: h. c( N$ Q5 s, k6 E- x# C% }
4 L4 ?2 O- l5 ~: H
7 E$ l- H/ V$ t9 S' V; I; x2 g0 q- I8 t
3、一张32G以下的SD卡和一个读卡器
# K. ?8 q8 J! z
) _# z! n& I& b( W作用:存储小说文件与图片文件4 }% c3 F2 V; c; q6 g# I5 S- }
2 n0 l* q% [- q4 i0 j3 f, |) f
+ O6 |8 c: i+ C2 p. ]: e
. O' I" P$ P& G* m* V3 c$ x二、硬件连接! S0 f! j2 o- ~& A' u9 |
1、把屏幕插到开发板上即可
9 \! N# u8 f$ S% Y" ^) K
# x; b. f0 Q" s+ I5 T三、相关知识点
! |( t8 E% ^2 G- b; F- B" [# C+ `! Y(一)、txt文件数据的读取
! D' ]8 l* i5 P5 F# X, z; ~( q; C
1、谈谈txt文件
- ?. d/ P' `6 G# P+ B! f! k5 j* ^* J! `; d
学过C语言的文件IO都知道,用open函数打开后,用read函数读取的第一个字节开始就是文本内容,txt文件是文档文件,对于我们程序员来说文档文件是最容易操作的文件类型之一,因为它不像图片那样还需要考虑头部的一大堆信息* S5 ~' c1 X3 C- J4 L# B
/ E9 O# k5 h0 j) {% T' f2、读取txt文件数据9 ~2 v S2 H2 M5 w7 w% K& H5 l
( N8 b# H3 B# w1 _- a" v
利用FATFS文件系统提供的函数f_open 、f_read即可对数据进行读取出来,当然读取出来的都是文字的编码,可以先用串口函数打印出来看看数据对不对 printf("%s\r\n",buf);" W- [; U5 I3 S& V
w6 k# c. o1 j: F, f$ k(二)汉字的显示(具体代码参考正点原子“汉字显示实验”)+ } D9 e( D* u! d
+ Y; r. W& e8 N: n; U
1、汉字的显示原理, X% a0 M( q3 G h' h# v
5 j6 d0 `$ e4 N# h; {$ _7 g1)学习过屏幕驱动的应该都知道,屏幕的显示无非就是在屏幕上打相应颜色的点,比如要显示一个字符 ‘A’ 那么我只需要知道 ‘A’ 相应的点阵数据就可以把它显示出来,汉字也一样。& g3 `" e! a, S2 w z0 _
& H Y. s0 r" Y) r9 N1 U. j
2、汉字库的存储% P& ]3 s1 |3 t) H; I% O
; d3 h/ E Y4 g! t/ I2)但是汉字与字符不同的是,汉字有1万多个,字符却只有100多个,并且汉字的显示明显比字符的点阵复杂程度高,比如说字体是12的字符占用点阵是12x6,每个字符需要12x6/8=9个字节的存储空间。字体是12 的汉字占用12x12的点阵,每个汉字需要12x12/8=18个字节存储空间,这还是最小字体,大的字体所需要的存储空间只会成倍增加- Y$ f* T+ ?) z) y! x4 }% C
0 |* E/ P. x; V
3)一般12号字体的汉字库需要500K字节、16号字体700K、24号字体1.6M、32号字体3M,这对于单片机来说数据量太大了,内部FLASH512K~1M表示压力很大
$ z% |8 `1 d% ]* W, Q3 _" |
" n, t, _2 s2 j8 L3 o) W: c% {: [" t- w3 c6 o9 u
1 q6 K! o; E0 F3 ]3 T+ H8 {3 T! j
2 n7 Y6 {; I' N8 f+ v4)需要把汉字库通过SD卡再保存到外部FILASH才行,w25q128无疑是个好选择,它拥有16M的存储空间,SPI通信协议,读写速度也是相当快。5 @6 H4 c/ ~1 V$ K
' j0 g2 a _5 B) {(三)txt文件数据显示到MCU屏( E4 p: M! Q# t# y, ]
* A0 f l9 I# T3 t3 f" x: H* {2 H$ W
1、数据编码格式的问题9 M* y3 S- }5 c& P
6 l6 N# ~- y& Q& ?' }8 N( a! M
有关显示汉字就必然会涉及编码格式的问题,不同的编码格式对应的汉字编码是不同的,比如UTF-8编码的文件用GB2312编码打开就会乱码。
* k" e1 R" z, m5 H# u同理,比如文档的格式是UTF-8编码,但是我的字库是GBK编码,读出来的数据直接显示到屏幕就必然会乱码
2 C- J0 m) C# D3 ~1 m' ^
4 ~0 c) p2 M" h# d. ]( J/ d四、下载调试8 a0 f3 o; y0 {
* g: }; V5 u" X
1、SD卡根目录文件拷贝
9 j6 p* |7 X0 j5 a1 o7 R# G$ H
Z8 h( E9 L3 a4 f+ x* O下载好本博客配套资料,把下面两个文件夹拷贝到SD卡根目录下* M; t2 N8 H( S8 j
2 x' f6 i' x) e+ j' [' c9 Z
! k6 }% i0 d5 N, ]* i
! x: e& X! I# L6 u! X f5 V% o: B2 u; C
()一定要是根目录,不然不能正常运行
+ Y+ c" I: H+ f4 ~) s, C2 v5 K; I5 ~% _6 p( ~% s5 S3 R! L
2、初始化外部FLASH -W25Q1288 Y3 y6 {$ M; U+ _ z
用keil打开代码工程,编译通过后下载$ D, I' M+ Q+ ?3 k4 P
下载完成等待外部FLASH -W25Q128初始化完成,一开始会黑屏一段时间,是在擦除FLASH,然后会提示字库加载进度,直到LCD显示阅读界面为止7 m7 m/ u# M. f5 i" o. P
- h" D) E0 L$ }
) D/ g( X2 Q) `3 M* T' Z
r* C; J2 z3 U c) U( @( k# U# i2 n% P* {) b2 |$ ]+ l
如果下载代码后运行不正常:
' S1 Y3 Z' ]& W6 U1)注释掉这些代码,编译下载
1 ~, Y" B2 Q; q+ l( z% h u" V( g5 K
$ l; a0 M( t" k: m
: D* X. n" \: W N- C* q' k
* ]0 i$ s# w6 m$ w
' n4 r7 d7 O; {+ d' o# G o2)不要断电,取消注释这段代码,编译下载,下载完成后W25Q128初始化完成,应该就可以运行/ M1 q& k# ^# f/ U
9 a5 |" q @: f* W1 W- c; A
1 J% j) U- I4 _1 L/ e
- r8 \7 s1 ] E! w
. ]( d7 F4 _- w5 {. S) t* [ l0 z
3、化作尘动态logo4 e7 l2 d8 g$ Q
% C* n2 D5 f( v& `/ I
4、进入主界面7 U& Z P' q/ v" ^
啥都没有,先导入图书
) x" f5 v+ q5 S7 T图书要从SD卡中导入,txt文件在资料里已经打包好了,直接导入
4 _: D0 f, H/ R. g
2 _. h6 h$ E/ I: x% w: ^. H5、导入图书
3 A" ]9 s4 K+ `1 z找到0:/TXT目录下的.txt文件,选择导入
. G6 U2 ~5 r3 {7 h8 V! ?, V; a" s/ K( I6 H! ?
导入“斗罗大陆.txt”,主界面开始显示
* k9 h) H$ A7 ?7 N, \$ f6 q图片是系统自动匹配,检测是否有与小说同名图片文件,比如“斗罗大陆.txt” 对应 “斗罗大陆.jpg”, }) G, d& t& \. F5 u
3 `. Y9 l B" k$ k/ X如果没有匹配图片会显示默认图片5 a+ o3 a2 i' U/ o; l
7 o9 B/ @) x2 T3 }
6、删除图书
: ~) f* [8 k7 _! P' n; X点击左下角删除图书,再点击 X 即可移除图书操作,只是移除,并不是真正删除。
( _# N4 y0 F4 V! b) Y/ K, t! j) _7 W9 p3 X) h9 u+ S' D
0 ^ \- e" f* C
7、阅读界面! K1 ^- V7 M3 d/ D" ?) X
阅读界面都是根据页数匹配相应文字,因为读写速度问题加上需要算法识别加载,翻页加载过程都会有一段时间! H) O0 t5 S+ Y* b# ?: }# v2 K
A, t; a1 ~; }( g) ?$ [: r, k& E' k G" r& R I# ]
8、目录功能
4 t# v( R0 M* K$ N) Y5 _1 c$ p. Q自动检测目录,通过检测“第” 与 “章”加上相应算法就可以检测显示目录,并记录偏移,可以跳转,上划可以显示下一页目录
8 d) E: T4 S. s- F2 f- n' `' c/ o5 k8 b/ \4 _$ C' W" Y
9、设置字体、背景
/ p0 T7 G! r# ]1 T ?可以设置显示背景,字体颜色,字体大小来适应自己喜欢的阅读方式1 z3 A$ L8 u1 l; @8 T
1)24号字体 、白天! C# N0 c% L. `( `
2 v/ M. @0 K9 e2)24号字体、护眼4 d* C/ B) B; X; ?6 H! c( m+ E2 A% p
+ P5 f9 | n# d) m3)12号字体、护眼2 K$ F% p) f9 h
; M. L: t0 \( ?, [3 P
8 W# f% `4 ?3 J( S1 u; `5 m3)24号字体、夜间
: U- l* C6 P. Z9 c) R( K% q7 f) t( ]( |
1 G. G9 u% [" ^; g0 I5 v: ^五、程序设计4 X0 p6 G1 W5 A; u& I- S" g" B% I3 g
代码过长,只展示部分代码:
Z: B: h/ [8 E& W' X7 _/ d1 M, L8 D
% K4 @. M* |) }' i- Y& v' \% u( Y- #include "sys.h"
. V1 t' c7 k& N3 T- k: b/ Z% k3 G8 M - #include "delay.h"
/ l8 r( o+ J. Z% D5 m6 H+ g. k - #include "usart.h"# B# O0 h7 F# ^3 g4 J
- #include "led.h") z' w1 ?- |: x* S3 {' ?8 b( H
- #include "lcd.h" P% T& O) {) l- u+ z
- #include "key.h" 6 I4 Y. a4 k: x, Y# T# N. ~: G$ u
- #include "sram.h"
$ h+ H+ i; |+ _# q0 r4 ?7 M. ^ - #include "malloc.h"
9 v2 N# h( b6 ^9 {8 o, N8 X& z - #include "usmart.h" 2 r' ~& i, ~4 k1 v! x
- #include "sdio_sdcard.h"
. \. R% p, ]: H! a! d1 q0 u - #include "malloc.h"
, Y5 ^6 }) K! ~- o, o1 N; H) I - #include "w25qxx.h" 3 u& _" r7 @7 R, K
- #include "ff.h"
+ S8 Y0 S& I% _) L" y - #include "exfuns.h" U" e4 J; B8 j* p8 d, K
- #include "fontupd.h". ], v5 t$ @: [: r) j: {
- #include "text.h"
, v% _. S v) R) f - #include "piclib.h"
4 ]" i& |* M: |% ^. C - #include "string.h" G8 B- \ w/ d# D3 I( S4 f
- #include "math.h"
8 P& N f' G8 M! W4 N' p3 } - #include "touch.h") y' m' v: r& X& z- R; e1 g- ? k! z
4 b, C w) K. r8 E- u8 menu_num;//当前主菜单页数: ]2 k6 h, d L% d
- u32 page;//当前页数* S3 H' g3 }8 \ [2 \2 j; x
- //char chapter_name[50];//当前章节名; W7 _# Q! q1 c9 L
- u32 page_offset[1000];//保存页数偏移! R3 Y3 T( E+ H7 w u1 M" ~# J
- //u32 page_off_mult;//页数偏移倍数
& X' h6 T" n2 b0 { - u8 txt_num;//当前书架图书数量
0 ^+ P3 b' A. W+ Z' S - u8 txt_path_name[30][60];//导入图书路径1 c' c; o& C! Y" S/ K
- u32 bookmark[30]; //保存对应书签 也就是页数 下次进入直接偏移页数& ?$ S; Q. ~6 K6 \8 i
- char txt_name[4][30]={"","","",""};//显示4本图书名字% k+ \/ t5 `0 P. E# N1 @
- u8 pname[60]; //正在打开的文件名路径
. q) c4 g e* e - int SIZE=24; //初始化字体' i) X/ V% s( T8 o1 Z
- char buff[2500];//一页数据 缓冲文档
2 H* v1 O# C+ U* t# x$ W( H- j - int page_mul_cnt=0;//存取次数 一次1000页2 e5 f- S8 p1 O8 R+ R2 C% q
- int now_page_mul;//当前1000页的倍数9 s; |: e4 @+ g" \2 N/ F7 {
- u32 data_offset;//读取偏移 读写flash用6 Q% f9 R) J) x! [
- / t0 T/ ~- ?" S) q, J* ]
- ; a1 N& ]. ]" S1 L3 U
- //显示主界面
4 ~' J% ?9 a& Y) H& e, C3 b - void menu(void);! _- F( E0 t5 d m- ]
- //获取触摸键值
! z4 H& A: u. @ - u16 get_ts_val(int key);( \( V5 O* K# n: I- [) a/ f" v( w
- //读取文件数据到LCD4 l7 f( k9 @( Q) S- I' [0 y6 y% m, W
- int read_to_lcd(void);0 i0 B. k4 ] f% p3 _
- //更新小说名# ], L) Y" W& w8 t; X6 n% \9 L3 Y
- u8 lcd_dis_files(u8 * path);
. Z2 Q; m- L& Y& }( I - //阅读模式1 Y) j. [0 u% X6 r9 q2 r
- void read_mode(void);
T: _; ?+ C4 p- \7 |: D0 e3 z% u - //设置字体格式& e4 W6 [* V" T* |4 f% l N
- int setting(void);
7 I- c7 g- h/ }1 A( k - //设置界面% a7 u& d4 c: n4 q
- void show_setting(void);* K0 n4 k( f5 \. h; ~% Q& C M. l
- //目录功能3 D& N9 c9 q8 @. |+ j
- u32 txt_dir_scan(void);% V9 w* I( u1 {4 ~. P3 W/ h
- //文件系统功能 导入小说
6 _4 C. l5 q3 _7 j z4 Z; l - void fatfs_choose(void);
9 n0 A3 [: e5 Z - //读取数据到flash
# \8 C2 X) i6 `6 z& O4 ]8 g! Q# C - void file_data_to_w25q(void);
3 S, p' u& k- Z& b) r' ~( J - //根据页码得到页数4 }$ F4 H+ \$ o/ V F( A3 T
- u32 ident_get_page(u32 page_offset);
8 y; ^) \3 D! L8 e% u - //遍历文件 显示到屏幕$ W( q% P( Y9 b
- u8 mf_scan_file(u8 * path);
( S1 j) i8 I Y$ q4 q& \ - //刷新显示书架名字
: Z! y9 t) {. r" h - void re_dis_txtname(int i);
! r; N- r5 Q; b% ~" Q - //带路径的文件名 转 不带路径文件名
( u ]0 a& f: \6 e - char* path_change(char *oldpath);/ t. v {- j5 ]( q/ W- @
- //根据页数得到页码
6 N/ g2 X$ |. E. [/ i" U - u32 ident_get_offset(u32 page);: z( f3 X' q* Y3 t+ C
- //更新内存1000页页码0 j7 z) t# |* i: u( f: C) @+ h
- void update_page_offset(void);
! d- E) H8 K) \# K) p - //读出书签数据
# F9 X$ D. G& q1 h. ], _ - void read_bookmark(void);' A' @; m9 p' z5 x- [( ?
- //保存书签数据到flash
. x6 L9 f& f, R - void save_bookmark(void);
" R/ N# R. e6 q) ]& R* M8 {# ~9 n - //保存书名数据到flash4 s) ~* h' l6 S, }
- void save_bookinfo(void);- ]5 c2 b4 Z9 e3 Q F6 |6 P2 u
- //删除小说3 l# J0 s0 s& ~+ y- O
- void del_txt(u8 *path);
9 d i" C/ u! ^" D - //删除小说控制界面
9 D; Q- x- y8 W! K& i+ v - void del_txt_ctrl(void);
2 J/ \2 i) j( Z& v$ R -
1 d- }/ C0 p" s: ^3 g0 F( S - % V* Q) Z+ b7 P$ [+ L8 s) |' B
- , D7 P. C6 j+ f
( d( v0 I }+ G7 o- int main(void)
2 ^# C; I' r" w% N" T2 k9 u5 m8 o - { w- O$ X9 G4 u* b) E8 l' W% C Z
- DIR picdir; //图片目录' a0 s+ u/ R6 U( _/ [8 C
-
4 e9 c5 {4 x" k" |2 k6 c; H5 \ - u8 key; n. e% L' g4 ]
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
4 J! Q+ k! M- ~3 f" J2 C \ - delay_init(168); //初始化延时函数, k9 N' ^) k6 e5 g- _
- uart_init(115200); //初始化串口波特率为115200
, Q$ x! y# N& x ^% ^6 w- P4 U( \ - LED_Init(); //初始化LED ) V# P" |2 {' d, \
- LCD_Init(); //LCD初始化
8 X2 y- r' ~( u0 Z0 t4 B2 h - KEY_Init(); //按键初始化
* e: F b7 G1 n F' K1 C o - tp_dev.init(); //触摸初始化 0 `0 f% r p/ U+ {, _
- W25QXX_Init(); //初始化W25Q128" y8 h. g3 m1 I: A0 e2 {* J6 A
- usmart_dev.init(168); //初始化USMART
) e8 E' ?) j) Z- x - my_mem_init(SRAMIN); //初始化内部内存池 5 `, W( {" L8 ~$ k1 G, P
- my_mem_init(SRAMCCM); //初始化CCM内存池 7 C% ]: G2 B4 h4 Z
- exfuns_init(); //为fatfs相关变量申请内存
' H) h6 t, h( C: \/ Z" |/ l - f_mount(fs[0],"0:",1); //挂载SD卡
4 {) J L) }( y, L - f_mount(fs[1],"1:",1); //挂载FLASH.) A( h; F! Z: ~- W" G0 Q
- % C& X7 J5 W- C4 Q. O' ^! B1 e
- while(font_init()); //检查字库; _. c" y2 d/ A) Y4 X: }4 B0 ?
-
" `$ Q4 h9 X1 O% H4 U |. ] - delay_ms(150);
$ t1 L4 F1 R$ X3 l1 H7 m% l& N - piclib_init(); //初始化画图
( u- l8 C. `9 M0 Z4 H9 P$ q6 V# s4 ~ - delay_ms(150);
; }8 {. C1 f4 L$ j# P9 }/ P; R - LCD_Clear(GBLUE);//清屏5 b" n3 H' w; n4 _
- ai_load_picfile("0:/SYSTEM/PICTURE/logo.gif",0,0,lcddev.width,lcddev.height,1);//显示图- Z, ]) w3 y$ a F+ a8 O
- read_bookmark();//读出图书 书签数据
6 W" D5 [/ O3 c - memset(page_offset,0,1000*4);//清空页码数组
' x$ L2 ` V4 P' Q0 m - menu_num=1;//显示第一页" ~( ]; X2 Y8 v' j$ S9 f( t
- //lcd_dis_files("0:/TXT");//更新系统书名& u) a7 h" k" R! X3 M: {5 U
- menu();//显示主界面
+ B: W& m; c7 J" L2 K$ c+ V% _( Q6 ]# y - while(1)
3 b3 A' }% B, y2 E1 k9 r - {
* f* O8 o& `# z8 J - key = get_ts_val(1);7 o0 n+ t) c" g0 Z8 k
- if(key!=0)6 c+ w& y9 R+ \
- {
* W/ V% x' F5 F& _0 T - printf("key=%d\n",key);4 U" ^, R! u/ P
- switch(key)//选择要打开的图书! i" @; p8 w0 l6 [2 K( g) b
- {
# O) G7 [' Y+ C- I6 Y; ?- f+ l - case 1: if(txt_num-4*(menu_num-1)>=1){4 @9 Y* S1 e: z R- V0 D
- strcpy((char *)pname,(char *)txt_path_name[0+(menu_num-1)*4]);//把要打开的书籍名称赋值
N0 u( u$ y4 @6 E: Y -
4 ^! s" ]! i6 Y; M" L - page = bookmark[0+(menu_num-1)*4];//根据flash保存的书签初始化进入的页数 d, |; l; z; t/ l! F. N
- if(page >= 0xffff)page=0;
# l' P, j) w& f0 s - read_mode();//进入阅读模式* l0 \7 Y" w, ]
- bookmark[0+(menu_num-1)*4] = page;//退出保存书签: [, Q' Z6 W+ ]" U. J: [
- save_bookmark();
1 D" Y) F8 c: A$ n3 i% T1 J - }break;- p, n4 Q* f3 v5 }; B6 F
- * z7 A+ L$ i+ n' b; v% s1 ]
- case 2: if(txt_num-4*(menu_num-1)>=2){& e$ t" I% o* ?
- strcpy((char *)pname,(char *)txt_path_name[1+(menu_num-1)*4]);* @2 N6 K8 X; l2 V5 c; \
- " E0 r* b4 T3 x8 h
- page = bookmark[1+(menu_num-1)*4];
+ k9 G, Q/ w* k - if(page >= 0xffff)page=0;1 R' I" v6 m( v5 l2 O
- read_mode();//进入阅读模式
1 O1 j% B9 p5 ~+ F* \ - bookmark[1+(menu_num-1)*4] = page;
2 z2 M- f/ A7 b! n: |" z/ u - save_bookmark();
, ^) { N6 k3 N( h, _* \ - }break;
1 J t+ k' @$ n9 {7 | -
* F" }0 S8 m( J -
2 V6 z* `0 }& v$ S7 Q! F - case 3: if(txt_num-4*(menu_num-1)>=3){
8 {$ k! P# u1 _ _2 M' Z9 B - strcpy((char *)pname,(char *)txt_path_name[2+(menu_num-1)*4]);
! o! w2 U) n+ E1 _% g - % w8 D( E1 g+ t _9 ?, H/ N! x; ~9 v2 D
- page = bookmark[2+(menu_num-1)*4];( w' f' }: C. s1 y
- if(page >= 0xffff)page=0;
; J. G2 ?$ [9 [ h% p" p+ e' A - read_mode();//进入阅读模式
' n% |# G! t+ H# s7 @( V: C - bookmark[2+(menu_num-1)*4] = page;) |) c e1 f ^- ]2 k, l. m
- save_bookmark(); F. V4 p; A, M& R% E
- }break;7 {8 z' E- t" Q1 C1 b% S* ^
-
5 z8 Z5 |0 a( y9 Y1 q; J8 i$ c - case 4: if(txt_num-4*(menu_num-1)>=4){
+ o% ?* g5 T9 m - strcpy((char *)pname,(char *)txt_path_name[3+(menu_num-1)*4]);
! p6 W9 y8 f6 {) W1 j - , Y( l' L+ T3 N& i
- page = bookmark[3+(menu_num-1)*4];
) c3 ^2 `; ^+ o8 ]5 k' v - if(page >= 0xffff)page=0;
6 O1 k$ g) ^) M5 f! T- i' q - read_mode();//进入阅读模式 p& N! h+ Y3 @' e) v
- bookmark[3+(menu_num-1)*4] = page;2 x) c' V+ ^6 y# {, _) r* n% l: ]1 f
- save_bookmark();; y% K8 H: T& y. J' F! k" b" r0 f
- }break; o/ I/ t3 l3 B6 J$ q) v
! n5 g5 ^+ ?3 t- case 5: //导入图书/ x; ?8 R: g% c
- fatfs_choose();//文件系统选择文件导入
3 ?1 V; C7 @/ Q - save_bookinfo();//保存书籍数据到flash7 U( Z) s8 ]. |( z I
- printf("当前图书数量:%d\r",txt_num);0 f9 Y6 j+ k$ q
- break;9 z# P/ Q f" h! Y' H
-
& x. B- Z1 g5 |4 H: T - case 6: del_txt_ctrl();//删除图书
, Z Y2 q) h Z - break;! j8 @5 I& g* p/ {. z0 u7 z; ?
-
0 }. r/ c- x% N B- R' w - case 111: if((txt_num-1)/4+1>menu_num)menu_num++;& a2 ~; I( }# V& y7 }9 J7 h
- printf("menu_num = %d\n",menu_num);//上一页! C! |$ J$ [" y% V/ G ]4 Q
- break;
. P+ q) ]( w1 z! Q5 ] -
/ f; e7 x2 k9 u - case 222: if(1<menu_num)menu_num--;. s7 B1 V% R! }' _
- printf("menu_num = %d\n",menu_num);//下一页
' u3 G- Y$ P( S9 v - break; 7 r3 k" \' C1 j
- }
8 d" }5 {0 w, E/ T) V6 Z -
( z- A; Y5 U: ` - menu();//显示主界面
) H% H- u! Y. W* I% T- j I - data_offset=0;//偏移清零" k9 B+ h0 m5 E) k; U8 L7 ?5 l9 _
- page_mul_cnt=0;//1000页倍数清零( t) Q2 U* ]! e. E
- }! O3 |: t% u5 p& |6 I; B5 r t
- delay_ms(10);# P. w9 ^, U1 |0 {/ W
- }
1 R0 [2 \7 D9 o ]# V ]5 x+ R - }
) h0 A1 D/ b$ q }$ x4 W
复制代码 - ^$ U3 i A; r2 s; K0 T$ v
六、硬件框图; {/ W2 I4 w8 s* V1 @
$ @2 ^$ {. y0 J
$ P. j8 ?( P8 J" ^$ n& _
单片机通过SPI与外部FLASH进行连接通信,使用SDIO与SD卡连接,第一次上电的时候,程序会把SD卡中的字库文件数据读取并写入到外部FLASH中,使液晶屏可以用函数显示32、24、16、12号字体的汉字
3 ~$ r6 H) A6 \触摸屏作为人机交互输入,程序通过识别用户点击的屏幕坐标,控制液晶屏的各种显示
" y p/ Q% C" Y6 D3 h& c( v8 K( c& z+ i- {6 {
七、程序框图5 }7 J+ A" P& s1 B: m5 p
, |% J( Q# Y5 }; `( U9 J
# R! o6 o1 Q" H+ o$ J# v5 Y) y Q
: r: B4 ~/ C& x! B开机单片机会初始化各种接口,SDIO、SPI等,用于控制SD卡、FLASH,显示屏,第一次上电会识别外部FLASH中的字库是否完整,不完整会进行更新字库的操作,然后初始化图片库,配合SD卡驱动、显示SD卡中的图片,开机显示SD卡中的一张GIF格式的图片作为LOGO,然后进入主循环显示主界面,书架界面会显示4本书的位置,还有删除图书、导入图书等操作,系统会识别用户按下触摸屏的坐标进入相对应的函数,例如点击导入图书,会进入导入图书的函数,会调用程序的文件系统,读取SD卡中的文件,导入TXT文件就可以显示图片与书名到书架,删除图书会显示一个X的图片到已添加到书架的书籍上,点击即可删除内存中保存的书籍信息,从而在书架删除图书,然后点击书籍会进入读取书籍信息的函数中,程序根据书籍在SD卡中的文件路径,通过文件系统读取这个TXT文档的数据,并显示到屏幕。进入阅读模式后可以设置字体、背景颜色等,目录功能。- R) L" U- y8 K! ^7 j2 I, c
, d) X8 t% |: J" a7 k C
# b! d. E( S Y/ d4 i, P
) S! z8 v4 w+ @9 o# v. f8 X |