一、环境介绍
小车主控MCU: STM32F103ZET6
STM32程序开发IDE: keil5
STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植
硬件包含:一块STM32F103ZET6系统板、一个2.8寸TFT电阻触摸显示屏、一个SD卡卡槽(SPI接口)、一张SD卡(存放字库和小说文件)
二、功能介绍
这是基于ST32F103ZET6设计的小说阅读器,虽然对于真实的小说阅读器产品来讲,实用性和功能方面还差很多,但是对于刚入门的STM32、单片机开发工程师来讲,这里面设计到的技术才是最有价值的。
所以这篇文章的小说阅读器主要是用来作为嵌入式单片机工程师入门练手项目、大学生的课程设计等。目的不在于小说阅读器,而是以小说阅读器为例子,学习相关的技术: SD卡、串口通信、SPI通信、8080时序、触摸屏校准原理、FATFS文件系统使用、语音播报模块使用等等。
该阅读器支持常规阅小说读器具备的基本功能:
1. 支持选择指定的小说进行查看阅读,可以通过触摸屏上的按钮进行切换。
2. 支持切换字体大小
3. 支持切换字体颜色、背景颜色
4. 标题栏显示当前阅读器查看的小说文件名称
5. 支持翻页、上一页、下一页
6. 支持语音自动阅读,发声接近正常真人发声,非常强大。
语音方案可以选择两种: (1).宇音SYN6658 (2). 科大讯飞SYN5152。 这两款芯片都是通过串口通信,编程十分简单。
内部编程思路介绍:
小说阅读器的字体是存放在SD卡上的,SD卡采用SPI接口的卡槽与STM32相连接,STM32配合FATFS文件系统对SD卡上的文件进行操作;为了提高访问效率、在第一次上电的时候会将SD卡上的字库文件拷贝到板载W25Q64芯片内。小说文件还是存放在SD卡上,每次翻页的时候从SD卡上获取文本文件,渲染到LCD显示屏上。
该显示屏是2.8寸的电阻触摸显示屏,驱动芯片是ILI9341(兼容:9325,9328),LCD的引脚接线兼容正点原子的2.8寸LCD显示屏;电阻屏的驱动芯片是XPT2046,,是很常见的组合,这个XPT2046就是个ADC芯片,最终要完成触摸屏上坐标点定位,还需要自己写校准算法进行换算。 ILI9341驱动芯片支持8080时序操作,可以采用IO模拟方式驱动、也可以采用STM32的FSMC接口驱动。 STM32增强版支持FSMC功能的,其他没有FSMC接口的芯片,可以采用模拟8080时序方式驱动,效果一样,只是效率上差点,无法实现高速刷屏,只要不进行高速刷屏,凑合使用是没什么问题的。
三、所用到的硬件介绍(都是淘宝买的)
3.1 STM32F103ZET6最小系统板
这是在淘宝上买的硬件详情,开发板和LCD用哪一款都可以的,编程思路都是一样。
开发板的板载资源如下:
CPU:STM32F103ZET6,LQFP144,FLASH:512K,SRAM:64K;
外扩SPI FLASH:W25Q32,8M字节;
1个电源指示灯;
2个状态指示灯;
一个EEPROM芯片,24C02,容量256字节(注意:不同产地标号不一,但都是24C02芯片,经测试无误)
1个光敏传感器;
1个无线模块接口,可接NRF24L01/RFID/CC01模块;
1路CAN接口,采用TJA1050芯片;
1路485接口,采用SP485芯片;
1个标准的2.4/2.8/3.5/4.3/7寸LCD接口,支持触摸屏;
一个USB串口,可用于程序下载和代码调试(USMART调试);
1个USB SLAVE接口,用于USB通信;
1个复位按键;
2个独立按键;
1个SD卡座,用来接SD卡;
1个RTC后备电池座;
1个标准的JTAG/SWD仿真下载调试接口;
1路5V转3.3V电路;
芯片引脚144个脚全部引出,方便外接扩展实验;
1个电源开关,用来开关USB的电源;
3.2 SD卡卡槽
3.3 SYN6658语音合成芯片
功能特点:
• 芯片支持任意中文文本的合成,可以采用GB2312、GBK、BIG5 和Unicode 四种编码方式;
• 芯片具有文本智能分析处理功能,对常见的数值、电话号码、时间日期、度量衡符号等格式的文本;
• 芯片可以自动对文本进行分析,判别文本中多音字的读法并合成正确的读音;
• 芯片可实现10级数字音量控制,音量更大,更广;
• 芯片内集成了77首声音提示音和14首和弦音乐;
• 提供两男、两女、一个效果器和一个女童声共6个中文发音人;
• 支持多种文本控制标记,提升文本处理的正确率;
• 支持多种控制命令,包括:合成、停止、暂停合成、继续合成、改变波特率等;
• 支持多种方式查询芯片的工作状态;
• 两种通讯模式:芯片支持UART、SPI两种通讯方式;
• 芯片支持Power Down 模式。使用控制命令可以使芯片进入Power Down 模式;
• 芯片支持的通讯波特率:4800bps,9600bps,57600bps、115200bps;
• 芯片各项指标均满足室外严酷环境下的应用;
应用范围:
• 车载信息终端语音播报,车载调度,车载导航
• 停车场收费系统/诱导系统
• 公交报站器 ,考勤机
• 手机,固定电话
• 排队叫号机,收银收费机
• 自动售货机,信息机, POS 机
• 智能仪器仪表 ,气象预警机,智能变压器
• 智能玩具,智能手表
• 电动自行车
• 语音电子书,彩屏故事书,语音电子词典,语音电子导游
• 短消息播放 ,新闻播放
• 电子地图
四、操作说明
4.1 程序下载
开发板支持Jlink下载、也支持串口下载。
4.2屏幕操作说明
目前实现的功能:
1. 小说翻页:支持点击触摸屏按钮翻下一页显示
2. 换小说:点击触摸屏按钮“下一本”,可以切换小说。
3. 换颜色:点击触摸屏按钮“颜色调整”,可以切换颜色,支持12种字体颜色切换。
4. 换字体:点击触摸屏按钮“字体调整”,可以切换字体,目前支持两种字体(16X16 24X24)。
思路说明:
程序里移植了FATFS文件系统,字体文件和小说文件都是存放在SD卡,通过文件系统读取SD卡里的小说文件进行显示。
操作的过程在串口调试助手上也会同步输出信息。
4.3 校准说明
第一次使用,需要校准屏幕,否则触摸屏没有反应。
如果发现屏幕不灵敏,可以强制进行校准,按下按键K2再按下复位键即可进行强制校准。
依次点击屏幕上4个红圈。
4.4 SD卡上存放的文件
SD卡上有两个目录:font目录和txt目录。
font目录:存放字库文件。有两个字库字体。
txt目录:存放小说文件,内置了3篇小说。
五、核心代码
代码采用Keil5编写,下载即可编译,测试,学习。
工程完整源码下载地址:基于STM32设计的小时阅读器完整源码(不懂可以私信).zip-嵌入式文档类资源-CSDN下载
5.1 main.c 主函数代码
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include
#include
#include "iic.h"
#include "at24c08.h"
#include "w25q64.h"
#include "nt35310_lcd.h"
#include "xpt2046.h"
#include "sdcard.h"
#include "ff.h" //FATFS文件系统的头文件
//更新字库---从SD卡读取字库到W25Q64
void FontUpdate_to_W25Q64();
FATFS fatfs; //文件系统注册工作区需要使用
u16 select_color[]={WHITE,BLACK,BLUE,RED,YELLOW,BROWN,BRRED,GRAY,DARKBLUE,LIGHTBLUE,GRAYBLUE,LIGHTGREEN};
u8 read_text_buf[4096+1];
int main()
{
u32 x;u32 y;u32 size=16;u8 *p;
u8 color_select_cnt=0; //12个
FIL text_file;
u16 br=0;
u8 r_data=10;
u32 read_cnt=0;
DIR dir;
FRESULT res;
FILINFO fno; //存放读取的文件信息
char *abs_path=NULL;
char path[]="0:/txt";
u32 cnt=0;
USART_X_Init(USART1,72,115200);
NT35310_LcdInit();
NT35310_Clear(WHITE);
IIC_Init(); //IIC总线初始化
W25Q64_Init(); //初始化W25Q64
TOUCH_Init(); //触摸屏初始化
TOUCH_CheckXY(); //触摸屏校准程序
RCC->APB2ENR|=1<<5;
GPIOD->CRH&=0xFF0FFFFF;
GPIOD->CRH|=0x00300000;
while(SDCardDeviceInit()!=0)
{
printf("SDCard_DeviceInit 错误.rn");
PDout(13)=!PDout(13);
delay_ms(100);
}
f_mount(&fatfs,"0:",0); //注册文件系统的工作区
//设计界面
LCD_color_1=RED;
LCD_color_2=LIGHTBLUE;
NT35310_DisplayString(16,0,16,"基于STM32的小说阅读器设计");
NT35310_DrawLine(0,16,239,16,DARKBLUE);
//绘制按键
NT35310_DrawRectangle(0,319-80,239,319,RED);
NT35310_DrawLine(0,319-40,239,319-40,DARKBLUE);
NT35310_DrawLine(239/2,319-80,239/2,319,DARKBLUE);
LCD_color_2=WHITE;
NT35310_DisplayString(32,319-70,16,"下一页");
NT35310_DisplayString(239/2+32,319-70,16,"下一本");
NT35310_DisplayString(32,319-30,16,"字体调整");
NT35310_DisplayString(239/2+32,319-30,16,"颜色调整");
/*1. 打开目录*/
res=f_opendir(&dir,path);
if(res!=FR_OK)return res;
res=f_readdir(&dir,&fno);
printf("文件名称: %s,文件大小: %ld 字节rn",fno.fname,fno.fsize);
LCD_color_1=BLACK;
NT35310_DisplayString(0,17,16,fno.fname);
if(abs_path)
{
free(abs_path);
abs_path=NULL;
}
//申请存放文件名称的长度
abs_path=malloc(strlen(path)+strlen(fno.fname)+1);
strcpy(abs_path,path);
strcat(abs_path,"/");
strcat(abs_path,fno.fname);
printf("abs_path=%sn",abs_path);
NT35310_DisplayString(0,17+16,16,"第1卷
第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀
此开卷第一回也。作者自云:因曾历过一番梦幻之后,故将真事隐去,
而借“通灵”之说,撰此<<石头记>>一书也。故曰“甄士隐”云云。
但书中所记何事何人?自又云:“今风尘碌碌,一事无成,忽念及当日所有之女子,
一一细考较去,觉其行止见识,皆出于我之上。何我堂堂须眉,诚不若彼裙钗哉?");
while(1)
{
if(TOUCH_PEN==0) //判断触摸屏是否按下
{
//判断是否读取到XY坐标
if(TOUCH_ReadXY())
{
// printf("x=%d,y=%drn",touch_info.x,touch_info.y);
//判断范围
if((touch_info.x>=0 && touch_info.x<=239/2)&&
(touch_info.y>=319-80 && touch_info.y<=319-40))
{
LCD_color_2=BLUE;
//填充颜色
NT35310_Fill(0+1,319-80+1,239/2-1,319-40-1,BLUE);
//显示字符串
NT35310_DisplayString(32,319-70,16,"下一页");
//等待触摸屏松开
while(TOUCH_PEN==0){}
//填充颜色--清屏
NT35310_Fill(0,18+16,239,319-80-1,WHITE);
LCD_color_2=WHITE;
if(read_cnt>=br)
{
read_cnt=0;
}
if(read_cnt==0)
{
if(br!=4096)
{
res=f_open(&text_file,(const TCHAR*)abs_path,FA_READ);//打开文件
if(res!=0)
{
printf("%s文件打开失败!rn",abs_path);
return 1; //文件打开失败
}
printf("%s文件打开成功!n",abs_path);
}
//执行代码