你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32项目设计:基于STM32F4的电子阅读器制作教程

[复制链接]
STMCU小助手 发布时间:2022-8-15 19:42
一、项目功能要求
7 h3 e$ i% j- u+ u% m4 O6 y3 W项目说明:
2 E- K6 g# G- O; E/ @2 N0 G6 \项目偏软件,但是要依赖于自己对硬件的熟悉和驱动才能完成
* v  P' v/ A  b6 K# U" d$ o
用到的主要技术:2 a$ d# B( K1 e; R1 {* S
SD卡驱动(难–不过可移植 SD卡驱动细节可在用完再了解其驱动协议)
$ X7 g# j, l- f. GFatFs文件系统移植使用4 U# W" I& G& P& y, B
LCD屏驱动(加载字库文件 做字库在LCD上的显示)
4 @+ A! |8 u  [, E( q6 _' X
+ i/ V  U, ^7 ]$ x& r5 S
功能要求:6 g, w+ e4 h8 C) q; N, z1 N% J
开机Logo
2 M+ \# x- n" X0 v2 ^电子书列表扫描
; I: d; D4 _0 Q, y4 }电子书列表显示及小说选择菜单6 e0 ?+ {- J! W& R" i" A
阅读功能:
* i/ j0 ]2 m7 n字体选择& s% H+ i( s/ z) c4 m' j
字体大小选择
) m( F: ]* b! K/ z字体颜色设置) ~+ w0 B9 w" R9 Y& q# A
阅读背景设置
6 Y4 X' r' x8 @书签设置
6 d$ J( l+ s% _! V% g能够记录每本电子书的退出时处于什么阅读位置 下次进入从该位置继续阅读; _4 T4 M7 i+ ^3 r
目录生成功能(字符匹配)
+ K/ _6 {' x) c! B# X& L, D3 Y章节跳转功能(基于目录生成功能)
; U' ]% A" _2 s0 b. a$ i阅读翻页设置(滚动/切换)
; _6 E# V. R2 y
" w5 q; Z  n+ n) q! R
二、材料准备
8 H* c/ @. ~! |1、普中STM32F4ZGT6最小系统板一块(或者其他STM32F4板子)
: M+ n; g$ \% ]+ y( z6 \; N(注意要买能插LCD屏的)
3 d! @5 A1 X$ D' w" C作用:主控芯片、处理各种数据
0 }# Z% @" {$ L" U, l* @
+ V+ c- H4 q3 S$ b 4JD9F[NFX]UH}9G2CQAFARS.png 0 J  J  V) E  c0 |
1 h1 q7 g  h. J
2、800*480 4.3寸电容触摸LCD屏(我用的正点原子的屏)
4 F& [+ ]& Y+ v5 f: Y7 k作用:显示与触摸控制
! l6 `2 l3 q; Y) u: p7 j

8 U8 T- g' L" E! Z4 V- ]+ c. b

& ]1 g. x" f% w8 B, N; g UYQL2~X(IYQ4OZ`QQM)N38E.png
$ v8 x2 ]! S  M7 p6 r1 m
; Z; x. K8 ^) v3、一张32G以下的SD卡和一个读卡器
  u5 Y( ~6 B0 L* J3 [& S, G/ o& D1 I: c8 @
作用:存储小说文件与图片文件0 H. S5 W! ?6 F% r, i. M
  k9 e0 u4 ?0 Q: i
JN0_R81S2)T7@SX%]G4T[DF.png * q8 T" U4 `+ z$ j  w

1 G2 J* _2 B/ \( [$ A3 s二、硬件连接
  ?# D5 Y& h. M; c# B% E. |1、把屏幕插到开发板上即可# \! W- H& s& N1 F7 ^9 z

7 ]1 N) _6 b# J$ A0 y7 d三、相关知识点1 `; O. K9 ]) w; B2 K
(一)、txt文件数据的读取+ e  b8 K  l  l
. a. t2 S) U' V% k5 I9 d0 F
1、谈谈txt文件- X4 W1 O& F% t. ^  \% w
8 ?; w7 y$ Z4 |. {7 y  e* a' o8 ^$ j
学过C语言的文件IO都知道,用open函数打开后,用read函数读取的第一个字节开始就是文本内容,txt文件是文档文件,对于我们程序员来说文档文件是最容易操作的文件类型之一,因为它不像图片那样还需要考虑头部的一大堆信息8 _1 a; c- f+ `

1 ~2 w8 F% }& u& h: y& J2、读取txt文件数据
* C  X2 a1 j* n- w
7 }% X; X4 z3 @2 c* T利用FATFS文件系统提供的函数f_open 、f_read即可对数据进行读取出来,当然读取出来的都是文字的编码,可以先用串口函数打印出来看看数据对不对 printf("%s\r\n",buf);
3 F: \' q1 G- |2 C/ ?5 q. W
; f, _0 C6 c6 K& _; l(二)汉字的显示(具体代码参考正点原子“汉字显示实验”)) _0 \3 g: a4 l
2 G; B8 F9 U3 d0 t
1、汉字的显示原理4 [/ g; D7 Y, }+ j) ^% s% w  q
0 ]! t3 w7 @! [
1)学习过屏幕驱动的应该都知道,屏幕的显示无非就是在屏幕上打相应颜色的点,比如要显示一个字符 ‘A’ 那么我只需要知道 ‘A’ 相应的点阵数据就可以把它显示出来,汉字也一样。
0 j, G$ j) q8 W1 S. Z9 r+ s" H% @% e+ K
2、汉字库的存储
" X$ D6 l1 I$ `5 h9 T" G) K) h, z* }( \# I+ \% _; r- a
2)但是汉字与字符不同的是,汉字有1万多个,字符却只有100多个,并且汉字的显示明显比字符的点阵复杂程度高,比如说字体是12的字符占用点阵是12x6,每个字符需要12x6/8=9个字节的存储空间。字体是12 的汉字占用12x12的点阵,每个汉字需要12x12/8=18个字节存储空间,这还是最小字体,大的字体所需要的存储空间只会成倍增加) t8 s6 L3 ?) P
# I) h- b  k$ T; A" v7 x! @, l- P
3)一般12号字体的汉字库需要500K字节、16号字体700K、24号字体1.6M、32号字体3M,这对于单片机来说数据量太大了,内部FLASH512K~1M表示压力很大
2 b: x0 M  ^0 w9 U# D% v

* T: t) F9 V. O( r% h1 C8 a

+ B( W  U) V" ^ 20201217162029866.png - b" }- @2 N9 E. F) M
  j9 A" P  v) k8 e8 P
4)需要把汉字库通过SD卡再保存到外部FILASH才行,w25q128无疑是个好选择,它拥有16M的存储空间,SPI通信协议,读写速度也是相当快。
% b# W+ P5 M: d, Q7 Y5 j
+ M* E5 E! @8 U- i(三)txt文件数据显示到MCU屏$ s8 U& k- O, e9 b' J# l
) l) z5 Z1 @9 \, a+ \
1、数据编码格式的问题% B0 L2 R0 b9 W. S/ k

1 P* D3 Z2 q3 t7 W1 \有关显示汉字就必然会涉及编码格式的问题,不同的编码格式对应的汉字编码是不同的,比如UTF-8编码的文件用GB2312编码打开就会乱码。- I& C! E8 M) d/ Q% |& P
同理,比如文档的格式是UTF-8编码,但是我的字库是GBK编码,读出来的数据直接显示到屏幕就必然会乱码) F$ {3 `8 d7 [" F: S: z
1 [! [' `$ _7 O
四、下载调试2 u1 J* F: f4 O1 P  c1 j

% n5 Y8 a$ P/ ~1 `4 u1、SD卡根目录文件拷贝/ y8 j' R" J! ^$ W6 g( p
, r2 X) ~# p, O1 Z# S4 l. E, u
下载好本博客配套资料,把下面两个文件夹拷贝到SD卡根目录下
! Y; ]  {+ Y/ u' f
- v9 D3 q  n/ }/ l  q( l

$ }8 s% \* K, D8 B5 @3 E 2020120719291362.png 3 Z4 [2 l+ W8 {2 M
+ l9 G$ I* V2 t
()一定要是根目录,不然不能正常运行

+ H+ y0 [/ _7 L  \4 t2 r+ o& O& E9 ]/ d$ N% u
2、初始化外部FLASH -W25Q128
9 N/ n, @( A7 u/ }' I# N用keil打开代码工程,编译通过后下载
' k6 j3 X- X+ H% i下载完成等待外部FLASH -W25Q128初始化完成,一开始会黑屏一段时间,是在擦除FLASH,然后会提示字库加载进度,直到LCD显示阅读界面为止

. X9 j: e, y( m' y  a' J
8 }% B! z& }/ F. q0 M) t; J

0 H; O5 a( h' z+ s 3}D6J3X%~W7WDI[ZHJ{D`XP.png
/ V: f& J' X! y# k! J1 k
: e' u" y- l' ?, D如果下载代码后运行不正常:, X' M7 N4 J; U0 p
1)注释掉这些代码,编译下载

" s  Q3 u6 x0 Y9 A! @1 `/ _: d9 A
0 T3 h% j( I3 t/ z
4 A3 y$ c% Z' \9 s+ Q
8BA9(4R~RG8}BJ`EIB%N@6K.png
) r/ Y* H2 [+ W$ b. t6 u  T, @# T7 ^0 T& q& }' S9 F
2)不要断电,取消注释这段代码,编译下载,下载完成后W25Q128初始化完成,应该就可以运行

; T6 M' _& C3 H
- x& y, \  [& B3 i

4 e1 w/ d. j; b$ \ 20201217154828284.png
/ W0 t: A. [! n' Q# V/ Y% O/ N$ J& X# f5 N1 o( b; |! p
3、化作尘动态logo

) q# \% u8 c: K. A& v' B9 [! x" t) L, g8 \
4、进入主界面
; s: z! D" g# D9 u3 E啥都没有,先导入图书" r( K+ T! J4 V8 {5 z# K$ X# v- V
图书要从SD卡中导入,txt文件在资料里已经打包好了,直接导入  ^  V% G6 U# |, P

# {2 O; e% b6 v" y- S7 U' v* G5、导入图书( f$ a2 j/ B3 t6 _
找到0:/TXT目录下的.txt文件,选择导入
/ t3 q1 Z* Q+ R% P2 d& G3 n" G
; \6 d0 y! s  _& k, a& `导入“斗罗大陆.txt”,主界面开始显示
/ ^1 G; i5 |6 d- O& Y3 J& U图片是系统自动匹配,检测是否有与小说同名图片文件,比如“斗罗大陆.txt” 对应 “斗罗大陆.jpg”2 \: X# G1 c* Y% g
) y! v1 E9 a& F' X
如果没有匹配图片会显示默认图片, _; f# a9 J" M, u9 [( A9 k; ^
: h$ Z& H/ N( _& E( @3 b
6、删除图书. [2 ~' Q. G7 ?( m/ T# K
点击左下角删除图书,再点击 X 即可移除图书操作,只是移除,并不是真正删除。
+ z6 O+ }- R: g$ B9 m0 r- E  _4 s) P) c) Q: A
3 K7 I0 B" u8 }- r; G
7、阅读界面; |0 u+ P# |3 }
阅读界面都是根据页数匹配相应文字,因为读写速度问题加上需要算法识别加载,翻页加载过程都会有一段时间" p9 O/ L8 J8 P

5 g$ N/ X5 r, B* t- B9 S0 D3 L) n  i" |& }0 _' \) F2 K# g
8、目录功能- m' e8 W8 X3 h0 B
自动检测目录,通过检测“第” 与 “章”加上相应算法就可以检测显示目录,并记录偏移,可以跳转,上划可以显示下一页目录' F: ]) y3 K$ R* Y8 P

6 n# Z2 K% _, P& k9 b  T1 j9、设置字体、背景2 n0 [0 n9 R6 A3 z% W
可以设置显示背景,字体颜色,字体大小来适应自己喜欢的阅读方式
8 b1 K# }, y0 y# e$ ^1)24号字体 、白天
! F+ ?+ |  O. G. L- g& w
2 o, [! z( ~/ t3 z7 K% n: k  ^# o$ e2)24号字体、护眼1 c' f5 N1 ?- `3 M* d5 n( Z
  `# e$ ^7 z  t0 ?
3)12号字体、护眼
" j" k  o" q  Z: j# P& p
0 E* L( Y2 }1 h. l
+ _* z5 w# s/ \! _' w3)24号字体、夜间
# @! T  u) {9 T, e1 L! F) j1 ]3 v6 U3 W' E) w! D" m$ @
3 c9 T9 C! X. F1 M; f* J: L8 d
五、程序设计
3 n$ w! m& r8 f) v, I+ U$ c/ P代码过长,只展示部分代码:
! R! `' L4 u* \

- A$ [! T: m$ \  m6 n
  1. #include "sys.h"
    ; ~% N1 ^, B9 C9 T6 e
  2. #include "delay.h"
    7 b- n; d2 T! S
  3. #include "usart.h"/ B$ m# @) @! g5 d
  4. #include "led.h"7 A1 Y& L/ O% N; E8 f
  5. #include "lcd.h"# x0 H8 p/ i$ }" P0 c3 W# B
  6. #include "key.h"  , S$ h* D* {- _2 p' l
  7. #include "sram.h"   
    / |6 ~  z9 F, q+ h' [9 ]# N
  8. #include "malloc.h"
    8 x( f; p! L! I2 |' @: a
  9. #include "usmart.h"  
    ) P; X5 j& n, l" {
  10. #include "sdio_sdcard.h"   
    # r* N7 }9 _/ ~! w/ r" x) d6 \7 K' y
  11. #include "malloc.h"
    9 Y- V. l! H, |8 t( J
  12. #include "w25qxx.h"   
    8 \# p' I% z  n" C# j, Y' Y* r
  13. #include "ff.h"  & B) U7 C% }; Z6 X
  14. #include "exfuns.h"    ( {& X1 a! g# {4 B" d% ^& v3 M) i
  15. #include "fontupd.h"
    ) E, A2 E, Y$ I$ f* [( o
  16. #include "text.h"         
    # ^: c7 G) ~+ n4 P6 `9 g1 s
  17. #include "piclib.h"        
    ; G3 S, Y( z! i( a' ~; W
  18. #include "string.h"        % ~+ x) z! q! Y; ?( r
  19. #include "math.h"        , f. l; s( I* k0 o- K6 D/ M" h% D2 P
  20. #include "touch.h"
    5 f7 T  X1 A9 ^$ X- A
  21. 3 W# u* O4 q9 g# b( H# ^4 y/ v8 C
  22. u8 menu_num;//当前主菜单页数. ]* _  K/ u) s$ V6 T* H
  23. u32 page;//当前页数
    . m# V7 D* P- U
  24. //char chapter_name[50];//当前章节名
    : f, _4 f7 v& S* `4 R, u! ^3 W9 Y
  25. u32 page_offset[1000];//保存页数偏移
    , V# [, Q* i2 \" p
  26. //u32 page_off_mult;//页数偏移倍数
      W. E6 ]8 z- N$ O4 X* [! J
  27. u8 txt_num;//当前书架图书数量
    " h  A/ p% z$ C- Q& o
  28. u8 txt_path_name[30][60];//导入图书路径
    . Y* S' A) Q6 X  i" a+ {
  29. u32 bookmark[30];                                //保存对应书签 也就是页数 下次进入直接偏移页数
    7 b  Y, Y" P) `) C. ?& j  X
  30. char txt_name[4][30]={"","","",""};//显示4本图书名字
    # I1 r0 j4 B: U" z! {6 r# t
  31. u8 pname[60];                        //正在打开的文件名路径, D- u3 `/ Y5 `4 ?# Z
  32. int SIZE=24;                        //初始化字体
    3 t- o) ~. |+ s; @, e0 u# g3 d! J
  33. char buff[2500];//一页数据 缓冲文档
    6 r6 ]$ i% n$ {2 ]$ n
  34. int page_mul_cnt=0;//存取次数 一次1000页
    + |5 L3 A2 q( M
  35. int now_page_mul;//当前1000页的倍数* o) C$ y$ S: x* O2 m& w
  36. u32 data_offset;//读取偏移  读写flash用
    ) p& x9 k7 e2 y' g9 c6 h  J

  37. 2 ]% [5 K& ?) t
  38. # V8 M: N/ ~- _* u/ w1 y
  39. //显示主界面8 o! Z+ P# d* ~9 z5 F! h  h
  40. void menu(void);& G$ _- a/ N) ?9 y$ R& m% C
  41. //获取触摸键值! M) a' i4 h1 ?% J; D
  42. u16 get_ts_val(int key);0 B$ {5 Y" V0 N( |/ F5 @: N( q
  43. //读取文件数据到LCD) u+ r8 ~& A$ T2 j8 V6 B" j
  44. int read_to_lcd(void);
    6 g! |4 a  D+ b) Y6 N
  45. //更新小说名# f0 p2 [- ~8 m+ l1 z- N7 x  s
  46. u8 lcd_dis_files(u8 * path);4 y9 K4 E5 @' ?
  47. //阅读模式0 j* m, v3 C2 T4 M3 d3 n7 Q
  48. void read_mode(void);
    9 p* @: c8 C* d/ m9 G) v6 t* W4 Z
  49. //设置字体格式
    - k: C. Y" Q3 L  i# m
  50. int setting(void);7 y  n6 h0 t$ s$ C9 A; ]2 {
  51. //设置界面
    8 p! b5 m. h1 C# Z/ \
  52. void show_setting(void);! H5 G; t; Y3 y6 W: H7 o. M) \
  53. //目录功能
    , @0 w  N/ f$ u
  54. u32 txt_dir_scan(void);
    : {5 T' P$ T# ]* R( }9 Q5 V; r
  55. //文件系统功能 导入小说
    - j0 H, u: W; i0 g+ ~
  56. void fatfs_choose(void);
    ( }  e& t4 A% w) L0 T1 Q
  57. //读取数据到flash
    3 o- ?9 g( M; ]- j) B3 j6 j
  58. void file_data_to_w25q(void);+ w- ^2 X7 `( q0 h" W
  59. //根据页码得到页数" g$ G; _+ J) I# Y- W; t8 f
  60. u32 ident_get_page(u32 page_offset);. P) \! \9 }6 r, ^+ m5 |4 l
  61. //遍历文件 显示到屏幕4 i6 O: e; C8 f9 ~
  62. u8 mf_scan_file(u8 * path);5 n$ @7 Q+ }( n
  63. //刷新显示书架名字
    6 R% g; O- e& }; S) d% @
  64. void re_dis_txtname(int i);0 J7 x' ^8 Z. u/ A7 e' c
  65. //带路径的文件名 转 不带路径文件名
      Q& B. ]* e  H
  66. char* path_change(char *oldpath);! T$ a8 e3 O. ~# N3 v% w
  67. //根据页数得到页码+ Y) h' `! d& {. M( t2 v# `
  68. u32 ident_get_offset(u32 page);0 i6 i8 C- b  r( c8 P
  69. //更新内存1000页页码
    4 Y4 a0 G: u& J, }  J. J8 y, p
  70. void update_page_offset(void);. x( k  `4 }/ h& A7 T  ~
  71. //读出书签数据) a. k; v: [* d' F
  72. void read_bookmark(void);
    2 R3 K3 I; I; t+ G% E# {5 W
  73. //保存书签数据到flash, y3 Z  R! q  R1 J. C
  74. void save_bookmark(void);
      x6 D. V! W7 i: I3 t
  75. //保存书名数据到flash
    % I4 j5 {$ q$ B" M3 j) V- s
  76. void save_bookinfo(void);
    : Q! f' W+ C" x4 P! m
  77. //删除小说$ j2 w& u& g. u0 m$ |
  78. void del_txt(u8 *path);
    5 `' S# [, N9 p# k* n7 A5 `# z
  79. //删除小说控制界面
    , U5 _; r1 F1 M* s: h! z5 _
  80. void del_txt_ctrl(void);
    ( P- d! l( e$ C- Z7 j6 N
  81.         
    4 u* B, m/ U2 H9 J( p- {) L+ E

  82.   e% g& z' G1 v5 I3 Q

  83. 5 L5 e* M4 _! ]  c  s

  84. - w' E* o& M" ^+ v1 h
  85. int main(void)
    % u# M, r$ `# f. N: f
  86. {        
    2 S* m, P* f8 W8 q% N1 e
  87.          DIR picdir;                         //图片目录
    4 m. q/ }9 a: d: W
  88.          9 [* c! m3 X3 `
  89.         u8 key;
    " O) u6 q% r' c8 k  [( q) o, K
  90.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组26 n3 a9 ^* D/ X' p7 G4 |
  91.         delay_init(168);  //初始化延时函数: D0 J- c* y( p/ Z. Q
  92.         uart_init(115200);                //初始化串口波特率为115200
    ; z4 O% I+ u9 \6 p1 |: Z' F% m
  93.         LED_Init();                                        //初始化LED  
    - {8 T  z' ~4 p2 K
  94.          LCD_Init();                                        //LCD初始化  ! x* \" l" _7 |4 h) R: s+ \
  95.          KEY_Init();                                        //按键初始化
    $ e5 N& t: h- F; \- h4 I- b3 f
  96.         tp_dev.init();                        //触摸初始化        
    , e  X" L. a* G' L  n/ e  t* x
  97.         W25QXX_Init();                                //初始化W25Q128
    9 D2 s" f1 [+ |+ D
  98.         usmart_dev.init(168);                //初始化USMART/ V; b0 ?4 ]. {7 T6 M
  99.         my_mem_init(SRAMIN);                //初始化内部内存池
    . q& E! F! T9 @2 [  Q9 c1 R; H
  100.         my_mem_init(SRAMCCM);                //初始化CCM内存池
    0 E, m4 w0 Q; c5 k: W
  101.         exfuns_init();                                //为fatfs相关变量申请内存  7 I" o2 s3 Y. E# f$ W1 m  {
  102.          f_mount(fs[0],"0:",1);                 //挂载SD卡
    5 R5 }% S% L/ _) T7 e2 v! j* @
  103.          f_mount(fs[1],"1:",1);                 //挂载FLASH.
    8 r8 M0 F5 W1 T

  104. 8 F1 e( {$ C+ L& J
  105.         while(font_init());                        //检查字库
    % a7 w6 b9 L1 U0 s8 a
  106.         * W) c2 B6 E# b" _. q( W
  107.         delay_ms(150);: ?6 W8 G" y; f# \) O. z# \
  108.         piclib_init();                                                                                //初始化画图         
    * A2 R( V3 F) v# }
  109.         delay_ms(150);7 Y( G* G, [$ K1 m3 |* f
  110.         LCD_Clear(GBLUE);//清屏
    ' z6 {6 t) x# S: v  z
  111.         ai_load_picfile("0:/SYSTEM/PICTURE/logo.gif",0,0,lcddev.width,lcddev.height,1);//显示图5 Y; d* M: R; i' f
  112.         read_bookmark();//读出图书 书签数据% P' x" D& Q) {+ E* g
  113.         memset(page_offset,0,1000*4);//清空页码数组
    7 A' m+ v) L" R( `3 y) K6 Z
  114.         menu_num=1;//显示第一页
    ! h6 T/ S& Y9 n9 k
  115.         //lcd_dis_files("0:/TXT");//更新系统书名
    . L. s. \! D5 l) k/ @: P
  116.         menu();//显示主界面
    9 ]8 a, l; H4 y" o" L! [
  117.         while(1)
    : {( O+ x% D' I1 j! k8 i% y5 |4 c9 s
  118.         {
    4 \8 a; T6 G( U/ B8 [6 K6 D, Q- z
  119.                 key = get_ts_val(1);0 B& n  b/ c1 j- B- L4 k  U
  120.                 if(key!=0)
    ! D9 x& g, K3 ^& H
  121.                 {
    : b) \1 W( E' Y! Y: d
  122.                         printf("key=%d\n",key);- @4 J' s8 i, A+ j$ p% v. ?  {
  123.                         switch(key)//选择要打开的图书  _; m) z3 l/ X' _7 y! y
  124.                         {
    1 \; M9 [! b$ r, m2 [5 {
  125.                                 case 1: if(txt_num-4*(menu_num-1)>=1){) V$ Y$ i2 e9 J$ V
  126.                                                                         strcpy((char *)pname,(char *)txt_path_name[0+(menu_num-1)*4]);//把要打开的书籍名称赋值
    ( U3 k) o( `+ @9 v
  127.                                         " ]7 l. O/ D( z& t1 p
  128.                                                                         page = bookmark[0+(menu_num-1)*4];//根据flash保存的书签初始化进入的页数
    2 {8 q: K* M! s+ B
  129.                                                                         if(page >= 0xffff)page=0;) x: Q5 v/ H8 B5 @
  130.                                                                                 read_mode();//进入阅读模式- u! D: _& l. T2 R; R6 ^$ \7 l# L
  131.                                                                         bookmark[0+(menu_num-1)*4] = page;//退出保存书签  X7 Q' Z# F  |
  132.                                                                         save_bookmark();
    4 Z1 ~" @  u0 e$ K: A' p/ c6 R
  133.                                                                         }break;
    8 o/ w1 t2 c& Q
  134.                                 $ m1 O4 T5 v0 {# M7 B1 O* w2 O
  135.                                 case 2:        if(txt_num-4*(menu_num-1)>=2){& H2 J8 B5 |9 H1 @2 }+ W
  136.                                                                         strcpy((char *)pname,(char *)txt_path_name[1+(menu_num-1)*4]);* D; q% w' q$ R# b! H* R( v
  137.                                         ; i( t3 j/ F8 J& J2 |
  138.                                                                         page = bookmark[1+(menu_num-1)*4];
    " e& ]& K2 I) L7 n( z) ?
  139.                                                                         if(page >= 0xffff)page=0;8 A# r$ V# d* O: x% u: r( M
  140.                                                                         read_mode();//进入阅读模式
    # e2 D3 h* l  V  a& T
  141.                                                                         bookmark[1+(menu_num-1)*4] = page;3 I2 ^$ b! I3 R
  142.                                                                         save_bookmark();
    4 X" Z/ w+ Z3 z" P
  143.                                                                         }break;; f2 k" _0 c7 L  c, J- {( c% g9 Y% a
  144.                                                                         
    5 J7 Q; ^) a' S# c4 g- Y
  145.                                                                         
    " q2 ~. i% L6 Q7 c' ?
  146.                                 case 3: if(txt_num-4*(menu_num-1)>=3){7 b+ I" n% e$ K
  147.                                                                         strcpy((char *)pname,(char *)txt_path_name[2+(menu_num-1)*4]);
    $ l' c5 @" K( x: I" E9 T; L; w
  148.                                        
    3 \; ~. y* v3 c2 r# ?6 d" E9 W$ Y9 m
  149.                                                                         page = bookmark[2+(menu_num-1)*4];
    : @0 i$ Y5 h1 y- l& B8 ^
  150.                                                                         if(page >= 0xffff)page=0;  J! A4 \# H' k, F
  151.                                                                         read_mode();//进入阅读模式5 q4 c4 k: p& A; m( k
  152.                                                                         bookmark[2+(menu_num-1)*4] = page;1 I2 N% W5 f" }+ n4 q& U0 t7 b
  153.                                                                         save_bookmark();
    8 g% o3 u& U) T! K+ g# A
  154.                                                                         }break;
    4 c6 l% |5 ]* N4 l6 e+ O
  155.                                                                           F. V' E" B1 q* k* P: _5 v
  156.                                 case 4: if(txt_num-4*(menu_num-1)>=4){
    6 `, {; g/ d# X3 Z6 j3 ?( ]
  157.                                                                         strcpy((char *)pname,(char *)txt_path_name[3+(menu_num-1)*4]);
    ! ~% x/ c. s8 y$ j/ c
  158.                                         $ A, r) S6 ~3 J) V! z  _! w7 W6 H% x
  159.                                                                         page = bookmark[3+(menu_num-1)*4];9 A3 [: W. t% t
  160.                                                                         if(page >= 0xffff)page=0;
    . b/ C$ r3 d6 k) O5 A
  161.                                                                         read_mode();//进入阅读模式: n0 r5 u  c6 a
  162.                                                                         bookmark[3+(menu_num-1)*4] = page;1 d+ P$ T, Q6 K3 O; Q
  163.                                                                         save_bookmark();: b/ c4 D* J5 g" k  Z
  164.                                                                         }break;/ ?; q9 g: U2 j

  165. 2 h% X8 F) |9 s9 p. U. H
  166.                                 case 5:                //导入图书
    & L9 h$ b+ E, C' e8 [' G9 s
  167.                                                                         fatfs_choose();//文件系统选择文件导入
    & }! s! M1 \) M  \  C' D+ f$ L
  168.                                                                         save_bookinfo();//保存书籍数据到flash
    & O+ R: ]1 k. p
  169.                                                                         printf("当前图书数量:%d\r",txt_num);3 C% j- s  `! i$ _! B8 ~! a
  170.                                                                         break;
    : f& |6 Y2 h- }. a4 \3 g
  171.                                 
    1 h( G8 g2 k, q7 q0 M& U: _
  172.                                 case 6:                del_txt_ctrl();//删除图书
    - O# j( @' j& |' K& n) g6 n4 h
  173.                                                                         break;
    " \1 ^) u: Q0 L' m, m5 i
  174.                                 , h2 C6 n8 F1 d. X/ v# {, c1 A
  175.                                 case 111: if((txt_num-1)/4+1>menu_num)menu_num++;: E6 I- i; F8 f. Y  P
  176.                                                                                 printf("menu_num = %d\n",menu_num);//上一页
    9 {+ |+ v9 q1 }. _* x5 c
  177.                                                                         break;: h* e  |- H1 }. X  T" b  G
  178.                                 
    ; f8 v. Z) @* a( k: U
  179.                                 case 222: if(1<menu_num)menu_num--;, t1 {4 P4 G* n/ o% L6 B4 ]
  180.                                                                                 printf("menu_num = %d\n",menu_num);//下一页5 Z8 G$ N) l+ E6 R3 ?
  181.                                                                         break;        # g% [, }. |3 h0 k% P+ I5 o
  182.                         }
    # r0 l, `; u- l  f
  183.                         
    4 ?3 U  K2 e( U6 d/ v; P% L' U0 C6 Q
  184.                         menu();//显示主界面
    ; ~$ ]' |& d* S1 z* }9 K3 w2 u# W7 M' j
  185.                         data_offset=0;//偏移清零) O$ @3 o4 G* s& w! k9 x5 Q' `* ?
  186.                         page_mul_cnt=0;//1000页倍数清零
    7 t/ V' ]" G& Z& R& ~4 V/ p, u$ ]/ H
  187.                 }
    * s/ M: F/ ?% {0 D8 i( x6 g; `
  188.                 delay_ms(10);' k8 a6 e4 w/ j+ N+ I1 J& Z5 a4 o
  189.         }
    % d1 F5 @! V! s6 ]* S  r
  190. }
    * N0 d& p7 i) P: j7 i
复制代码
7 b# w; `% y% U2 L; e' p
六、硬件框图+ d1 R( o' }& G- S
. x7 F- t0 i4 Z( B; [
f4eb57ecfb5a4b5283e54dddf8c1c3be.png 6 n6 Y- M0 M/ B/ N! N, ]0 P
单片机通过SPI与外部FLASH进行连接通信,使用SDIO与SD卡连接,第一次上电的时候,程序会把SD卡中的字库文件数据读取并写入到外部FLASH中,使液晶屏可以用函数显示32、24、16、12号字体的汉字
9 ~2 v3 B4 l3 {% L2 {2 v) U触摸屏作为人机交互输入,程序通过识别用户点击的屏幕坐标,控制液晶屏的各种显示
/ x5 A+ V+ Q. R, v: R  r8 S' A7 t$ K* T. n1 R
七、程序框图
5 I; ?, c/ H6 U+ ?
* c. b+ N  V. e
ce916629c9dc436fbf5cec5c7c084e3d.png
$ T: J" F; I; R0 [
& U9 {$ }2 e# D6 ]  M7 G开机单片机会初始化各种接口,SDIO、SPI等,用于控制SD卡、FLASH,显示屏,第一次上电会识别外部FLASH中的字库是否完整,不完整会进行更新字库的操作,然后初始化图片库,配合SD卡驱动、显示SD卡中的图片,开机显示SD卡中的一张GIF格式的图片作为LOGO,然后进入主循环显示主界面,书架界面会显示4本书的位置,还有删除图书、导入图书等操作,系统会识别用户按下触摸屏的坐标进入相对应的函数,例如点击导入图书,会进入导入图书的函数,会调用程序的文件系统,读取SD卡中的文件,导入TXT文件就可以显示图片与书名到书架,删除图书会显示一个X的图片到已添加到书架的书籍上,点
击即可删除内存中保存的书籍信息,从而在书架删除图书,然后点击书籍会进入读取书籍信息的函数中,程序根据书籍在SD卡中的文件路径,通过文件系统读取这个TXT文档的数据,并显示到屏幕。进入阅读模式后可以设置字体、背景颜色等,目录功能。
0 v7 ?1 d( M+ r% A9 \' X, M8 b# a, o+ l) ]
6 [/ g: y" s" D2 V7 }

( D+ B' V: }5 y5 N5 v
收藏 评论0 发布时间:2022-8-15 19:42

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版