单片机毕设电子小说阅读器(STM32 LCD触屏)

一、电路设计

此电路由STM32最小系统板、800*480 4.3寸电容触摸LCD屏、一张32G以下的SD卡和一个读卡器组成。
项目偏软件,但是要依赖于自己对硬件的熟悉和驱动才能完成,用到的主要技术:
1)SD卡驱动(难–不过可移植 SD卡驱动细节可在用完再了解其驱动协议)
2)FatFs文件系统移植使用
3)LCD屏驱动(加载字库文件 做字库在LCD上的显示)

二、原理图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、部分代码



    #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;	 		//图片目录
    	u32 recode=0;
    	
    	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.
    
    	/******************防止二次烧入****************************/
    	W25QXX_Read((u8 *)&recode,1024*1024*4-4,4);//读出到内存
    	if(recode != 0xffaaffaa)
    	{
    		recode = 0xffaaffaa;
    		W25QXX_Write((u8 *)&recode,1024*1024*4-4,4);//写入flash
    		//W25QXX_Erase_Chip();//擦除整片
    		txt_num=0;//初始化小说本数0 不然程序无法运行 
    		save_bookinfo();//保存到flash
    	}
    	/******************防止二次烧入****************************/
    	
    	while(font_init()) 			//检查字库
    	{  
    		LCD_Clear(WHITE);		   	//清屏
     		POINT_COLOR=RED;			//设置字体为红色	   	   	  
    		LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
    		while(SD_Init())			//检测SD卡
    		{
    			LCD_ShowString(30,70,200,16,16,"SD Card Failed!");
    			delay_ms(200);
    			LCD_Fill(30,70,200+30,70+16,WHITE);
    			delay_ms(200);		    
    		}								 						    
    		LCD_ShowString(30,70,200,16,16,"SD Card OK");
    		LCD_ShowString(30,90,200,16,16,"Font Updating...");
    		key=update_font(20,110,16,"0:");//更新字库
    		while(key)//更新失败		
    		{			 		  
    			LCD_ShowString(30,110,200,16,16,"Font Update Failed!");
    			delay_ms(200);
    			LCD_Fill(20,110,200+20,110+16,WHITE);
    			delay_ms(200);		       
    		} 		  
    		LCD_ShowString(30,110,200,16,16,"Font Update Success!   ");
    		delay_ms(1500);	
    		LCD_Clear(WHITE);//清屏	       
    	}     
    
    	//f_opendir(&picdir;,"0:/SYSTEM/PICTURE"); //打开目录
    	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);
    	}
    }
    
    //阅读模式 进入阅读
    void read_mode(void)
    {
    	int key;
    	u8 res,n;
    	char spr_name[30];
    
    	sprintf((char *)spr_name,"%s",pname);
    	res=mf_open((char *)spr_name,FA_READ);//只读打开
    	if(res==FR_OK)printf("打开:%s\n",(char *)spr_name);
    	else return;//打开失败
    	
    	LCD_Clear(WHITE);//清屏
    	n=page/1000+1;//计算要更新几次
    	while(n--)
    	{
    		LCD_ShowNum(200,376,page/1000+1-n,2,24);//显示进度条
    		LCD_ShowChar(234,376,'/',24,0);
    		LCD_ShowNum(250,376,page/1000+1,2,24);
    		file_data_to_w25q();	//更新页数 一次1000页
    	}
    	mf_lseek(page_offset[page%1000]);//得到初始偏移
    	
    	read_to_lcd();//读取文档数据到屏幕
    	
    	Show_Str(420,770,200,24,"返回",24,0);
    	Show_Str(5,770,50,24,"设置",24,0);
    	Show_Str(218,770,50,24,"目录",24,0);
    	LCD_ShowNum(400,0,page,5,16);
    	
    	while(1)
    	{
    			key = get_ts_val(2);
    			if(key != 0)
    			{
    //				printf("key == %d\n",key);
    				switch(key)//操作选择
    				{
    					case 101:
    										page++;
    										if(page%1000==0 && page>0)
    										{
    											//更新缓冲页码数组
    											file_data_to_w25q();//先写入页码到flash
    											update_page_offset();//更新内存1000页页码
    										}
    										res=mf_lseek(page_offset[page%100]);
    										if(res==0)read_to_lcd();
    										break;//下一页
    					case 202:	
    										
    										if(page==0)
    										{
    											Show_Str(180,730,200,24,(u8*)"已经是第一页",24,0);
    											break;
    										}
    										page--;
    										if(page%999==0 && page>0)
    										{
    											update_page_offset();//更新内存1000页页码
    										}
    										res=mf_lseek(page_offset[page%1000]);
    										if(res==0)read_to_lcd();
    										break;//上一页
    					case 303:
    					case 404:break;
    					case 5: 
    									return;//保存数据到flash//返回 
    					case 6:
    								res=setting();
    								if(res)  //修改设置退出
    								{
    										res=0;
    										LCD_Clear(BACK_COLOR);//设置完还原界面
    										Show_Str(50,50,400,700,(u8 *)buff,SIZE,0); 
    								}else //返回退出 
    								{
    									LCD_Fill(0,570,480,800,BACK_COLOR);
    									Show_Str(50,50,400,700,(u8 *)buff,SIZE,0); 
    								}
    								break;
    					case 7:page=txt_dir_scan();//目录扫描 返回页数
    								
    								update_page_offset();//更新内存1000页页码
    								res=mf_lseek(page_offset[page%1000]);//偏移到页码
    								if(res==0)read_to_lcd();
    								break;
    				}
    				Show_Str(420,770,200,24,"返回",24,0);
    				Show_Str(5,770,50,24,"设置",24,0);
    				Show_Str(218,770,50,24,"目录",24,0);
    				LCD_ShowNum(400,0,page,5,16);
    				//printf("lseek=%ld\n",offset);
    			}
    	}
    }


​    

🔥 项目分享:

https://gitee.com/feifei1122/simulation-project

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值