最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

基于STM32的数码相框系统设计与实现(软件)_毕业设计论文

IT圈 admin 27浏览 0评论

2023年12月8日发(作者:闽志义)

毕业设计报告(论文)

题目:基于STM32的数码相框系统

设计与实现(软件)

所属系 电子工程系

专 业 自 动 化

设计地点 东南大学成贤学院

东南大学成贤学院毕业设计报告(论文)

诚 信 承 诺

本人承诺所呈交的毕业设计报告(论文)及取得的成果是在导师指导下完成,引用他人成果的部分均已列出参考文献。如论文涉及任何知识产权纠纷,本人将承担一切责任。

学生签名:

日 期:

基于STM32的数码相框系统设计与实现(软件)

摘 要

本设计是一款基于嵌入式硬件平台的数码相框,主控芯片为基于ARM Cortex-M3内核的STM32系列嵌入式处理器,本设计包含主控制器核心板、LCD液晶显示、SD卡存储器等多个功能模块。实现对SD卡里多幅图片以幻灯片形式在TFT屏上动态显示的效果,且带有实时时钟的功能。

关键词:嵌入式;数码相框;Cortex-M3

- I - The design of digital photo frames based on the STM32

Abstract

The design is a digital photo frame-based embedded hardware platform ,whose main chip for the

STM32 family of embedded processors based on ARM Cortex-M3 core . The design includes a host

controller core board, LCD display, SD card memory and other functional modules. It can achieve the

effect of multiple images of the SD card as a slide show on the TFT screen dynamic display, and with

real-time clock function.

Keywords:Embedded; Digital Photo Frame; Cortex-M3

- II - 目 录

摘 要 ............................................................................. I

ABSTRACT .......................................................................... II

第一章 引 言 ...................................................................... 1

1.1

课题研究意义 .................................................................. 1

1.2

数码相框的发展情况和趋势 ...................................................... 1

1.2.1 数码相框的发展现状 ........................................................ 1

1.2.2 数码相框的发展趋势 ........................................................ 2

1.3

本课题设计主要研究内容 ........................................................ 2

1.4

主要章节安排 .................................................................. 3

第二章 硬件介绍 .................................................................... 4

2.1

嵌入式系统概况 ................................................................ 4

2.1.1 嵌入式系统的定义 .......................................................... 4

2.1.2 嵌入式系统的组成 .......................................................... 4

2.1.3 嵌入式系统的特点 .......................................................... 5

2.2

数码相框模块 .................................................................. 5

2.2.1 MCU主控模块 .............................................................. 5

2.2.2 LCD模块 .................................................................. 6

2.2.3 SD存储卡模块 ............................................................. 9

第三章 编程环境介绍................................................................ 12

3.1

RVMDK3.80A简介 .............................................................. 12

3.2

新建RVMDK工程 ............................................................... 12

3.3

软件仿真 ..................................................................... 19

3.4

在线调试 ..................................................................... 24

3.4.1 J-link简介 .............................................................. 24

3.4.2 J-link调试步骤 .......................................................... 25

3.5

程序下载 ..................................................................... 28

第四章 程序设计与调试.............................................................. 34

4.1

系统描述 ..................................................................... 34

4.2

软件设计 ..................................................................... 34

4.2.1 文件读取 ................................................................ 34

4.2.2 图像解码与显示 ........................................................... 35

4.2.3 时钟显示 ................................................................ 42

4.2.4 主程序设计............................................................... 52

4.3

程序调试 ..................................................................... 57

第五章 结束语 ..................................................................... 59

致 谢 ............................................................................ 60

参考文献(REFERENCES).............................................................. 1

附录 数码相框原理图................................................................. 2

- III - 东南大学成贤学院毕业论文

第一章 引 言

1.1 课题研究意义

嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一。嵌入式系统用在一些专用设备上,通常这些设备的硬件资源(如处理器、存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高。特别是随着消费家电的智能化,嵌入式更显重要。像我们平常常见到的手机、PDA、电子字典、可视电话、VCD/DVD/MP3播放器、数码相机、数字摄像机、U-Disk、机顶盒、高清电视、游戏机、智能玩具、交换机、路由器、数控设备、汽车电子、家电控制系统、医疗仪器、航天航空设备等都是典型的嵌入式产品。

数字摄影的兴起不可避免地引起了数码相框的发展,因为仅有不到35%的数码照片被打印出来。数码相框的基本原理就是采用普通相框的造型,把原来相框中间的照片部分换成液晶显示屏,配上电源,存储介质等,使得同一个相框内可以循环播放照片,比普通照片的单一显示功能更有优势。从2007年开始,数码相框的市场关注度开始激增。在2008年,数码相框市场呈现高速发展的态势,本课题的研究具有极高的潜在市场价值。

此外,本设计属于数字影音娱乐产品,需要较为强劲的处理器进行图像解码的工作,而STM32 具有超低的价格、超多的外设、丰富的型号、优异的实时性能、杰出的功耗控制和极低的开发成本等特点。因此,进行基于STM32平台的数码相框系统的设计具有重要的理论意义和实用价值。

1.2 数码相框的发展情况和趋势

1.2.1 数码相框的发展现状

数码相框产品是2001年开始出现的,但由于当时消费者的接受度及价格过高的因素,使这一市场一直到2003年都很低迷。随着主要器件价格的下降,数码相框的价格也逐步下降,市场在2004年开始有了起色,尤其在2005年,数码相框产品开始在欧美热销,但出货量也只有150万台左右,到了2006年的出货量同比上涨133%,为280万台,2007年的出货量同比上涨185%,为800万台,预计到2011年出货量将达到4000万台。从屏幕尺寸来看,2006年5-6.9英寸产品占主流,2007年7、8、9英寸产品成为最大市场。预计2011年,7、8、9英寸产品的供货比例将持续保持首位,而平均销售单价将以每年16.5%左右的速度降低。

2006年以前,中国生产的数码相框绝大多数出口国外。2005年底Philips率先将数码相框在中国推广,在礼品市场上取得了一些成绩,但由于销售价格较高,约为2050元/台,这一年中国数码相框的销售量仅有1.7万台。2006年下半年,开始有更多的国内厂商在中国市场推出数码相框,因而也带动了此产品价格的下降,这一年的平均售价为1150元/台,仍然较高,市场也以商务礼品为主,但由于2005年销售量的基数较低,2006年的销售量同比增长了470.6%,达到9.7万台。直到2007年下半年,业界才感到这个一直处于培育期的市场,开始了真正的起飞。这得益于对数码相框产品认知度的提高、价格的下滑和需求量的提高。

从IT厂商来看,仅2007年下半年以来,就有惠普、三星、优派、AOC、明基、柯达、长城等众多新军加入数码相框阵营。其中,巨头惠普2007年7月底在美国宣布进入数码相框市场,2007年数码相框出货量设定为50万台。除新军外,数码相框老牌劲旅的出货量表现也令业界振奋,如飞利浦2006年数码相框出货量达到50万台,而2007年上半年出货量已达去年总和,2007年全年出货量达150万台。而从上游面板厂商的动作来看,也显示出乐观的发展态势。中华映管、群创等厂商均显著调高了配套数码相框产品的中尺寸面板的出货量目标,2007年出货量达1000万台,预计2008- 1 - 东南大学成贤学院毕业论文

年更将倍增至2000万台。其中,中华映管目前已调配一座4.5代面板厂来支持生产中尺寸面板,主要生产可携式DVD播放机面板与数码相框面板,其数码相框面板以7英寸、8英寸、10.2英寸为主要尺寸,数码相框面板占其中尺寸面板的比重提高到40%。

1.2.2 数码相框的发展趋势

从长远来看,2008年及今后几年将为处在数码相框产品供应链的各企业带来巨大的商机。未来几年,数码相框的市场将处在逐渐走向成熟期的阶段,其产销量和市场需求依然将保持大幅度的增长,在未来的三年内,市场尚无萎缩的可能。但数码相框拓展中国市场需克服两大难点:一是价格;二是拓展应用空间。价格下降是必然趋势,中国消费者接受只是时间的问题,而根据中国消费者的需求和特点,开发出相应的应用产品,则是需要数码相框厂商亟待解决的问题。

从技术上来说,未来数码相框的发展将向两极分化。一部分产品着重强调基本功能和低成本,整合家庭中的闹钟、日历和装饰功能,这些产品走的是低成本路线,以展示照片为主,追求图像的品质及幻灯片播放特效,已成为DC/DV的附属物;另一部分产品将会添加一些新的功能,如WiFi,还可即时报告天气、股票等信息,从而有望成为“桌面信息中心”。此外,触摸面板会成为一个应用的新亮点。

从产品形态上来说,数码相框的市场将会有非常明确的细分。

1 数码相框:

这将是以数字照片的重显为主要功能的产品,其功能更接近于传统意义上的相框。

由于人机界面的限制,为了更方便的重显和浏览以及确定重显的规则,这类产品并不强调有大容量的内存以及丰富的存储卡接口,这类产品的主要特征是:

1) 支持USB Device&Host以便于更新和同步数据。

2) 在某些情况下(如从PC端通过相框的USB Device同步数据),允许修改数字照片的格式使得有最佳的重显效果。

3) 仅依靠内置的半导体存储器存放需要重显的数字照片。

4) 文件(照片)查询和播放规则设定非常简洁易用。

5) 产品大致分为桌面和壁挂两种。

2 数码相册:

这是以数字照片的存储和浏览为主要功能的产品,由于需要满足跟PC相类似功能,所以这类产品的主要特征是:

1) 有大容量的内置数据存储器。

2) 支持USB Device&Host及各种存储卡接口,并支持内部存储器与各种数据存储器之间的同步以及相互拷贝。

3) 强大的文件管理功能:浏览,搜寻,命名(重命名),复制,删除,备份等。

4) 带或不带内建显示单元,有能支持其它高分辨率显示设备的接口(如色差,VGA甚至是HDMI)。

1.3 本课题设计主要研究内容

本课题是基于ARM单片机STM32F103RBT6的存储程序控制,从SD卡读取图片,解码后输出到TFT-LCD上显示,同时通过按键可以切换到时间模式。

1)硬件电路原理图的绘制(见附录);

2)硬件资料的研究;

3)软件方案的选择与论证;

4)软件运行与调试;

- 2 - 东南大学成贤学院毕业论文

1.4 主要章节安排

第一章 就课题研究的背景与意义以及发展现状与趋势做出说明;

第二章 概要性地介绍了嵌入式系统的基本知识;

第三章 详细地介绍了软件编程与下载环境;

第四章 程序设计与调试;

第五章 结束语;

致 谢 在软件设计过程中给予我无限帮助的老师和同学;

参考文献 列出本次设计中参阅的相关资料;

附 录 在设计过程中所参考的部分资料及硬件装置的部分资料。

- 3 - 东南大学成贤学院毕业论文

第二章 硬件介绍

2.1 嵌入式系统概况

2.1.1 嵌入式系统的定义

虽然嵌入式系统是近几年才风靡起来的,但其历史可追溯到20世纪70年代。经过30多年的发展,在硬件和软件交替发展的支撑下,嵌入式技术逐渐趋于稳定和成熟,已被广泛应用于工业控制、交通管理、信息家电、家庭智能管理系统、POS网络及电子商务、环境检测、机器人等各个领域。毫不夸张的说,嵌入式系统已经无所不在,所以研究和开发嵌入式系统有着十分重要的意义。

根据IEEE(国际电气和电子工程师协会)的定义,嵌入式系统是“控制、监视或辅助设备、机器和车间运行的装置”,这主要是从应用上加以定义的。不过,上述定义并不能充分体现出嵌入式系统的精髓。目前,国内一个普遍被认同的定义是:以应用为中心、以计算机为基础,软、硬件可裁减,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。

广义地讲,凡是不用于通用目的的可编程计算机设备,就可以算是嵌入式计算机系统。狭义上而言,嵌入式系统是指以应用为核心,以计算机技术为基础,软硬件可裁剪,适于应用系统对功能、可靠性、成本、体积和功耗严格要求的专用计算机系统。

总的来说,嵌入式系统是一个外延极广的概念,凡是与产品结合在一起的、具有嵌入式系统特点的系统都可以称为嵌入式系统。可以从以下几个方面来理解嵌入式系统的含义:

嵌入式系统是面向用户、面向产品、面向应用的,必须与具体应用相结合才会具有生命力。正因为与具体应用的紧密结合,嵌入式系统才具有很强的专用性。

嵌入式系统将先进的半导体技术、计算机技术和电子技术,以及各个行业的具体应用相结合,是一个技术密集、资金密集、学科交叉和不断创新的知识集成系统。

嵌入式系统必须根据应用需要对硬件和软件进行裁剪,以满足应用系统对功能、可靠性、成本、体积和功耗的要求。

2.1.2 嵌入式系统的组成

通常来说,嵌入式系统可以划分成硬件和软件两部分。嵌入式硬件由嵌入式微处理器、片内周边电路和外部设备三部分组成。嵌入式微处理器是嵌入式硬件系统的核心,直接影响嵌入式产品的应用范围和开发复杂度。典型的嵌入式微处理器有Motorola公司的Power PC系列、Intel公司的Strong Arm系列、AMD公司的X86系列以及EPSON公司的SIC33系列等。嵌入式软件一般由连接硬件和应用程序的嵌入式实时操作系统(Real-time operating System,简称RTOS)和在其上运行的应用软件构成。

①嵌入式处理器

嵌入式处理器是嵌入式系统的核心部件,是控制、辅助系统运行的硬件单元,其功能和性能影响着整个系统的功能、性能和设计。嵌入式处理器的选择也制约着其配套的外围器件及操作系统的选择。

嵌入式处理器的种类繁多、数量庞大。目前世界上嵌入式处理器的种类数量已经超过1000种,流行的体系结构有30多个系列。嵌入式微处理器具有体积小、重量轻、成本低、可靠性高等优点,因此得到了广泛应用。目前这样的嵌入式处理器类型有ARM、MIPS、MC6800、386EX、PowerPC等系列,其中以ARM的应用最为广泛。

嵌入式处理器可以分为四类,即

嵌入式微处理器(Embedded Microprocessor Unit,EMPU),如ARM

- 4 - 东南大学成贤学院毕业论文

嵌入式微控制器(Microcontroller Unit,MCU)

嵌入式DSP处理器(Embedded Digital Signal Processor,EDSP)

嵌入式片上系统(System On Chip)

②嵌入式外围设备

这里所说的嵌入式外围设备,指在一个嵌入式硬件系统中,.除了中心控制部件(MCU,DSP,EMPU,SOC)以外的完成存储、通信、保护、调试、显示等辅助功能的其他部件。根据外围设备的功能可分为以下三类,即:

存储器类型:静态易失型存储器(RAM,SRAM)、动态存储器(DRAM)、非易失型存储器(ROM,EPROM,EEPROM,FLASH)。其中,因为FLASH可以擦写多次,存储速度快,容量大,价格便宜在嵌入式领域应用广泛。

接口类型:目前存在的所有接口在嵌入式领域都应用广泛,如RS-232(串口)、IRDA(红外线接口)、SPI(串行外围设备接口)、I2C(现场总线接口)、USB(通用串行接口)、Ethernet(以太接口)和普通并口。

显示类型:CRT,LCD和触摸屏等外围设备。

2.1.3 嵌入式系统的特点

嵌入式系统具有以下几个重要特征:

①系统内核小,由于嵌入式系统一般应用于小型电子装置,系统资源相对有限,所以内核较之传统的操作系统要小得多。比如,ENEA公司的OSE分布式系统,内核只有5KB,而Windows的内核则要大得多。

②专用性强,嵌入式系统的个性化很强,其中的软件系统和硬件结合非常紧密,一般要针对硬件进行系统的移植,同时针对不同的任务,往往需要对系统进行较大的更改。另外,程序的编译下载要和系统相结合。

③嵌入式系统一般没有系统软件和应用软件的明显区分,不要求其功能的设计及实现过于复杂,这样既利于控制系统成本,也利于实现系统安全。

④高实时性的操作系统软件是嵌入式软件的基本要求,而且软件要求固化存储,以提高速度,软件代码要求高质量和高可靠性。

⑤嵌入式软件开发要想走向标准化,就必须使用多任务操作系统。嵌入式系统的应用程序可以没有操作系统而直接在芯片上运行,但为了更合理的调度多任务,利用系统资源、系统函数,用户必须自行选配RTOS开发平台。

⑥执行的实时性、可靠性,并减少开发时间,保障软件质量。嵌入式系统开发需要专门的开发工具和环境。由于嵌入式系统本身不具备自主开发能力,即使完成设计后,用户通常也不能对其中的程序功能进行修改,因此必须有一套基于通用计算机的开发工具和环境才能进行开发。

2.2 数码相框模块

2.2.1 MCU主控模块

STM32系列闪存微控制器是意法半导体公司(ST)基于ARM公司具有突破性的Cortex-M3内核的处理器,该处理器是专门设计于满足集高性能、低功耗、实时应用、具有竞争性价格于一体的嵌入式领域的要求。此次设计采用的具体型号是STM32F103RBT6,如图2-1所示。

- 5 - 东南大学成贤学院毕业论文

图2-1 STM32F103RBT6处理器

STM32F103RBT6嵌入式处理器具有以下特点:

32位RISC性能处理器;

32位ARM Cortex-M3结构优化;

72 MHZ运行频率,单周期访问时速度可达1.25 DMIPS/MHz;

硬件除法和单周期乘法;

快速可嵌套中断,6~12个时钟周期;

具有MPU保护设定访问规则;

片内具有256KB FLASH,48KB RAM;

80个快速I/O端口,16个I/O可映射到外部中断,几乎所有的I/O可以忍受5V电压;

片上集成12Bit A/D、D/A、PWM、CAN、USB、SDIO、FSMC等资源;

ARM Cortex-M3是一种基于ARM7v架构的最新ARM嵌入式内核,它采用哈佛结构,使用分离的指令和数据总线(冯诺伊曼结构下,数据和指令共用一条总线)。从本质上来说,哈佛结构在物理上更为复杂,但是处理速度明显加快。根据摩尔定理,复杂性并不是一件非常重要的事,而吞吐量的增加却极具价值。

除了使用哈佛结构,Cortex-M3还具有其它显著的优点:具有更小的基础内核,价格更低,速度更快。与内核集成在一起的是一些系统外设,如中断控制器、总线矩阵、调试功能模块,而这些外设通常都是由芯片制造商增加的。

Cortex-M3还集成了睡眠模式和可选的完整的八区域存储器保护单元,只支持最新的Thumb-2指令集,最大限度降低了汇编器使用率。Cortex-M3这样设计的优势在于:

免去Thumb和ARM代码的互相切换,对于早期的处理器来说,这种状态切换会降低性能。

Thumb-2指令集的设计是专门面向C语言的,且包括If/Then结构(预测接下来的四条语句的条件执行)、硬件除法以及本地位域操作。

Thumb-2指令集允许用户在C代码层面维护和修改应用程序,C代码部分非常易于重用。

Thumb-2指令集也包含了调用汇编代码的功能:Luminary公司认为没有必要使用任何汇编语言。

综合以上这些优势,新产品的开发将更易于实现,上市时间也大为缩短。STM32F103RBT6的资源完全满足此次的嵌入式数码相框设计,通过设计电路开发一个支持TFT彩色液晶屏的驱动电路,在设计中搭配2.8寸TFT真彩触摸屏模块作为显示界面,同时支持一个SD卡(SPI方式)可用于存储图片、数据等。

2.2.2 LCD模块

Thin Film Transistor(薄膜场效应晶体管),是指液晶显示器上的每一液晶象素点都是由集成在其后的薄膜晶体管来驱动。从而可以做到高速度、高亮度、高对比度显示屏幕信息,TFT-LCD(薄- 6 - 东南大学成贤学院毕业论文

膜晶体管液晶显示器)是多数液晶显示器的一种。TFT屏幕的优点如下:

大面积。九十年代初第一代大面积玻璃基板(300mm×400mm)TFT-LCD生产线投产,到2000年上半年玻璃基板的面积已经扩大到了680mm×880mm),最近950mm×1200mm的玻璃基板也将投入运行。

高集成度。用于液晶投影的1.3英寸TFT芯片的分辨率为XGA含有百万个象素。分辨率为SXGA(1280×1024)的16.1英寸的TFT阵列非晶体硅的膜厚只有50nm,以及TAB ON GLASS和SYSTEM ON GLASS技术,其IC的集成度,对设备和供应技术的要求,技术难度都超过传统的LSI。

功能强大。TFT最早作为矩阵选址电路改善了液晶的光阀特性。对于高分辨率显示器,通过0-6V范围的电压调节(其典型值0.2到4V),实现了对象元的精确控制,从而使LCD实现高质量的高分辨率显示成为可能。TFT-LCD是人类历史上第一种在显示质量上超过CRT的平板显示器。现在人们开始把驱动IC集成到玻璃基板上,整个TFT的功能将更强大,这是传统的大规模半导体集成电路所无法比拟的。

低成本。玻璃基板和塑料基板从根本上解决了大规模半导体集成电路的成本问题,为大规模半导体集成电路的应用开拓了广阔的应用空间。

工艺灵活。除了采用溅射、CVD(化学气相沉积)MCVD(分子化学气相沉积)等传统工艺成膜以外,激光退火技术也开始应用,既可以制作非晶膜、多晶膜,也可以制造单晶膜。不仅可以制作硅膜,也可以制作其他的Ⅱ-Ⅵ族和Ⅲ-Ⅴ族半导体薄膜。

应用领域广泛。以TFT技术为基础的液晶平板显示器是信息社会的支柱产业,技术可应用到正在迅速成长中的薄膜晶体管有机电致发光(TFT-OLED)平板显示器也在迅速的成长中。

TFT液晶显示屏亮度好、对比度高、层次感强、颜色鲜艳,其广泛应用于手机、MP4等消费品。因此,本系统选用2.8英寸TFT-LCD屏(如图2-2所示)可显26万色,分辨率320*240,控制器为ILI9320,采用16位的80并口,配合触摸屏专用芯片XPT2046,可对屏幕进行触摸操作,更显智能化和个性化。为了方便用户使用,我们存储方式采用兼容FAT的文件系统,同时该文件系统也兼容FAT32等电脑主流的文件系统方式进行存储。

图2-2 2.8英寸TFT-LCD模块

该模块的80 并口有如下一些信号线:

CS:TFT-LCD片选信号。

WR:向TFT-LCD写入数据。

RD:从TFT-LCD读取数据。

D[15:0]:16位双向数据线。

RST:硬复位TFT-LCD。

RS:命令/数据标志(0,读写命令;1,读写数据)。

TFT-LCD模块的RST 信号线是直接接到STM32 的复位脚上,并不由软件控制,这样可以省下来一个I/O口。另外我们还需要一个背光控制线来控制TFT-LCD的背光。所以我们总共需要的I/O口数目为21个。

模块的控制器为ILI9320(可能为其他型号,但是他们的设置很相似,除了初始化序列有些区- 7 - 东南大学成贤学院毕业论文

别,其他大都是一摸一样的,这里仅以9320为例介绍),该控制器自带显存,其显存总大小为172820(240*320*18/8),即18位模式(26万色)下的显存量。模块的16位数据线与显寸的对应关系为565方式,如下图所示:

图2-3 16位数据与显存对应关系图

最低5位代表蓝色,中间6位为绿色,最高5 位为红色。数值越大,表示该颜色越深。接下来介绍一下ILI9320的几个重要命令,因为ILI9320的命令很多,这里不一一介绍。这里我们要介绍的命令列表如下:

表2.1 ILI9320 常用命令表

R0,这个命令,有两个功能,如果对它写,则最低位为OSC,用于开启或关闭振荡器。而如果对它读操作,则返回的是控制器的型号。这个命令最大的功能就是通过读它可以得到控器的型号,而我们代码在知道了控制器的型号之后,可以针对不同型号的控制器,进行不同的初始化。因为93xx

系列的初始化,其实都比较类似,我们完全可以用一个代码兼容好几个控制器。

R3,入口模式命令。我们重点关注的是I/D0、I/D1、AM 这3 个位,因为这3 个位控制了屏幕的显示方向。

AM:控制GRAM更新方向。当AM=0的时候,地址以行方向更新。当AM=1的时候,地址以列方向更新。

I/D[1:0]:当更新了一个数据之后,根据这两个位的设置来控制地址计数器自动增加/减少1,其关系如下图:

- 8 - 东南大学成贤学院毕业论文

图2-4 GRAM 显示方向设置图

通过这几个位的设置,我们就可以控制屏幕的显示方向了。

R7,显示控制命令。该命令CL位用来控制是8位彩色,还是26万色。为0时26万色,为1时八位色。D1、D0、BASEE这三个位用来控制显示开关与否的。当全部设置为1的时候开启显示,全0是关闭。我们一般通过该命令的设置来开启或关闭显示器,以降低功耗。

R32,R33,设置GRAM的行地址和列地址。R32用于设置列地址(X 坐标,0~239),R33用于设置行地址(Y坐标,0~319)。当我们要在某个指定点写入一个颜色的时候,先通过这两个命令设置到改点,然后写入颜色值就可以了。

R34,写数据到GRAM命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。该命令是我们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要先写入命令编号,然后写入操作数。

R80~R83,行列GRAM 地址位置设置。这几个命令用于设定显示区域的大小,我们整个屏的大小为240*320,但是有时候我们只需要在其中的一部分区域写入数据,如果用先写坐标,后写数据这样的方式来实现,则速度大打折扣。此时我们就可以通过这几个命令,在其中开辟一个区域,然后不停的丢数据,地址计数器就会根据R3的设置自动增加/减少,这样就不需要频繁的写地址了,大大提高了刷新的速度。

通过以上介绍,我们可以得出TFT-LCD显示需要的相关设置步骤如下:

1)设置STM32与TFT-LCD模块相连接的I/O。

这一步,先将我们与TFT-LCD模块相连的I/O口设置为输出,具体使用哪些I/O口,这里需要根据连接电路以及TFT-LCD模块的设置来确定。

2)初始化TFT-LCD模块。

通过向TFT-LCD写入一系列的设置,来启动TFT-LCD的显示。为后续显示字符和数字做准备。

3)通过函数将字符和数字显示到TFT-LCD模块上。

这里就是通过我们设计的程序,将要显示的字符送到TFT-LCD模块就可以了,这些函数将在软件设计部分向大家介绍。通过以上三步,我们就可以使用TFT-LCD模块来显示字符和数字了,并且可以显示各种颜色的背景。

2.2.3 SD存储卡模块

SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地应用于便携式装置上,例如数码相机、个人数码助理(PDA)和多媒体- 9 - 东南大学成贤学院毕业论文

播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性,此外它可存多种格式数据文件,具有很强的可扩展性;用户可方便使用SD卡读卡器对其进行用户信息修改。2G金士顿SD卡实物如下图2-5所示。

SD卡一般支持两种操作模式:SD卡模式与SPI模式。

主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。SD卡的引脚排序如下图2-6所示:

图2-5 Kingston SD卡 图2-6 SD卡引脚排序图

SD 卡引脚功能描述如下表所示:

表2.2 SD卡引脚功能表

SD卡只能使用3.3V的I/O电平,所以,MCU一定要能够支持3.3V的I/O端口输出。在SPI 模式下,CS/MOSI/MISO/CLK都需要加10~100K左右的上拉电阻。SD卡要进入SPI模式很简单,就是在SD卡收到复位命令(CMD0)时,CS为有效电平(低电平)则SPI模式被启用。不过在发送CMD0之前,要发送>74个时钟,这是因为SD卡内部有个供电电压上升时间,大概为64个CLK,剩下的10个CLK用于SD卡同步,之后才能开始CMD0的操作,在卡初始化的时候,CLK时钟最大不能超过400KHZ。

本次硬件电路板使用的是SPI模式来读写SD卡,下面我们就重点介绍一下SD卡在SPI模式下的相关操作。

SPI模式下几个重要的操作命令,如下表所示:

表2.3 SPI模式下SD卡部分操作指令

其中 R1 的回应格式如下表所示:

- 10 - 东南大学成贤学院毕业论文

表2.4 SD卡R1回应格式

SD卡的典型初始化过程如下:

1、初始化与SD卡连接的硬件条件(MCU的SPI配置,I/O口配置);

2、上电延时(>74个CLK);

3、复位卡(CMD0);

4、激活卡,内部初始化并获取卡类型(CMD1(用于MMC卡)、CMD55、CMD41);

5、查询OCR,获取供电状况(CMD58);

6、是否使用CRC(CMD59);

7、设置读写块数据长度(CMD16);

8、读取CSD,获取存储卡的其他信息(CMD9);

9、发送8CLK后,禁止片选;

这样我们就完成了对SD卡的初始化,这里面我们一般设置读写块数据长度为512个字节,并禁止使用CRC。在完成了初始化之后,就可以开始读写数据了。

SD 卡读取数据,这里通过CMD17来实现,具体过程如下:

1、发送CMD17;

2、接收卡响应R1;

3、接收数据起始令牌0XFE;

4、接收数据;

5、接收2 个字节的CRC,如果没有开启CRC,这两个字节在读取后可以丢掉;

6、8CLK 之后禁止片选;

以上就是一个典型的读取SD卡数据过程,SD卡的写与读数据差不多,写数据通过CMD24 来实现,具体过程如下:

1、发送CMD24;

2、接收卡响应R1;

3、发送写数据起始令牌0XFE;

4、发送数据;

5、发送2字节的伪CRC;

6、8CLK之后禁止片选;

- 11 - 东南大学成贤学院毕业论文

第三章 编程环境介绍

3.1 RVMDK3.80A简介

RVMDK源自德国的KEIL公司,是RealView MDK的简称,在全球RVMDK被超过10万的嵌入式开发工程师使用。RealView MDK集成了业内最领先的技术,包括µVision3集成开发环境与RealView编译器。支持ARM7、ARM9和最新的Cortex-M3核处理器,自动配置启动代码,集成Flash烧写模块,强大的Simulation设备模拟,性能分析等功能。与ARM之前的工具包ADS1.2相比,RealView编译器具有代码更小、性能更高的优点。RealView编译器与ADS1.2的比较:代码密度方面比ADS1.2编译的代码尺寸小10%;代码性能方面比ADS1.2编译的代码性能提高20%。

现在RealView的最新版本是RVMDK4.13A,4.0以上版本的RVMDK对IDE界面进行了很大改变,并且支持Cortex-M0内核的处理器。虽然4.10界面确实是好了,支持的器件也多了,但编译效率没有3.24/3.80A高,尤其是编译后的代码执行速度(FFT运算),4.10要对速度进行-O2优化才能和3.24/3.80A的普通级别相比。另外,国内大多数单片机工程师都接触和使用过KEIL,相信大家都知道KEIL的使用是非常简单的,而且很容易入手。基于以上几点,此次选择RVMDK3.80版本的编译器来对软件进行编译。

3.2 新建RVMDK工程

首先,打开 MDK(以下简称RVMDK 为MDK)软件,再点击Project->New uVision Project菜单项,则弹出如图3-1所示界面:

图3-1 保存工程界面

新建一个文件夹 TEST,然后把工程名字设为test,点击“保存”按钮,弹出选择器件的对话框,因为我们的开发板使用的是STM32F103RBT6,所以在这里我们选择STMicroelectronics下面的STM32F103RB(如果使用的是其他系列的芯片,选择相应的型号就可以了)。如图3-2所示:

- 12 - 东南大学成贤学院毕业论文

图3-2 器件选择界面

点击OK,MDK会弹出一个对话框,问你是否加载启动代码到当前工程下面,这里我们选择是。如图3-3所示:

图3-3 提示界面

启动代码是一段和硬件相关的汇编代码,是必不可少的!这段代码的具体作用如下:①堆栈的初始化;②向量表定义;③地址重映射及中断向量表的转移;④设置系统时钟频率;⑤中断寄存器的初始化。在上面点击了是以后,MDK就把启动代码STM32F10x.s加入到了我们的工程下面。到这里,我们就可以开始编写自己的代码了。

由于上面我们还没有任何代码在工程里面,我们在TEST 目录下新建一个新文件夹USER,这里我们把系统代码复制过来(整个SYSTEM文件夹,这些代码在任何STM32F103的芯片上都是通用的,可以用于快速构建自己的工程,后面会有详细介绍)。之后,TEST文件夹下的文件如图3-4所示:

- 13 - 东南大学成贤学院毕业论文

图3-4 TEST文件夹最终摸样

然后我们在 USER 文件夹下面找到2,打开它,然后在Target目录树上右键->Manage

Components。如图3-5所示:

图3-5 调出Manage Components

在进入Manage Components界面之后,弹出如下对话框:

- 14 - 东南大学成贤学院毕业论文

图3-6 Components 选项卡

在上面对话框的中间栏,点新建(用红圈标出)按钮(也可以通过双击下面的空白处实现),新建USER 和SYSTEM两个组,然后点击Add Files按钮,把sys.c,usart.c,delay.c加入到SYSTEM组中。此时USER组下还是没有任何文件的,得到如下图所示的界面:

图3-7 修改结果

点击OK,退出该界面返回IDE。这时,我们在Target树下发现多了2个组名,就是我们刚刚新建的2个组。如下图所示:

- 15 - 东南大学成贤学院毕业论文

图3-8在编辑状态下的体现

接着,我们新建一个test.c文件,并保存在USER目录下,然后双击USER组,会弹出加载文件的对话框,此时我们在USER目录下选择test.c文件,加入到USER组下。得到如下界面:

图3-9 在USER 组下加入test.c 文件

接着我们在 test.c文件里面输入如下代码:

#include "sys.h"

#include "delay.h"

#include "usart.h"

int main(void)

{

u8 t=0;

Stm32_Clock_Init(9); //72M

delay_init(72); //延时初始化

- 16 - 东南大学成贤学院毕业论文

uart_init(72,9600); //设置串口1 波特率

while(1)

{

printf("t:%dn",t);

delay_ms(500);

t++;

}

}

点击(部分编译按钮)编译一下,会在Output Windows信息栏中发现如下报错信息:test.c(1):

error: #5:can not open source input file "sys.h": No such file or directory。如下图所示(图中红圈内信息):

图3-10编译报错

意思是无法打开源输入文件sys.h,没这个文件或目录。双击红圈内的内容,你会发现在test.c的01行出现了一个浅绿色的小箭头,说明错误是这个地方产生的。双击后浅绿色箭头出现位置如下:

图3-11编译报错

其实通过下面错误的说明,就是include 的路径没有加进去的缘故,而导致了这个错误。现在我们点击(Options for Target 按钮),弹出Options for Target’Target 1’对话框,选择C/C++选项卡,如下图所示:

- 17 - 东南大学成贤学院毕业论文

图3-12 加入头文件包含路径

在Include Paths处,点击2处的按钮。在弹出的对话框中加入SYSTEM文件夹下的3个文件夹名字,把这几个路径都加进去(此操作即设定编译器的头文件包含路径,下面会经常用到)。

图3-13 头文件包含路径设置

点击OK确认,回到IDE,此时再点击按钮,再编译一次,发现没错误了,得到如下界面:

- 18 - 东南大学成贤学院毕业论文

图3-14 再次编译结果

至此,一个完整的STM32开发工程在MDK下建立了,接下来我们就是进行软件仿真了。

3.3 软件仿真

MDK的一个强大的功能就是提供软件仿真,通过软件仿真,我们可以发现很多将要出现的问题,避免了下载到STM32里面来查这些错误,这样最大的好处是能很方便的检查程序存在的问题,因为在MDK的仿真下面,你可以查看很多硬件相关的寄存器,通过观察这些寄存器,你可以知道代码是不是真正有效。另外一个优点是不必频繁的刷机,从而延长了STM32的FLASH寿命。当然,软件仿真不是万能的,很多问题还是要到在线调试才能发现。接下来我们开始进行软件仿真。

在软件仿真之前,先检查一下配置是不是正确,点击要检查芯片型号和晶振频率,其他的一般默认就可以):

,确定Target选项卡内容如下所示(主

图3-15 Target 选项卡

确认了芯片以及外部晶振频率(8.0 M)之后,基本上就确定了硬件环境了,接下来,我们再看- 19 - 东南大学成贤学院毕业论文

Debug选项卡,设置为如下图所示的设置:

图3-16 Debug 选项卡

主要确认是Use Simulator是否选择(因为如果选择右边的Use,那就是用ULINK进行硬件Debug了,这个将在下面介绍),其他的采用默认的就可以。确认了这项之后,我们便可以选择OK,退出Options for Target对话框了。接下来,我们点击下界面:

(开始/停止仿真按钮),开始仿真,出现如

图3-17开始仿真

可以发现,多出了一个工具条,这个工具条对于我们仿真是非常有用的,下面简单介绍一下工具条相关按钮的功能,工具条部分按钮的功能如下图所示

- 20 - 东南大学成贤学院毕业论文

图3-18 仿真工具条

复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。代码重新执行。

执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能。

挂起:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。

执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。

执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。

执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。

执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。

汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。

观看变量/堆栈窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量值,也是很常用的一个调试窗口。

串口打印窗口:该按钮按下,会弹出一个串口调试助手界面的窗口,用来显示从串口打印出来的内容。

内存查看窗口:该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况,是很常用的一个调试窗口

性能分析窗口:按下该按钮,会弹出一个观看各个函数执行时间和所占百分比的窗口,用来分析函数的性能是比较有用的。

逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过 SETUP 按钮新建一些I/O 口,就可以观察这些I/O 口的电平变化情况,以多种形式显示出来,比较直观。

其他几个按钮用的比较少,以上是比较常用的,当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西来决定要不要看。

这样,我们在上面的仿真界面里面选内存查看窗口、串口打印窗口。然后调节一下这两个窗口的位置,如下图所示:

- 21 - 东南大学成贤学院毕业论文

图3-19 调出仿真串口打印窗口

我们把光标放到 test.c的09行,然后双击鼠标左键,可以看到在09行的右边出现了一个红框,即表示设置了一个断点(也可以通过鼠标右键弹出菜单来加入,再次双击则取消)。然后我们点击,执行到断点处,如下图所示:

图3-20 执行到断点处

我们不忙着往下执行,现在来点击菜单栏的Peripherals->USARTs->USART1。可以看到,有很多外设可以查看,这里我们查看的是串口1的情况。如下图所示

- 22 - 东南大学成贤学院毕业论文

图3-21 查看串口1 相关寄存器

单击 USART1后会在IDE之外出现一个如下界面:

图3-22 串口1 各寄存器初始化前后对比

左边这个就是STM32默认时候,串口1的状态,从中可以看到所有与串口相关的寄存器全部在这上面表示出来了,而且有当前串口的波特率等信息的显示。我们接着单击一下,执行完串口初始化函数,得到了如上面右边图片所示的串口信息。你可以对比一下这两个的区别,就知道在uart_init(72,9600);这个函数里面大概执行了哪些操作。这样可以很清楚的告诉你,当前的串口是否可用,你的设置是否正确,同样这样的方法也可以适用于很多其他外设。

然后我们继续单击下图所示:

按钮,一步步执行,最后就会看到在USART #1 中打印出相关的信息,如- 23 - 东南大学成贤学院毕业论文

图3-23 串口1输出信息

这样证明我们的仿真是通过的,代码运行会在串口1 不停的输出t 的值,每0.5s执行一次(时间可以通过IDE的最下面观看到),并且t 自增。与我们预期的目地是一致的。再次按下否可行。

结束仿真。至此,我们软件仿真算是结束了,接下来我们下载代码到硬件上来真正验证一下我们的代码是3.4 在线调试

利用串口,我们只能下载程序,并不能实时跟踪,而利用调试工具,比如JLINK、ULINK等就可以实时跟踪程序,使你的开发事半功倍。这里我们以JLINK V8为例,说说如何在线调试。

3.4.1 J-link简介

J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器。配合IAR EWAR,ADS,KEIL,WINARM,Real View等集成开发环境支持所有ARM7/ARM9/ARM11内核芯片的仿真,通过RDI接口和各集成开发环境无缝连接,操作方便、连接方便、简单易学,是学习开发ARM最好最实用的开发工具。

J-LINK仿真器V8版,其仿真速度和功能远非简易的并口WIGGLER调试器可比。J-LINK支持ARM7、ARM9、ARM11、Cortex-M3核心,支持ADS、IAR、KEIL开发环境。V8.0版本除拥有上一版本V7.0的全部功能外,软硬件上都有改进:(1)V8.0版的SWD硬件接口支持1.2-5.0V的目标板,V7.0只能支持3.3V的目标板。(2)V8.0使用双色LED可以指示更多的工作状态,V7.0只有1个LED指示灯。(3)V8.0增强了JTAG驱动能力,提高了目标板的兼容性。(4)优化了固件结构,使应用程序区扩大。J-Link ARM主要特点:

IAR EWARM集成开发环境无缝连接的JTAG仿真器。

支持所有ARM7/ARM9内核的芯片,以及Cortex-M3,包括Thumb模式。

支持ADS,IAR,KEIL,WINARM,REALVIEW等几乎所有的开发环境。

下载速度高达ARM7:600kB/s,ARM9:550kB/s,通过DCC最高可达800 KB/s。

最高JTAG速度12MHz。

目标板电压范围1.2V–3.3V,5V兼容。

自动速度识别功能。

- 24 - 东南大学成贤学院毕业论文

监测所有JTAG信号和目标板电压。

完全即插即用。

使用USB电源(但不对目标板供电)

带USB连接线和20芯扁平电缆。

支持多JTAG器件串行连接。

标准20芯JTAG仿真插头。

选配14芯JTAG仿真插头。

选配用于5V目标板的适配器。

带J-Link TCP/IP server,允许通过TCP/ IP网络使用J-Link。

3.4.2 J-link调试步骤

JLINK-V8支持JTAG和SWD,而STM32也支持JTAG和SWD。所以,我们有2种方式可以用来调试,JTAG调试的时候,占用的I/O 线比较多,而SWD 调试的时候占用的I/O线很少,只需要2跟即可。

在安装了JLINK V8之后,我们接上JLINK-V8,并把JTAG口插到硬件板上,打开之前新建的工程,点击,打开Options for Target选项卡,在Debug栏选择仿真工具为Cortex-M3 J-LINK,如下图所示

图3-24 Debug 选项卡设置

然后我们点击Settings,设置J-LINK的一些参数,如下图所示:

- 25 - 东南大学成贤学院毕业论文

图3-25 J-LINK 模式设置

上图中,我们使用J-LINK V8的SW模式调试,因为我们JTAG需要占用比SW模式多很多的I/O口,而在硬件板上这些I/O口都是非常有用的,并造成部分外设无法使用。所以建议大家在调试的时候,一定要选择SW模式。Max Clock,可以点击Auto Clk来自动设置,这里设置JLINK的调试速度为10MHZ,如果USB数据线比较差,那么可能会出问题,此时,可以通过降低这里的速率来试试。

单击OK,完成此部分设置,接下来我们还需要在Utilities选项卡里面设置下载时的目标编程器,如下图所示:

图3-26 FLASH 编程器选择

上图中,我们选择J-LINK来调试Cortex-M3,然后点击Settings,设置如下图所示:

- 26 - 东南大学成贤学院毕业论文

图3-27 编程设置

这里要根据不同的MCU选择FLASH的大小,因为我们开发板使用的是STM32F103RBT6,其FLASH大小为128K,所以我们在Programming Algorithm里面选择128K型号的STM32。然后选中Reset and

Run,以实现在编程后自动启动。其他默认设置即可。

在设置完之后,点击OK,然后再点击OK,回到IDE界面,编译一下工程。再点击真(如果开发板的代码没被更新过,则会先更新代码,再仿真,你也可以通过按下图所示:

,开始仿,只下载代码,而不进入仿真,特别注意:开发板上的B0要设置到GND,否则代码下载后不会自动运行的!),如

图3-28 开始仿真

可以看到都是一些汇编码的查看,如果我们要快速运行到main函数,可以在main函数的第一句语句处放入断点,然后点击,来快速执行到该处。如下图所示:

- 27 - 东南大学成贤学院毕业论文

图3-29 程序运行到断点处

接下来,我们就可以和软件仿真一样的开始仿真了,不过这是真正的在硬件上的仿真,其结果更可信。

3.5 程序下载

STM32的程序下载有多种方法:USB、串口、JTAG、SWD等,这几种方式都可以用来给STM32下载代码。不过,我们最常用的,最经济的,就是通过串口给STM32下载代码。

STM32的串口下载一般是通过串口1 下载的,本设计的硬件板,不是通过RS232串口下载的,而是通过自带的USB串口来下载。看起来像是USB下载(只有一根USB线,并没有串口线)的,实际上,是通过USB转成串口,然后再下载的。

下面,我们就一步步实现如何在实验平台上利用USB串口来下载代码。

首先要在板子上设置一下,在板子上把RXD和PA9(STM32的TXD),TXD和PA10(STM32的RXD)通过跳线帽连接起来,这样我们就把PL2303和MCU的串口1连接上了。这里由于硬件板自带了一键下载电路,所以并不需要去关心BOOT0和BOOT1的状态,但是为了让下载完后可以按复位执行程序,要把BOOT1和BOOT0都设置为0。设置完成如下图所示:

- 28 - 东南大学成贤学院毕业论文

图3-30 开发板串口下载跳线设置

接着我们在USB_232处插入USB线,并接上电脑,如果之前没有安装PL2303的驱动(如果已经安装过了驱动,则应该能在设备管理器里面看到USB 串口,如果不能则要先卸载之前的驱动,卸载完后重启电脑(必要步骤),再重新安装我们提供的驱动),则电脑会提示找到新硬件,如下图所示:

图3-31 找到新硬件

我们不理会这个提示,直接找到光盘->软件文件夹下的PL-2303驱动,安装该驱动。在驱动安装完成之后,拔掉USB线,然后重新插入电脑,此时电脑就会自动给其安装驱动了。在安装完成之后,可以在电脑的设备管理器里面找到USB串口(如果找不到,则重启下电脑),如下图所示:

图3-32 USB 串口驱动安装成功

- 29 - 东南大学成贤学院毕业论文

上图中我们显示的USB串口为COM5,不同电脑可能不一样,可能是COM4、COM6等,但是Prolific

USB-to-Serial Comm Port,这个一定是一样的,如果没找到,则有可能是安装有误或者系统不兼容。

在安装了USB串口驱动之后,我们就可以开始串口下载程序了,这里我们的串口下载软件选择的是mcuisp,该软件属于第三方软件,由单片机在线编程网提供,大家可以去免费下载,目前最新版本为V0.993。该软件启动界面如下:

图3-33 mcuisp 启动界面

然后我们选择要下载的HEX文件,以前面我们新建的工程为例,因为我们前面的工程没有在KEIL里面设置生成.hex文件,所以在USER文件夹下是找不到.hex文件的。下面我们看看如何设置:先在工程里面点击,打开Output选项卡,勾选Create HEX File选项,如下图所示:

图3-34 MDK 设置生成HEX 文件

图中选中第二个红圈内的选项,可以使编译器产生浏览信息,方便快速查看函数和变量等,这点在后面会介绍。选中之后点击OK,重新编译,编译结果如下图所示:

- 30 - 东南大学成贤学院毕业论文

图3-35 重新编译结果

从上图中可以看到,编译器已经产生了hex文件了,然后我们打开USER文件夹,看看里面发生了什么变化?如下图所示:

图3-36 新编译生成文件

从上图可以看到,重新编译产生了很多文件,其中就有我们所需要的hex文件(图中红圈圈中),至此,我们就可以开始下载了。用mcuisp软件打开USER文件夹,找到,打开并进行相应设置后,如下图所示:

图3-37 mcuisp 设置

- 31 - 东南大学成贤学院毕业论文

图3-37中红圈圈中的设置,是我们建议的设置。编程后执行,这个选项在无一键下载功能的条件下是很有用的,当选中该选项之后,可以在下载完程序之后自动运行代码。否则,下载代码之后,必须先将B0连接GND,再按复位键,才能开始运行刚刚下载的代码。硬件板虽然自带了一键下载功能,但是还是建议选上这个设置。

编程前重装文件,该选项也比较有用,当选中该选项之后,mcuisp会在每次编程之前,将hex文件重新装载一遍,这对于代码调试的时候是比较有用的。

最后,我们选择的DTR 的低电平复位,RTS 高电平进BootLoader,这个选择项选中,mcuisp就会通过DTR和RTS信号来控制板载的一键下载功能电路,以实现一键下载功能。如果不选择,则无法实现一键下载功能。这个是必要的选项(在BOOT0 接GND 的条件下)。

在装载了hex文件之后,我们要下载代码还需要选择串口,这里mcuisp 有智能串口搜索功能。每次打开mcuisp软件,软件会自动去搜索当前电脑上可用的串口,然后选中一个作为默认的串口(一般是您最后一次关闭时所选则的串口)。也可以通过点击菜单栏的搜索串口,来实现自动搜索当前可用串口。串口波特率则可以通过bps那里设置,对于STM32,该波特率最大为230400bps,这里我们一般选择最高的波特率:460800,让mcuisp 自动去同步。搜索完串口之后界面如下图所示:

图3-38 搜索串口

从之前USB串口的安装可知,开发板的串口被识别为COM5了,所以我选择COM5。选择了相应串口之后就可以通过按”开始编程(P)”这个按钮,一键下载代码到STM32上,下载成功后如下图所示:

- 32 - 东南大学成贤学院毕业论文

图3-39 下载完成

上图中,我用圈圈圈出了mcuisp对一键下载电路的控制过程,其实就是控制DTR和RTS电平的变化,控制BOOT0和RESET,从而实现自动下载。另外界面提示已经下载完成(如果老提示:开始连接„,需要检查一下,开发板的设置是否正确,是否有其他因素干扰等),并且从0X80000000处开始运行了,我打开串口调试助手选择COM5,会发现从硬件板发回来的信息,如下图所示:

图3-40 程序开始运行了

接收到的数据和我仿真的是一样的,证明程序没有问题。至此,说明下载代码成功了,并且也从硬件上验证了代码的正确性。

- 33 - 东南大学成贤学院毕业论文

第四章 程序设计与调试

4.1 系统描述

本系统采用基于ARM Cortex-M3内核的STM32作为主控制器,外扩SD卡以及TFT彩屏。系统通过文件系统读取SD卡内存储的BMP、JPEG、JPG格式图片,把多幅图片以幻灯片的形式从TFT屏上显示出来。同时,通过STM32内部的RTC模块使系统具有掉电不遗失日期及时钟的功能。系统框图如图4-1所示。

图4-1 系统框图

4.2 软件设计

4.2.1 文件读取

本设计需要用到FAT(FAT16/32)文件系统来读取SD 卡上的字库和UNICODE到GBK的转换码表到W25X16部分,因此要重点介绍FAT文件系统。FAT文件系统本身比较复杂,所以这里只简单介绍一下。

常用的文件系统有FAT12/16/32等,FAT12是最古老的文件系统,只能管理8M左右的空间,现在基本淘汰了。FAT16则可以管理2G的空间(通过特殊处理也能管理2G以上的空间),而FAT32则能管理到2TB(2048GB)的空间。FAT32较FAT16的优势还在于FAT32采用了更小的簇,可以更有效的保存信息,而不会造成较多的浪费。

XP在SD卡里面建立的文件系统最常用的也就是FAT16和FAT32。这是由XP在格式化SD卡的时候建立的,通常SD卡上的数据信息由MBR、DBR、FAT、FDT和数据区5个部分组成(有的也没有MBR)。我们以FAT32为例做介绍。

MBR称为主引导记录区,该区存储了分区表等信息,位于SD卡的扇区0(物理扇区),在其分区信息里面记录了DBR 所在的位置,SD卡一般只会有一个分区,所以也就只要找到分区1的DBR 所在位置就可以了。

DBR称为操作系统引导记录区,如果没有MBR,那么DBR就位于0扇区,如果有则必须通过MBR区得到DBR所在的地址,然后读出DBR信息。在DBR区,我们可以知道每个扇区所占用的字节数、每个簇的扇区数、FAT表的份数、每个FAT表的扇区数、跟目录簇号、FAT表1所在的扇区等一系列非常重要的信息。

FAT称为文件分配表(FAT表),一般一个卡上会存在2个FAT表,一个用作备份,一个用作使用。FAT表一般紧随DBR,另一个FAT表则紧随第一个FAT表,这样只要知道了第一个FAT表的位置及大小,那么第二个FAT表的位置也就确定了。FAT表记录了每个文件的位置和区域,是一种链式结构,FAT以“F8 FF FF 0F FF FF FF FF”这样的8个字节为表头,用以表示FAT表的开始,后面的数据每四个字节为一个簇项(从第2簇开始),用来标记下一个簇所在的位置,这样每个位置都存储了下一个簇,只要按着这个表走,就可以找到文件的所有内容。如果找到下一个簇位置,里面记录的是“FF FF FF 0F”,代表这个文件到此就结束了,没有后续簇了,这样一个文件的读取就结束- 34 - 东南大学成贤学院毕业论文

了。

FDT称为文件根目录表,这个区域固定为32个扇区,假设每个扇区为512个字节,那么更目录下最多存放512个文件(假设都用短文件名存储,每个短文件名占32个字节)。

文件目录表是另一个重要的部分,FAT文件系统中(仅以短文件名介绍),文件目录项在目录表下以32个字节的方式记录,各字段定义如下:

表4.1 文件目录项各字节定义

从上表可知,我们在文件的目录项就可以找到该文件的其实簇,然后在FAT表里面找到该簇开始的下一个簇,依次读取这些簇就可以把整个文件读出来了。

4.2.2 图像解码与显示

4.2.2.1 BMP文件格式

BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。

部分代码:

//BMP信息头

typedef __packed struct

{

DWORD biSize ;

LONG biWidth ;

LONG biHeight ;

WORD biPlanes ;

//说明BITMAPINFOHEADER结构所需要的字数。

//说明图象的宽度,以象素为单位

//说明图象的高度,以象素为单位

//为目标设备说明位面数,其值将总是被设为1

WORD biBitCount ; //说明比特数/象素,其值为1、4、8、16、24、或32

DWORD biCompression ; //说明图象数据压缩的类型。其值可以是下述值之一:

DWORD biSizeImage ;//说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0

- 35 - 东南大学成贤学院毕业论文

LONG biXPelsPerMeter ;//说明水平分辨率,用象素/米表示

LONG biYPelsPerMeter ;//说明垂直分辨率,用象素/米表示

DWORD biClrUsed ; //说明位图实际使用的彩色表中的颜色索引数

DWORD biClrImportant ; //说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

} BITMAPINFOHEADER ;

//BMP头文件

typedef __packed struct

{

WORD bfType ; //文件标志.只对'BM',用来识别BMP位图类型

DWORD bfSize ; //文件大小,占四个字节

WORD bfReserved1 ;//保留

WORD bfReserved2 ;//保留

DWORD bfOffBits ; //从文件开始到位图数据(bitmap data)开始之间的的偏移量

}BITMAPFILEHEADER ;

//彩色表

typedef __packed struct

{

BYTE rgbBlue ; //指定蓝色强度

BYTE rgbGreen ; //指定绿色强度

BYTE rgbRed ; //指定红色强度

BYTE rgbReserved ;//保留,设置为0

}RGBQUAD ;

//位图信息头

typedef __packed struct

{

//解码这个BMP文件

{

u16 count;

u8 rgb ,color_byte;

u16 x ,y,color,tmp_color ;

u16 uiTemp; //x轴方向像素计数器

u16 countpix=0;//记录像素

u8 realx=0;

- 36 -

BITMAPFILEHEADER bmfHeader;

BITMAPINFOHEADER bmiHeader;

}BITMAPINFO;

BOOL BmpDecode(FileInfoStruct *BmpFileName)

u16 realy=0; //x,y的实际坐标

u8 yok=1;

BITMAPINFO *pbmp;//临时指针 东南大学成贤学院毕业论文

CurFile=BmpFileName;

F_Open(CurFile);//打开文件

F_Read(CurFile,jpg_buffer);//读出512个字节

pbmp=(BITMAPINFO*)jpg_buffer;//得到BMP的头部信息

count=pbmp->its; //数据偏移,得到数据段的开始地址

color_byte=pbmp->ount/8;//彩色位 16/24/32

ght=pbmp->ht;//得到图片高度

th=pbmp->h; //得到图片宽度

//水平像素必须是4的倍数!!

if((th*color_byte)%4)

uiTemp=((th*color_byte)/4+1)*4;

uiTemp=th*color_byte;

else

AI_Drow_Init();//初始化智能画图

//开始解码BMP

x =0 ;

y=ght;

rgb=0;

realy=y*_Fac/10000;

while(1)

{

{

if(color_byte==3) //24位颜色图

{

switch (rgb)

{

case 0:

tmp_color = jpg_buffer[count]>>3 ;

color |= tmp_color;

break ;

tmp_color = jpg_buffer[count]>>2 ;

tmp_color <<= 5 ;

color |= tmp_color ;

break;

tmp_color = jpg_buffer[count]>>3 ;

tmp_color <<= 11 ;

color |= tmp_color ;

break ;

- 37 -

while(count<512) //读取一簇512扇区 (SectorsPerClust 每簇扇区数)

case 1:

case 2 :

} 东南大学成贤学院毕业论文

}

else

{

if(color_byte==2) //16位颜色图

{

}

else

{

if(color_byte==4)//32位颜色图

{

switch (rgb)

{

case 0 :

tmp_color=jpg_buffer[count];

color|=tmp_color>>3;

break ;

tmp_color=jpg_buffer[count];

tmp_color>>=2;

color|=tmp_color<<5;

break ;

tmp_color=jpg_buffer[count];

tmp_color>>=3;

color|=tmp_color<<11;

break ;

- 38 -

switch(rgb)

{

case 0 :

color=jpg_buffer[count]&0x1f;

tmp_color<<=6;

color|=tmp_color;

break ;

tmp_color=jpg_buffer[count];

tmp_color<<=9 ;

color |= tmp_color ;

break ;

tmp_color=jpg_buffer[count]>>5;

case 1 :

}

case 1 :

case 2 :

case 3 :break ;

} 东南大学成贤学院毕业论文

的值

}

}

}

}

}//位图颜色得到

rgb++;

count++ ;

{

}

countpix++;//像素累加

if(countpix>=uiTemp)//水平方向像素值到了.换行

{

y--;

if(y<=0)return TRUE;

realy=y*_Fac/10000;//实际y值改变

if(IsElementOk(realx,realy,0))yok=1;/此处不改变x,yelse yok=0;

x=0;

countpix=0;

color=0x00;

rgb=0;

if(x

{

}

x++;//x轴增加一个像素

color=0x00;

rgb=0;

}

realx=x*_Fac/10000;//x轴实际值

if(IsElementOk(realx,realy,1)&&yok)//符合条件

{

POINT_COLOR=color;

if(rgb==color_byte) //水平方向读取到1像素数数据后显示

LCD_DrawPoint(realx+PICINFO.S_XOFF,realy+PICINFO.S_YOFF-1);

}

if(!F_Read(CurFile,jpg_buffer))break;//读出512个字节,读数失败时自动退出

count=0 ;

}

return TRUE;//BMP显示结束.

4.2.2.2 JPEG文件格式

- 39 - 东南大学成贤学院毕业论文

JPEG 是Joint Photographic Experts Group(联合图像专家组)的缩写,文件后辍名为".jpg"或".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以把1.37MB的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找到平衡点。JPEG 格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。

JPEG/JPG 的解码过程可以简单的概述为如下几个部分:

1、从文件头读出文件的相关信息。

JPEG文件数据分为文件头和图像数据两大部分,其中文件头记录了图像的版本、长宽、采样因子、量化表、哈夫曼表等重要信息,所以解码前必须将文件头信息读出,以备图像数据解码过程之用。

2、从图像数据流读取一个最小编码单元(MCU),并提取出里边的各个颜色分量单元。

3、将颜色分量单元从数据流恢复成矩阵数据。

利用文件头给出的哈夫曼表,对分割出来的颜色分量单元进行解码,把其恢复成8×8的数据矩阵。

4、8×8的数据矩阵进一步解码。

此部分解码工作以8×8的数据矩阵为单位, 其中包括相邻矩阵的直流系数差分解码、利用文件头给出的量化表反量化数据、反Zig-zag编码、隔行正负纠正、反向离散余弦变换等5个步骤,最终输出仍然是一个8×8的数据矩阵。

5、颜色系统YCrCb向RGB转换。

将一个MCU的各个颜色分量单元解码结果整合起来,将图像颜色系统从YCrCb向RGB转换。

6、排列整合各个MCU的解码数据。

不断读取数据流中的MCU并对其解码,直至读完所有MCU为止,将各MCU解码后的数据正确排列成完整的图像。JPEG的解码本身是比较复杂的。

部分代码:

//调用顺序: Initialize_Fast_IDCT() :初始化

// DecodeMCUBlock() Huffman Decode

// IQtIZzMCUComponent() 反量化、反DCT

// GetYUV() Get Y U V

// StoreBuffer() YUV to RGB

int Decode(void)

{

int funcret;

Y_in_MCU=SampRate_Y_H*SampRate_Y_V;//YDU YDU YDU YDU

U_in_MCU=SampRate_U_H*SampRate_U_V;//cRDU

V_in_MCU=SampRate_V_H*SampRate_V_V;//cBDU

H_YtoU=SampRate_Y_H/SampRate_U_H;

- 40 - 东南大学成贤学院毕业论文

V_YtoU=SampRate_Y_V/SampRate_U_V;

H_YtoV=SampRate_Y_H/SampRate_V_H;

V_YtoV=SampRate_Y_V/SampRate_V_V;

Initialize_Fast_IDCT();

//The Digital has been Huffman Decoded andbe stored in

//MCUBuffer(YDU,YDU,YDU,YDU,UDU,VDU) Every DU := 8*8

while((funcret=DecodeMCUBlock())==FUNC_OK) //After Call DecodeMCUBUBlock()

{ interval++;

if((restart)&&(interval % restart==0))

IntervalFlag=TRUE;

else

IntervalFlag=FALSE;

IQtIZzMCUComponent(0); //反量化 and IDCT The Data in QtZzMCUBuffer

IQtIZzMCUComponent(1);

IQtIZzMCUComponent(2);

GetYUV(0);

GetYUV(1);

GetYUV(2);

StoreBuffer(); //To RGB

sizej+=SampRate_Y_H*8;

if(sizej>=th)

{ sizej=0;

sizei+=SampRate_Y_V*8;

}

if((sizej==0)&&(sizei>=ght))break;

}

return funcret;

}

//智能画图

//FileName:要显示的图片文件 BMP/JPG/JPEG

//(sx,sy) :开始显示的坐标点

//(ex,ey) :结束显示的坐标点

//图片在开始和结束的坐标点范围内显示

BOOL AI_LoadPicFile(FileInfoStruct *FileName,u16 sx,u16 sy,u16 ex,u16 ey)

{

int funcret;//返回值

//得到显示方框大小

//得到Y cR cB

if(ey>sy)PICINFO.S_Height=ey-sy;

else PICINFO.S_Height=sy-ey;

else PICINFO.S_Width=sx-ex;

//显示区域无效

- 41 -

if(ex>sx)PICINFO.S_Width=ex-sx; 东南大学成贤学院毕业论文

if(PICINFO.S_Height==0||PICINFO.S_Width==0)

{

}

//显示的开始坐标点

PICINFO.S_YOFF=sy;

PICINFO.S_XOFF=sx;

CurFile=FileName; //文件名传递

if(CurFile->F_Type==T_BMP)//得到一个BMP图像

{ funcret=BmpDecode(CurFile); //得到一个BMP图像

}

else if(CurFile->F_Type==T_JPG||CurFile->F_Type==T_JPEG)//得到JPG/JPEG图片

{ F_Open(CurFile); //得到JPEG/JPG图片的开始信息

//开始时读入1024个字节到缓存里面.方便后面提取JPEG解码的信息

F_Read(CurFile,jpg_buffer); //读第一次

F_Read(CurFile,jpg_buffer+512);//读第二次

InitTable(); //初始化各个数据表

if((funcret=InitTag())!=FUNC_OK)return FALSE;//初始化表头不成功

if((SampRate_Y_H==0)||(SampRate_Y_V==0))return FALSE ;//采样率错误

AI_Drow_Init(); //初始化_Fac,启动智能画图

funcret=Decode();//解码JPEG开始

return funcret;

PICINFO.S_Height=LCD_H;

PICINFO.S_Width=LCD_W;

return FALSE;

}else return FALSE; //非图片格式!!!

if(funcret==FUNC_OK)return TRUE;//解码成功

else return FALSE; //解码失败

}

此部分代码包含了JPEG/JPG以及BMP的解码代码,解码通过AI_LoadPicFile( )函数来实现,在该函数里面先判断文件的类型,然后调用不同的解码函数,解码JPEG由Decode( )函数实现,而解码BMP 则由BmpDecode( )函数实现。AI_LoadPicFile( )函数会将图片以合适的大小显示在液晶上(总是不会超过你给定的区域),对比输入尺寸大的图片,会自动压缩。解码图片完成后返回解码是否成功的信息。

4.2.3 时钟显示

实时时钟(RTC)是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操作,所以在要设置时间之前,先要取消备份区域(BKP)写保护。

RTC由两个主要部分组成(见下图4.2)。第一部分(APB1接口)用来和APB1总线相连。此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作。APB1接口由APB1总线时钟驱动,用来与APB1总线连接。

- 42 - 东南大学成贤学院毕业论文

另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是RTC的预分频模块,它可编程产生最长为1秒的RTC 时间基准TR_CLK。RTC的预分频模块包含了一个20位的可编程分频器(RTC 预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编程计数器,可被初始化为当前的系统时间,一个32位的时钟计数器,按秒钟计算,可以记录4294967296秒,约合136年左右,作为一般应用,这已经是足够了的。

RTC还有一个闹钟寄存器RTC_ALR,用于产生闹钟。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。

图4-2 RTC简化框图

RTC内核完全独立于RTC APB1接口,而软件是通过APB1接口访问RTC的预分频值、计数器值和闹钟值的。但是相关可读寄存器只在RTC APB1 时钟进行重新同步的RTC时钟的上升沿被更新,RTC 标志也是如此。这就意味着,如果APB1接口刚刚被开启之后,在第一次的内部寄存器更新之前,从APB1上的RTC寄存器值可能被破坏了(通常读到0)。因此,若在读取RTC寄存器曾经被禁止的RTC APB1接口,软件首先必须等待RTC_CRL寄存器的RSF位(寄存器同步标志位,bit3)被硬件置1。

接下来,我们介绍一下RTC相关的几个寄存器。首先要介绍的是RTC的控制寄存器,RTC总共有2个控制寄存器RTC_CRH和RTC_CRL,两个都是16位的。RTC_CRH的各位描如下

- 43 - 东南大学成贤学院毕业论文

图4-3 寄存器RTC_CRH 各位描述

该寄存器用来控制中断的,我们将要用到秒钟中断,所以该寄存器必须设置最低位为1,以允许秒钟中断。我们再看看RTC_CRL寄存器。该寄存器各位描述如下图所示:

图4-4 寄存器RTC_CRL 各位描述

本设计我们用到的是该寄存器的0、3~5这几个位,第0位是秒钟标志位,我们在进入闹钟中断的时候,通过判断这位来决定是不是发生了秒钟中断。然后必须通过软件将该位清零(写0)。第3位为寄存器同步标志位,我们在修改控制寄存器RTC_CRH/CRL之前,必须先判断该位,是否已经同- 44 -

2023年12月8日发(作者:闽志义)

毕业设计报告(论文)

题目:基于STM32的数码相框系统

设计与实现(软件)

所属系 电子工程系

专 业 自 动 化

设计地点 东南大学成贤学院

东南大学成贤学院毕业设计报告(论文)

诚 信 承 诺

本人承诺所呈交的毕业设计报告(论文)及取得的成果是在导师指导下完成,引用他人成果的部分均已列出参考文献。如论文涉及任何知识产权纠纷,本人将承担一切责任。

学生签名:

日 期:

基于STM32的数码相框系统设计与实现(软件)

摘 要

本设计是一款基于嵌入式硬件平台的数码相框,主控芯片为基于ARM Cortex-M3内核的STM32系列嵌入式处理器,本设计包含主控制器核心板、LCD液晶显示、SD卡存储器等多个功能模块。实现对SD卡里多幅图片以幻灯片形式在TFT屏上动态显示的效果,且带有实时时钟的功能。

关键词:嵌入式;数码相框;Cortex-M3

- I - The design of digital photo frames based on the STM32

Abstract

The design is a digital photo frame-based embedded hardware platform ,whose main chip for the

STM32 family of embedded processors based on ARM Cortex-M3 core . The design includes a host

controller core board, LCD display, SD card memory and other functional modules. It can achieve the

effect of multiple images of the SD card as a slide show on the TFT screen dynamic display, and with

real-time clock function.

Keywords:Embedded; Digital Photo Frame; Cortex-M3

- II - 目 录

摘 要 ............................................................................. I

ABSTRACT .......................................................................... II

第一章 引 言 ...................................................................... 1

1.1

课题研究意义 .................................................................. 1

1.2

数码相框的发展情况和趋势 ...................................................... 1

1.2.1 数码相框的发展现状 ........................................................ 1

1.2.2 数码相框的发展趋势 ........................................................ 2

1.3

本课题设计主要研究内容 ........................................................ 2

1.4

主要章节安排 .................................................................. 3

第二章 硬件介绍 .................................................................... 4

2.1

嵌入式系统概况 ................................................................ 4

2.1.1 嵌入式系统的定义 .......................................................... 4

2.1.2 嵌入式系统的组成 .......................................................... 4

2.1.3 嵌入式系统的特点 .......................................................... 5

2.2

数码相框模块 .................................................................. 5

2.2.1 MCU主控模块 .............................................................. 5

2.2.2 LCD模块 .................................................................. 6

2.2.3 SD存储卡模块 ............................................................. 9

第三章 编程环境介绍................................................................ 12

3.1

RVMDK3.80A简介 .............................................................. 12

3.2

新建RVMDK工程 ............................................................... 12

3.3

软件仿真 ..................................................................... 19

3.4

在线调试 ..................................................................... 24

3.4.1 J-link简介 .............................................................. 24

3.4.2 J-link调试步骤 .......................................................... 25

3.5

程序下载 ..................................................................... 28

第四章 程序设计与调试.............................................................. 34

4.1

系统描述 ..................................................................... 34

4.2

软件设计 ..................................................................... 34

4.2.1 文件读取 ................................................................ 34

4.2.2 图像解码与显示 ........................................................... 35

4.2.3 时钟显示 ................................................................ 42

4.2.4 主程序设计............................................................... 52

4.3

程序调试 ..................................................................... 57

第五章 结束语 ..................................................................... 59

致 谢 ............................................................................ 60

参考文献(REFERENCES).............................................................. 1

附录 数码相框原理图................................................................. 2

- III - 东南大学成贤学院毕业论文

第一章 引 言

1.1 课题研究意义

嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一。嵌入式系统用在一些专用设备上,通常这些设备的硬件资源(如处理器、存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高。特别是随着消费家电的智能化,嵌入式更显重要。像我们平常常见到的手机、PDA、电子字典、可视电话、VCD/DVD/MP3播放器、数码相机、数字摄像机、U-Disk、机顶盒、高清电视、游戏机、智能玩具、交换机、路由器、数控设备、汽车电子、家电控制系统、医疗仪器、航天航空设备等都是典型的嵌入式产品。

数字摄影的兴起不可避免地引起了数码相框的发展,因为仅有不到35%的数码照片被打印出来。数码相框的基本原理就是采用普通相框的造型,把原来相框中间的照片部分换成液晶显示屏,配上电源,存储介质等,使得同一个相框内可以循环播放照片,比普通照片的单一显示功能更有优势。从2007年开始,数码相框的市场关注度开始激增。在2008年,数码相框市场呈现高速发展的态势,本课题的研究具有极高的潜在市场价值。

此外,本设计属于数字影音娱乐产品,需要较为强劲的处理器进行图像解码的工作,而STM32 具有超低的价格、超多的外设、丰富的型号、优异的实时性能、杰出的功耗控制和极低的开发成本等特点。因此,进行基于STM32平台的数码相框系统的设计具有重要的理论意义和实用价值。

1.2 数码相框的发展情况和趋势

1.2.1 数码相框的发展现状

数码相框产品是2001年开始出现的,但由于当时消费者的接受度及价格过高的因素,使这一市场一直到2003年都很低迷。随着主要器件价格的下降,数码相框的价格也逐步下降,市场在2004年开始有了起色,尤其在2005年,数码相框产品开始在欧美热销,但出货量也只有150万台左右,到了2006年的出货量同比上涨133%,为280万台,2007年的出货量同比上涨185%,为800万台,预计到2011年出货量将达到4000万台。从屏幕尺寸来看,2006年5-6.9英寸产品占主流,2007年7、8、9英寸产品成为最大市场。预计2011年,7、8、9英寸产品的供货比例将持续保持首位,而平均销售单价将以每年16.5%左右的速度降低。

2006年以前,中国生产的数码相框绝大多数出口国外。2005年底Philips率先将数码相框在中国推广,在礼品市场上取得了一些成绩,但由于销售价格较高,约为2050元/台,这一年中国数码相框的销售量仅有1.7万台。2006年下半年,开始有更多的国内厂商在中国市场推出数码相框,因而也带动了此产品价格的下降,这一年的平均售价为1150元/台,仍然较高,市场也以商务礼品为主,但由于2005年销售量的基数较低,2006年的销售量同比增长了470.6%,达到9.7万台。直到2007年下半年,业界才感到这个一直处于培育期的市场,开始了真正的起飞。这得益于对数码相框产品认知度的提高、价格的下滑和需求量的提高。

从IT厂商来看,仅2007年下半年以来,就有惠普、三星、优派、AOC、明基、柯达、长城等众多新军加入数码相框阵营。其中,巨头惠普2007年7月底在美国宣布进入数码相框市场,2007年数码相框出货量设定为50万台。除新军外,数码相框老牌劲旅的出货量表现也令业界振奋,如飞利浦2006年数码相框出货量达到50万台,而2007年上半年出货量已达去年总和,2007年全年出货量达150万台。而从上游面板厂商的动作来看,也显示出乐观的发展态势。中华映管、群创等厂商均显著调高了配套数码相框产品的中尺寸面板的出货量目标,2007年出货量达1000万台,预计2008- 1 - 东南大学成贤学院毕业论文

年更将倍增至2000万台。其中,中华映管目前已调配一座4.5代面板厂来支持生产中尺寸面板,主要生产可携式DVD播放机面板与数码相框面板,其数码相框面板以7英寸、8英寸、10.2英寸为主要尺寸,数码相框面板占其中尺寸面板的比重提高到40%。

1.2.2 数码相框的发展趋势

从长远来看,2008年及今后几年将为处在数码相框产品供应链的各企业带来巨大的商机。未来几年,数码相框的市场将处在逐渐走向成熟期的阶段,其产销量和市场需求依然将保持大幅度的增长,在未来的三年内,市场尚无萎缩的可能。但数码相框拓展中国市场需克服两大难点:一是价格;二是拓展应用空间。价格下降是必然趋势,中国消费者接受只是时间的问题,而根据中国消费者的需求和特点,开发出相应的应用产品,则是需要数码相框厂商亟待解决的问题。

从技术上来说,未来数码相框的发展将向两极分化。一部分产品着重强调基本功能和低成本,整合家庭中的闹钟、日历和装饰功能,这些产品走的是低成本路线,以展示照片为主,追求图像的品质及幻灯片播放特效,已成为DC/DV的附属物;另一部分产品将会添加一些新的功能,如WiFi,还可即时报告天气、股票等信息,从而有望成为“桌面信息中心”。此外,触摸面板会成为一个应用的新亮点。

从产品形态上来说,数码相框的市场将会有非常明确的细分。

1 数码相框:

这将是以数字照片的重显为主要功能的产品,其功能更接近于传统意义上的相框。

由于人机界面的限制,为了更方便的重显和浏览以及确定重显的规则,这类产品并不强调有大容量的内存以及丰富的存储卡接口,这类产品的主要特征是:

1) 支持USB Device&Host以便于更新和同步数据。

2) 在某些情况下(如从PC端通过相框的USB Device同步数据),允许修改数字照片的格式使得有最佳的重显效果。

3) 仅依靠内置的半导体存储器存放需要重显的数字照片。

4) 文件(照片)查询和播放规则设定非常简洁易用。

5) 产品大致分为桌面和壁挂两种。

2 数码相册:

这是以数字照片的存储和浏览为主要功能的产品,由于需要满足跟PC相类似功能,所以这类产品的主要特征是:

1) 有大容量的内置数据存储器。

2) 支持USB Device&Host及各种存储卡接口,并支持内部存储器与各种数据存储器之间的同步以及相互拷贝。

3) 强大的文件管理功能:浏览,搜寻,命名(重命名),复制,删除,备份等。

4) 带或不带内建显示单元,有能支持其它高分辨率显示设备的接口(如色差,VGA甚至是HDMI)。

1.3 本课题设计主要研究内容

本课题是基于ARM单片机STM32F103RBT6的存储程序控制,从SD卡读取图片,解码后输出到TFT-LCD上显示,同时通过按键可以切换到时间模式。

1)硬件电路原理图的绘制(见附录);

2)硬件资料的研究;

3)软件方案的选择与论证;

4)软件运行与调试;

- 2 - 东南大学成贤学院毕业论文

1.4 主要章节安排

第一章 就课题研究的背景与意义以及发展现状与趋势做出说明;

第二章 概要性地介绍了嵌入式系统的基本知识;

第三章 详细地介绍了软件编程与下载环境;

第四章 程序设计与调试;

第五章 结束语;

致 谢 在软件设计过程中给予我无限帮助的老师和同学;

参考文献 列出本次设计中参阅的相关资料;

附 录 在设计过程中所参考的部分资料及硬件装置的部分资料。

- 3 - 东南大学成贤学院毕业论文

第二章 硬件介绍

2.1 嵌入式系统概况

2.1.1 嵌入式系统的定义

虽然嵌入式系统是近几年才风靡起来的,但其历史可追溯到20世纪70年代。经过30多年的发展,在硬件和软件交替发展的支撑下,嵌入式技术逐渐趋于稳定和成熟,已被广泛应用于工业控制、交通管理、信息家电、家庭智能管理系统、POS网络及电子商务、环境检测、机器人等各个领域。毫不夸张的说,嵌入式系统已经无所不在,所以研究和开发嵌入式系统有着十分重要的意义。

根据IEEE(国际电气和电子工程师协会)的定义,嵌入式系统是“控制、监视或辅助设备、机器和车间运行的装置”,这主要是从应用上加以定义的。不过,上述定义并不能充分体现出嵌入式系统的精髓。目前,国内一个普遍被认同的定义是:以应用为中心、以计算机为基础,软、硬件可裁减,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。

广义地讲,凡是不用于通用目的的可编程计算机设备,就可以算是嵌入式计算机系统。狭义上而言,嵌入式系统是指以应用为核心,以计算机技术为基础,软硬件可裁剪,适于应用系统对功能、可靠性、成本、体积和功耗严格要求的专用计算机系统。

总的来说,嵌入式系统是一个外延极广的概念,凡是与产品结合在一起的、具有嵌入式系统特点的系统都可以称为嵌入式系统。可以从以下几个方面来理解嵌入式系统的含义:

嵌入式系统是面向用户、面向产品、面向应用的,必须与具体应用相结合才会具有生命力。正因为与具体应用的紧密结合,嵌入式系统才具有很强的专用性。

嵌入式系统将先进的半导体技术、计算机技术和电子技术,以及各个行业的具体应用相结合,是一个技术密集、资金密集、学科交叉和不断创新的知识集成系统。

嵌入式系统必须根据应用需要对硬件和软件进行裁剪,以满足应用系统对功能、可靠性、成本、体积和功耗的要求。

2.1.2 嵌入式系统的组成

通常来说,嵌入式系统可以划分成硬件和软件两部分。嵌入式硬件由嵌入式微处理器、片内周边电路和外部设备三部分组成。嵌入式微处理器是嵌入式硬件系统的核心,直接影响嵌入式产品的应用范围和开发复杂度。典型的嵌入式微处理器有Motorola公司的Power PC系列、Intel公司的Strong Arm系列、AMD公司的X86系列以及EPSON公司的SIC33系列等。嵌入式软件一般由连接硬件和应用程序的嵌入式实时操作系统(Real-time operating System,简称RTOS)和在其上运行的应用软件构成。

①嵌入式处理器

嵌入式处理器是嵌入式系统的核心部件,是控制、辅助系统运行的硬件单元,其功能和性能影响着整个系统的功能、性能和设计。嵌入式处理器的选择也制约着其配套的外围器件及操作系统的选择。

嵌入式处理器的种类繁多、数量庞大。目前世界上嵌入式处理器的种类数量已经超过1000种,流行的体系结构有30多个系列。嵌入式微处理器具有体积小、重量轻、成本低、可靠性高等优点,因此得到了广泛应用。目前这样的嵌入式处理器类型有ARM、MIPS、MC6800、386EX、PowerPC等系列,其中以ARM的应用最为广泛。

嵌入式处理器可以分为四类,即

嵌入式微处理器(Embedded Microprocessor Unit,EMPU),如ARM

- 4 - 东南大学成贤学院毕业论文

嵌入式微控制器(Microcontroller Unit,MCU)

嵌入式DSP处理器(Embedded Digital Signal Processor,EDSP)

嵌入式片上系统(System On Chip)

②嵌入式外围设备

这里所说的嵌入式外围设备,指在一个嵌入式硬件系统中,.除了中心控制部件(MCU,DSP,EMPU,SOC)以外的完成存储、通信、保护、调试、显示等辅助功能的其他部件。根据外围设备的功能可分为以下三类,即:

存储器类型:静态易失型存储器(RAM,SRAM)、动态存储器(DRAM)、非易失型存储器(ROM,EPROM,EEPROM,FLASH)。其中,因为FLASH可以擦写多次,存储速度快,容量大,价格便宜在嵌入式领域应用广泛。

接口类型:目前存在的所有接口在嵌入式领域都应用广泛,如RS-232(串口)、IRDA(红外线接口)、SPI(串行外围设备接口)、I2C(现场总线接口)、USB(通用串行接口)、Ethernet(以太接口)和普通并口。

显示类型:CRT,LCD和触摸屏等外围设备。

2.1.3 嵌入式系统的特点

嵌入式系统具有以下几个重要特征:

①系统内核小,由于嵌入式系统一般应用于小型电子装置,系统资源相对有限,所以内核较之传统的操作系统要小得多。比如,ENEA公司的OSE分布式系统,内核只有5KB,而Windows的内核则要大得多。

②专用性强,嵌入式系统的个性化很强,其中的软件系统和硬件结合非常紧密,一般要针对硬件进行系统的移植,同时针对不同的任务,往往需要对系统进行较大的更改。另外,程序的编译下载要和系统相结合。

③嵌入式系统一般没有系统软件和应用软件的明显区分,不要求其功能的设计及实现过于复杂,这样既利于控制系统成本,也利于实现系统安全。

④高实时性的操作系统软件是嵌入式软件的基本要求,而且软件要求固化存储,以提高速度,软件代码要求高质量和高可靠性。

⑤嵌入式软件开发要想走向标准化,就必须使用多任务操作系统。嵌入式系统的应用程序可以没有操作系统而直接在芯片上运行,但为了更合理的调度多任务,利用系统资源、系统函数,用户必须自行选配RTOS开发平台。

⑥执行的实时性、可靠性,并减少开发时间,保障软件质量。嵌入式系统开发需要专门的开发工具和环境。由于嵌入式系统本身不具备自主开发能力,即使完成设计后,用户通常也不能对其中的程序功能进行修改,因此必须有一套基于通用计算机的开发工具和环境才能进行开发。

2.2 数码相框模块

2.2.1 MCU主控模块

STM32系列闪存微控制器是意法半导体公司(ST)基于ARM公司具有突破性的Cortex-M3内核的处理器,该处理器是专门设计于满足集高性能、低功耗、实时应用、具有竞争性价格于一体的嵌入式领域的要求。此次设计采用的具体型号是STM32F103RBT6,如图2-1所示。

- 5 - 东南大学成贤学院毕业论文

图2-1 STM32F103RBT6处理器

STM32F103RBT6嵌入式处理器具有以下特点:

32位RISC性能处理器;

32位ARM Cortex-M3结构优化;

72 MHZ运行频率,单周期访问时速度可达1.25 DMIPS/MHz;

硬件除法和单周期乘法;

快速可嵌套中断,6~12个时钟周期;

具有MPU保护设定访问规则;

片内具有256KB FLASH,48KB RAM;

80个快速I/O端口,16个I/O可映射到外部中断,几乎所有的I/O可以忍受5V电压;

片上集成12Bit A/D、D/A、PWM、CAN、USB、SDIO、FSMC等资源;

ARM Cortex-M3是一种基于ARM7v架构的最新ARM嵌入式内核,它采用哈佛结构,使用分离的指令和数据总线(冯诺伊曼结构下,数据和指令共用一条总线)。从本质上来说,哈佛结构在物理上更为复杂,但是处理速度明显加快。根据摩尔定理,复杂性并不是一件非常重要的事,而吞吐量的增加却极具价值。

除了使用哈佛结构,Cortex-M3还具有其它显著的优点:具有更小的基础内核,价格更低,速度更快。与内核集成在一起的是一些系统外设,如中断控制器、总线矩阵、调试功能模块,而这些外设通常都是由芯片制造商增加的。

Cortex-M3还集成了睡眠模式和可选的完整的八区域存储器保护单元,只支持最新的Thumb-2指令集,最大限度降低了汇编器使用率。Cortex-M3这样设计的优势在于:

免去Thumb和ARM代码的互相切换,对于早期的处理器来说,这种状态切换会降低性能。

Thumb-2指令集的设计是专门面向C语言的,且包括If/Then结构(预测接下来的四条语句的条件执行)、硬件除法以及本地位域操作。

Thumb-2指令集允许用户在C代码层面维护和修改应用程序,C代码部分非常易于重用。

Thumb-2指令集也包含了调用汇编代码的功能:Luminary公司认为没有必要使用任何汇编语言。

综合以上这些优势,新产品的开发将更易于实现,上市时间也大为缩短。STM32F103RBT6的资源完全满足此次的嵌入式数码相框设计,通过设计电路开发一个支持TFT彩色液晶屏的驱动电路,在设计中搭配2.8寸TFT真彩触摸屏模块作为显示界面,同时支持一个SD卡(SPI方式)可用于存储图片、数据等。

2.2.2 LCD模块

Thin Film Transistor(薄膜场效应晶体管),是指液晶显示器上的每一液晶象素点都是由集成在其后的薄膜晶体管来驱动。从而可以做到高速度、高亮度、高对比度显示屏幕信息,TFT-LCD(薄- 6 - 东南大学成贤学院毕业论文

膜晶体管液晶显示器)是多数液晶显示器的一种。TFT屏幕的优点如下:

大面积。九十年代初第一代大面积玻璃基板(300mm×400mm)TFT-LCD生产线投产,到2000年上半年玻璃基板的面积已经扩大到了680mm×880mm),最近950mm×1200mm的玻璃基板也将投入运行。

高集成度。用于液晶投影的1.3英寸TFT芯片的分辨率为XGA含有百万个象素。分辨率为SXGA(1280×1024)的16.1英寸的TFT阵列非晶体硅的膜厚只有50nm,以及TAB ON GLASS和SYSTEM ON GLASS技术,其IC的集成度,对设备和供应技术的要求,技术难度都超过传统的LSI。

功能强大。TFT最早作为矩阵选址电路改善了液晶的光阀特性。对于高分辨率显示器,通过0-6V范围的电压调节(其典型值0.2到4V),实现了对象元的精确控制,从而使LCD实现高质量的高分辨率显示成为可能。TFT-LCD是人类历史上第一种在显示质量上超过CRT的平板显示器。现在人们开始把驱动IC集成到玻璃基板上,整个TFT的功能将更强大,这是传统的大规模半导体集成电路所无法比拟的。

低成本。玻璃基板和塑料基板从根本上解决了大规模半导体集成电路的成本问题,为大规模半导体集成电路的应用开拓了广阔的应用空间。

工艺灵活。除了采用溅射、CVD(化学气相沉积)MCVD(分子化学气相沉积)等传统工艺成膜以外,激光退火技术也开始应用,既可以制作非晶膜、多晶膜,也可以制造单晶膜。不仅可以制作硅膜,也可以制作其他的Ⅱ-Ⅵ族和Ⅲ-Ⅴ族半导体薄膜。

应用领域广泛。以TFT技术为基础的液晶平板显示器是信息社会的支柱产业,技术可应用到正在迅速成长中的薄膜晶体管有机电致发光(TFT-OLED)平板显示器也在迅速的成长中。

TFT液晶显示屏亮度好、对比度高、层次感强、颜色鲜艳,其广泛应用于手机、MP4等消费品。因此,本系统选用2.8英寸TFT-LCD屏(如图2-2所示)可显26万色,分辨率320*240,控制器为ILI9320,采用16位的80并口,配合触摸屏专用芯片XPT2046,可对屏幕进行触摸操作,更显智能化和个性化。为了方便用户使用,我们存储方式采用兼容FAT的文件系统,同时该文件系统也兼容FAT32等电脑主流的文件系统方式进行存储。

图2-2 2.8英寸TFT-LCD模块

该模块的80 并口有如下一些信号线:

CS:TFT-LCD片选信号。

WR:向TFT-LCD写入数据。

RD:从TFT-LCD读取数据。

D[15:0]:16位双向数据线。

RST:硬复位TFT-LCD。

RS:命令/数据标志(0,读写命令;1,读写数据)。

TFT-LCD模块的RST 信号线是直接接到STM32 的复位脚上,并不由软件控制,这样可以省下来一个I/O口。另外我们还需要一个背光控制线来控制TFT-LCD的背光。所以我们总共需要的I/O口数目为21个。

模块的控制器为ILI9320(可能为其他型号,但是他们的设置很相似,除了初始化序列有些区- 7 - 东南大学成贤学院毕业论文

别,其他大都是一摸一样的,这里仅以9320为例介绍),该控制器自带显存,其显存总大小为172820(240*320*18/8),即18位模式(26万色)下的显存量。模块的16位数据线与显寸的对应关系为565方式,如下图所示:

图2-3 16位数据与显存对应关系图

最低5位代表蓝色,中间6位为绿色,最高5 位为红色。数值越大,表示该颜色越深。接下来介绍一下ILI9320的几个重要命令,因为ILI9320的命令很多,这里不一一介绍。这里我们要介绍的命令列表如下:

表2.1 ILI9320 常用命令表

R0,这个命令,有两个功能,如果对它写,则最低位为OSC,用于开启或关闭振荡器。而如果对它读操作,则返回的是控制器的型号。这个命令最大的功能就是通过读它可以得到控器的型号,而我们代码在知道了控制器的型号之后,可以针对不同型号的控制器,进行不同的初始化。因为93xx

系列的初始化,其实都比较类似,我们完全可以用一个代码兼容好几个控制器。

R3,入口模式命令。我们重点关注的是I/D0、I/D1、AM 这3 个位,因为这3 个位控制了屏幕的显示方向。

AM:控制GRAM更新方向。当AM=0的时候,地址以行方向更新。当AM=1的时候,地址以列方向更新。

I/D[1:0]:当更新了一个数据之后,根据这两个位的设置来控制地址计数器自动增加/减少1,其关系如下图:

- 8 - 东南大学成贤学院毕业论文

图2-4 GRAM 显示方向设置图

通过这几个位的设置,我们就可以控制屏幕的显示方向了。

R7,显示控制命令。该命令CL位用来控制是8位彩色,还是26万色。为0时26万色,为1时八位色。D1、D0、BASEE这三个位用来控制显示开关与否的。当全部设置为1的时候开启显示,全0是关闭。我们一般通过该命令的设置来开启或关闭显示器,以降低功耗。

R32,R33,设置GRAM的行地址和列地址。R32用于设置列地址(X 坐标,0~239),R33用于设置行地址(Y坐标,0~319)。当我们要在某个指定点写入一个颜色的时候,先通过这两个命令设置到改点,然后写入颜色值就可以了。

R34,写数据到GRAM命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。该命令是我们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要先写入命令编号,然后写入操作数。

R80~R83,行列GRAM 地址位置设置。这几个命令用于设定显示区域的大小,我们整个屏的大小为240*320,但是有时候我们只需要在其中的一部分区域写入数据,如果用先写坐标,后写数据这样的方式来实现,则速度大打折扣。此时我们就可以通过这几个命令,在其中开辟一个区域,然后不停的丢数据,地址计数器就会根据R3的设置自动增加/减少,这样就不需要频繁的写地址了,大大提高了刷新的速度。

通过以上介绍,我们可以得出TFT-LCD显示需要的相关设置步骤如下:

1)设置STM32与TFT-LCD模块相连接的I/O。

这一步,先将我们与TFT-LCD模块相连的I/O口设置为输出,具体使用哪些I/O口,这里需要根据连接电路以及TFT-LCD模块的设置来确定。

2)初始化TFT-LCD模块。

通过向TFT-LCD写入一系列的设置,来启动TFT-LCD的显示。为后续显示字符和数字做准备。

3)通过函数将字符和数字显示到TFT-LCD模块上。

这里就是通过我们设计的程序,将要显示的字符送到TFT-LCD模块就可以了,这些函数将在软件设计部分向大家介绍。通过以上三步,我们就可以使用TFT-LCD模块来显示字符和数字了,并且可以显示各种颜色的背景。

2.2.3 SD存储卡模块

SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地应用于便携式装置上,例如数码相机、个人数码助理(PDA)和多媒体- 9 - 东南大学成贤学院毕业论文

播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性,此外它可存多种格式数据文件,具有很强的可扩展性;用户可方便使用SD卡读卡器对其进行用户信息修改。2G金士顿SD卡实物如下图2-5所示。

SD卡一般支持两种操作模式:SD卡模式与SPI模式。

主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。SD卡的引脚排序如下图2-6所示:

图2-5 Kingston SD卡 图2-6 SD卡引脚排序图

SD 卡引脚功能描述如下表所示:

表2.2 SD卡引脚功能表

SD卡只能使用3.3V的I/O电平,所以,MCU一定要能够支持3.3V的I/O端口输出。在SPI 模式下,CS/MOSI/MISO/CLK都需要加10~100K左右的上拉电阻。SD卡要进入SPI模式很简单,就是在SD卡收到复位命令(CMD0)时,CS为有效电平(低电平)则SPI模式被启用。不过在发送CMD0之前,要发送>74个时钟,这是因为SD卡内部有个供电电压上升时间,大概为64个CLK,剩下的10个CLK用于SD卡同步,之后才能开始CMD0的操作,在卡初始化的时候,CLK时钟最大不能超过400KHZ。

本次硬件电路板使用的是SPI模式来读写SD卡,下面我们就重点介绍一下SD卡在SPI模式下的相关操作。

SPI模式下几个重要的操作命令,如下表所示:

表2.3 SPI模式下SD卡部分操作指令

其中 R1 的回应格式如下表所示:

- 10 - 东南大学成贤学院毕业论文

表2.4 SD卡R1回应格式

SD卡的典型初始化过程如下:

1、初始化与SD卡连接的硬件条件(MCU的SPI配置,I/O口配置);

2、上电延时(>74个CLK);

3、复位卡(CMD0);

4、激活卡,内部初始化并获取卡类型(CMD1(用于MMC卡)、CMD55、CMD41);

5、查询OCR,获取供电状况(CMD58);

6、是否使用CRC(CMD59);

7、设置读写块数据长度(CMD16);

8、读取CSD,获取存储卡的其他信息(CMD9);

9、发送8CLK后,禁止片选;

这样我们就完成了对SD卡的初始化,这里面我们一般设置读写块数据长度为512个字节,并禁止使用CRC。在完成了初始化之后,就可以开始读写数据了。

SD 卡读取数据,这里通过CMD17来实现,具体过程如下:

1、发送CMD17;

2、接收卡响应R1;

3、接收数据起始令牌0XFE;

4、接收数据;

5、接收2 个字节的CRC,如果没有开启CRC,这两个字节在读取后可以丢掉;

6、8CLK 之后禁止片选;

以上就是一个典型的读取SD卡数据过程,SD卡的写与读数据差不多,写数据通过CMD24 来实现,具体过程如下:

1、发送CMD24;

2、接收卡响应R1;

3、发送写数据起始令牌0XFE;

4、发送数据;

5、发送2字节的伪CRC;

6、8CLK之后禁止片选;

- 11 - 东南大学成贤学院毕业论文

第三章 编程环境介绍

3.1 RVMDK3.80A简介

RVMDK源自德国的KEIL公司,是RealView MDK的简称,在全球RVMDK被超过10万的嵌入式开发工程师使用。RealView MDK集成了业内最领先的技术,包括µVision3集成开发环境与RealView编译器。支持ARM7、ARM9和最新的Cortex-M3核处理器,自动配置启动代码,集成Flash烧写模块,强大的Simulation设备模拟,性能分析等功能。与ARM之前的工具包ADS1.2相比,RealView编译器具有代码更小、性能更高的优点。RealView编译器与ADS1.2的比较:代码密度方面比ADS1.2编译的代码尺寸小10%;代码性能方面比ADS1.2编译的代码性能提高20%。

现在RealView的最新版本是RVMDK4.13A,4.0以上版本的RVMDK对IDE界面进行了很大改变,并且支持Cortex-M0内核的处理器。虽然4.10界面确实是好了,支持的器件也多了,但编译效率没有3.24/3.80A高,尤其是编译后的代码执行速度(FFT运算),4.10要对速度进行-O2优化才能和3.24/3.80A的普通级别相比。另外,国内大多数单片机工程师都接触和使用过KEIL,相信大家都知道KEIL的使用是非常简单的,而且很容易入手。基于以上几点,此次选择RVMDK3.80版本的编译器来对软件进行编译。

3.2 新建RVMDK工程

首先,打开 MDK(以下简称RVMDK 为MDK)软件,再点击Project->New uVision Project菜单项,则弹出如图3-1所示界面:

图3-1 保存工程界面

新建一个文件夹 TEST,然后把工程名字设为test,点击“保存”按钮,弹出选择器件的对话框,因为我们的开发板使用的是STM32F103RBT6,所以在这里我们选择STMicroelectronics下面的STM32F103RB(如果使用的是其他系列的芯片,选择相应的型号就可以了)。如图3-2所示:

- 12 - 东南大学成贤学院毕业论文

图3-2 器件选择界面

点击OK,MDK会弹出一个对话框,问你是否加载启动代码到当前工程下面,这里我们选择是。如图3-3所示:

图3-3 提示界面

启动代码是一段和硬件相关的汇编代码,是必不可少的!这段代码的具体作用如下:①堆栈的初始化;②向量表定义;③地址重映射及中断向量表的转移;④设置系统时钟频率;⑤中断寄存器的初始化。在上面点击了是以后,MDK就把启动代码STM32F10x.s加入到了我们的工程下面。到这里,我们就可以开始编写自己的代码了。

由于上面我们还没有任何代码在工程里面,我们在TEST 目录下新建一个新文件夹USER,这里我们把系统代码复制过来(整个SYSTEM文件夹,这些代码在任何STM32F103的芯片上都是通用的,可以用于快速构建自己的工程,后面会有详细介绍)。之后,TEST文件夹下的文件如图3-4所示:

- 13 - 东南大学成贤学院毕业论文

图3-4 TEST文件夹最终摸样

然后我们在 USER 文件夹下面找到2,打开它,然后在Target目录树上右键->Manage

Components。如图3-5所示:

图3-5 调出Manage Components

在进入Manage Components界面之后,弹出如下对话框:

- 14 - 东南大学成贤学院毕业论文

图3-6 Components 选项卡

在上面对话框的中间栏,点新建(用红圈标出)按钮(也可以通过双击下面的空白处实现),新建USER 和SYSTEM两个组,然后点击Add Files按钮,把sys.c,usart.c,delay.c加入到SYSTEM组中。此时USER组下还是没有任何文件的,得到如下图所示的界面:

图3-7 修改结果

点击OK,退出该界面返回IDE。这时,我们在Target树下发现多了2个组名,就是我们刚刚新建的2个组。如下图所示:

- 15 - 东南大学成贤学院毕业论文

图3-8在编辑状态下的体现

接着,我们新建一个test.c文件,并保存在USER目录下,然后双击USER组,会弹出加载文件的对话框,此时我们在USER目录下选择test.c文件,加入到USER组下。得到如下界面:

图3-9 在USER 组下加入test.c 文件

接着我们在 test.c文件里面输入如下代码:

#include "sys.h"

#include "delay.h"

#include "usart.h"

int main(void)

{

u8 t=0;

Stm32_Clock_Init(9); //72M

delay_init(72); //延时初始化

- 16 - 东南大学成贤学院毕业论文

uart_init(72,9600); //设置串口1 波特率

while(1)

{

printf("t:%dn",t);

delay_ms(500);

t++;

}

}

点击(部分编译按钮)编译一下,会在Output Windows信息栏中发现如下报错信息:test.c(1):

error: #5:can not open source input file "sys.h": No such file or directory。如下图所示(图中红圈内信息):

图3-10编译报错

意思是无法打开源输入文件sys.h,没这个文件或目录。双击红圈内的内容,你会发现在test.c的01行出现了一个浅绿色的小箭头,说明错误是这个地方产生的。双击后浅绿色箭头出现位置如下:

图3-11编译报错

其实通过下面错误的说明,就是include 的路径没有加进去的缘故,而导致了这个错误。现在我们点击(Options for Target 按钮),弹出Options for Target’Target 1’对话框,选择C/C++选项卡,如下图所示:

- 17 - 东南大学成贤学院毕业论文

图3-12 加入头文件包含路径

在Include Paths处,点击2处的按钮。在弹出的对话框中加入SYSTEM文件夹下的3个文件夹名字,把这几个路径都加进去(此操作即设定编译器的头文件包含路径,下面会经常用到)。

图3-13 头文件包含路径设置

点击OK确认,回到IDE,此时再点击按钮,再编译一次,发现没错误了,得到如下界面:

- 18 - 东南大学成贤学院毕业论文

图3-14 再次编译结果

至此,一个完整的STM32开发工程在MDK下建立了,接下来我们就是进行软件仿真了。

3.3 软件仿真

MDK的一个强大的功能就是提供软件仿真,通过软件仿真,我们可以发现很多将要出现的问题,避免了下载到STM32里面来查这些错误,这样最大的好处是能很方便的检查程序存在的问题,因为在MDK的仿真下面,你可以查看很多硬件相关的寄存器,通过观察这些寄存器,你可以知道代码是不是真正有效。另外一个优点是不必频繁的刷机,从而延长了STM32的FLASH寿命。当然,软件仿真不是万能的,很多问题还是要到在线调试才能发现。接下来我们开始进行软件仿真。

在软件仿真之前,先检查一下配置是不是正确,点击要检查芯片型号和晶振频率,其他的一般默认就可以):

,确定Target选项卡内容如下所示(主

图3-15 Target 选项卡

确认了芯片以及外部晶振频率(8.0 M)之后,基本上就确定了硬件环境了,接下来,我们再看- 19 - 东南大学成贤学院毕业论文

Debug选项卡,设置为如下图所示的设置:

图3-16 Debug 选项卡

主要确认是Use Simulator是否选择(因为如果选择右边的Use,那就是用ULINK进行硬件Debug了,这个将在下面介绍),其他的采用默认的就可以。确认了这项之后,我们便可以选择OK,退出Options for Target对话框了。接下来,我们点击下界面:

(开始/停止仿真按钮),开始仿真,出现如

图3-17开始仿真

可以发现,多出了一个工具条,这个工具条对于我们仿真是非常有用的,下面简单介绍一下工具条相关按钮的功能,工具条部分按钮的功能如下图所示

- 20 - 东南大学成贤学院毕业论文

图3-18 仿真工具条

复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。代码重新执行。

执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能。

挂起:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。

执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。

执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。

执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。

执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。

汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。

观看变量/堆栈窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量值,也是很常用的一个调试窗口。

串口打印窗口:该按钮按下,会弹出一个串口调试助手界面的窗口,用来显示从串口打印出来的内容。

内存查看窗口:该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况,是很常用的一个调试窗口

性能分析窗口:按下该按钮,会弹出一个观看各个函数执行时间和所占百分比的窗口,用来分析函数的性能是比较有用的。

逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过 SETUP 按钮新建一些I/O 口,就可以观察这些I/O 口的电平变化情况,以多种形式显示出来,比较直观。

其他几个按钮用的比较少,以上是比较常用的,当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西来决定要不要看。

这样,我们在上面的仿真界面里面选内存查看窗口、串口打印窗口。然后调节一下这两个窗口的位置,如下图所示:

- 21 - 东南大学成贤学院毕业论文

图3-19 调出仿真串口打印窗口

我们把光标放到 test.c的09行,然后双击鼠标左键,可以看到在09行的右边出现了一个红框,即表示设置了一个断点(也可以通过鼠标右键弹出菜单来加入,再次双击则取消)。然后我们点击,执行到断点处,如下图所示:

图3-20 执行到断点处

我们不忙着往下执行,现在来点击菜单栏的Peripherals->USARTs->USART1。可以看到,有很多外设可以查看,这里我们查看的是串口1的情况。如下图所示

- 22 - 东南大学成贤学院毕业论文

图3-21 查看串口1 相关寄存器

单击 USART1后会在IDE之外出现一个如下界面:

图3-22 串口1 各寄存器初始化前后对比

左边这个就是STM32默认时候,串口1的状态,从中可以看到所有与串口相关的寄存器全部在这上面表示出来了,而且有当前串口的波特率等信息的显示。我们接着单击一下,执行完串口初始化函数,得到了如上面右边图片所示的串口信息。你可以对比一下这两个的区别,就知道在uart_init(72,9600);这个函数里面大概执行了哪些操作。这样可以很清楚的告诉你,当前的串口是否可用,你的设置是否正确,同样这样的方法也可以适用于很多其他外设。

然后我们继续单击下图所示:

按钮,一步步执行,最后就会看到在USART #1 中打印出相关的信息,如- 23 - 东南大学成贤学院毕业论文

图3-23 串口1输出信息

这样证明我们的仿真是通过的,代码运行会在串口1 不停的输出t 的值,每0.5s执行一次(时间可以通过IDE的最下面观看到),并且t 自增。与我们预期的目地是一致的。再次按下否可行。

结束仿真。至此,我们软件仿真算是结束了,接下来我们下载代码到硬件上来真正验证一下我们的代码是3.4 在线调试

利用串口,我们只能下载程序,并不能实时跟踪,而利用调试工具,比如JLINK、ULINK等就可以实时跟踪程序,使你的开发事半功倍。这里我们以JLINK V8为例,说说如何在线调试。

3.4.1 J-link简介

J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器。配合IAR EWAR,ADS,KEIL,WINARM,Real View等集成开发环境支持所有ARM7/ARM9/ARM11内核芯片的仿真,通过RDI接口和各集成开发环境无缝连接,操作方便、连接方便、简单易学,是学习开发ARM最好最实用的开发工具。

J-LINK仿真器V8版,其仿真速度和功能远非简易的并口WIGGLER调试器可比。J-LINK支持ARM7、ARM9、ARM11、Cortex-M3核心,支持ADS、IAR、KEIL开发环境。V8.0版本除拥有上一版本V7.0的全部功能外,软硬件上都有改进:(1)V8.0版的SWD硬件接口支持1.2-5.0V的目标板,V7.0只能支持3.3V的目标板。(2)V8.0使用双色LED可以指示更多的工作状态,V7.0只有1个LED指示灯。(3)V8.0增强了JTAG驱动能力,提高了目标板的兼容性。(4)优化了固件结构,使应用程序区扩大。J-Link ARM主要特点:

IAR EWARM集成开发环境无缝连接的JTAG仿真器。

支持所有ARM7/ARM9内核的芯片,以及Cortex-M3,包括Thumb模式。

支持ADS,IAR,KEIL,WINARM,REALVIEW等几乎所有的开发环境。

下载速度高达ARM7:600kB/s,ARM9:550kB/s,通过DCC最高可达800 KB/s。

最高JTAG速度12MHz。

目标板电压范围1.2V–3.3V,5V兼容。

自动速度识别功能。

- 24 - 东南大学成贤学院毕业论文

监测所有JTAG信号和目标板电压。

完全即插即用。

使用USB电源(但不对目标板供电)

带USB连接线和20芯扁平电缆。

支持多JTAG器件串行连接。

标准20芯JTAG仿真插头。

选配14芯JTAG仿真插头。

选配用于5V目标板的适配器。

带J-Link TCP/IP server,允许通过TCP/ IP网络使用J-Link。

3.4.2 J-link调试步骤

JLINK-V8支持JTAG和SWD,而STM32也支持JTAG和SWD。所以,我们有2种方式可以用来调试,JTAG调试的时候,占用的I/O 线比较多,而SWD 调试的时候占用的I/O线很少,只需要2跟即可。

在安装了JLINK V8之后,我们接上JLINK-V8,并把JTAG口插到硬件板上,打开之前新建的工程,点击,打开Options for Target选项卡,在Debug栏选择仿真工具为Cortex-M3 J-LINK,如下图所示

图3-24 Debug 选项卡设置

然后我们点击Settings,设置J-LINK的一些参数,如下图所示:

- 25 - 东南大学成贤学院毕业论文

图3-25 J-LINK 模式设置

上图中,我们使用J-LINK V8的SW模式调试,因为我们JTAG需要占用比SW模式多很多的I/O口,而在硬件板上这些I/O口都是非常有用的,并造成部分外设无法使用。所以建议大家在调试的时候,一定要选择SW模式。Max Clock,可以点击Auto Clk来自动设置,这里设置JLINK的调试速度为10MHZ,如果USB数据线比较差,那么可能会出问题,此时,可以通过降低这里的速率来试试。

单击OK,完成此部分设置,接下来我们还需要在Utilities选项卡里面设置下载时的目标编程器,如下图所示:

图3-26 FLASH 编程器选择

上图中,我们选择J-LINK来调试Cortex-M3,然后点击Settings,设置如下图所示:

- 26 - 东南大学成贤学院毕业论文

图3-27 编程设置

这里要根据不同的MCU选择FLASH的大小,因为我们开发板使用的是STM32F103RBT6,其FLASH大小为128K,所以我们在Programming Algorithm里面选择128K型号的STM32。然后选中Reset and

Run,以实现在编程后自动启动。其他默认设置即可。

在设置完之后,点击OK,然后再点击OK,回到IDE界面,编译一下工程。再点击真(如果开发板的代码没被更新过,则会先更新代码,再仿真,你也可以通过按下图所示:

,开始仿,只下载代码,而不进入仿真,特别注意:开发板上的B0要设置到GND,否则代码下载后不会自动运行的!),如

图3-28 开始仿真

可以看到都是一些汇编码的查看,如果我们要快速运行到main函数,可以在main函数的第一句语句处放入断点,然后点击,来快速执行到该处。如下图所示:

- 27 - 东南大学成贤学院毕业论文

图3-29 程序运行到断点处

接下来,我们就可以和软件仿真一样的开始仿真了,不过这是真正的在硬件上的仿真,其结果更可信。

3.5 程序下载

STM32的程序下载有多种方法:USB、串口、JTAG、SWD等,这几种方式都可以用来给STM32下载代码。不过,我们最常用的,最经济的,就是通过串口给STM32下载代码。

STM32的串口下载一般是通过串口1 下载的,本设计的硬件板,不是通过RS232串口下载的,而是通过自带的USB串口来下载。看起来像是USB下载(只有一根USB线,并没有串口线)的,实际上,是通过USB转成串口,然后再下载的。

下面,我们就一步步实现如何在实验平台上利用USB串口来下载代码。

首先要在板子上设置一下,在板子上把RXD和PA9(STM32的TXD),TXD和PA10(STM32的RXD)通过跳线帽连接起来,这样我们就把PL2303和MCU的串口1连接上了。这里由于硬件板自带了一键下载电路,所以并不需要去关心BOOT0和BOOT1的状态,但是为了让下载完后可以按复位执行程序,要把BOOT1和BOOT0都设置为0。设置完成如下图所示:

- 28 - 东南大学成贤学院毕业论文

图3-30 开发板串口下载跳线设置

接着我们在USB_232处插入USB线,并接上电脑,如果之前没有安装PL2303的驱动(如果已经安装过了驱动,则应该能在设备管理器里面看到USB 串口,如果不能则要先卸载之前的驱动,卸载完后重启电脑(必要步骤),再重新安装我们提供的驱动),则电脑会提示找到新硬件,如下图所示:

图3-31 找到新硬件

我们不理会这个提示,直接找到光盘->软件文件夹下的PL-2303驱动,安装该驱动。在驱动安装完成之后,拔掉USB线,然后重新插入电脑,此时电脑就会自动给其安装驱动了。在安装完成之后,可以在电脑的设备管理器里面找到USB串口(如果找不到,则重启下电脑),如下图所示:

图3-32 USB 串口驱动安装成功

- 29 - 东南大学成贤学院毕业论文

上图中我们显示的USB串口为COM5,不同电脑可能不一样,可能是COM4、COM6等,但是Prolific

USB-to-Serial Comm Port,这个一定是一样的,如果没找到,则有可能是安装有误或者系统不兼容。

在安装了USB串口驱动之后,我们就可以开始串口下载程序了,这里我们的串口下载软件选择的是mcuisp,该软件属于第三方软件,由单片机在线编程网提供,大家可以去免费下载,目前最新版本为V0.993。该软件启动界面如下:

图3-33 mcuisp 启动界面

然后我们选择要下载的HEX文件,以前面我们新建的工程为例,因为我们前面的工程没有在KEIL里面设置生成.hex文件,所以在USER文件夹下是找不到.hex文件的。下面我们看看如何设置:先在工程里面点击,打开Output选项卡,勾选Create HEX File选项,如下图所示:

图3-34 MDK 设置生成HEX 文件

图中选中第二个红圈内的选项,可以使编译器产生浏览信息,方便快速查看函数和变量等,这点在后面会介绍。选中之后点击OK,重新编译,编译结果如下图所示:

- 30 - 东南大学成贤学院毕业论文

图3-35 重新编译结果

从上图中可以看到,编译器已经产生了hex文件了,然后我们打开USER文件夹,看看里面发生了什么变化?如下图所示:

图3-36 新编译生成文件

从上图可以看到,重新编译产生了很多文件,其中就有我们所需要的hex文件(图中红圈圈中),至此,我们就可以开始下载了。用mcuisp软件打开USER文件夹,找到,打开并进行相应设置后,如下图所示:

图3-37 mcuisp 设置

- 31 - 东南大学成贤学院毕业论文

图3-37中红圈圈中的设置,是我们建议的设置。编程后执行,这个选项在无一键下载功能的条件下是很有用的,当选中该选项之后,可以在下载完程序之后自动运行代码。否则,下载代码之后,必须先将B0连接GND,再按复位键,才能开始运行刚刚下载的代码。硬件板虽然自带了一键下载功能,但是还是建议选上这个设置。

编程前重装文件,该选项也比较有用,当选中该选项之后,mcuisp会在每次编程之前,将hex文件重新装载一遍,这对于代码调试的时候是比较有用的。

最后,我们选择的DTR 的低电平复位,RTS 高电平进BootLoader,这个选择项选中,mcuisp就会通过DTR和RTS信号来控制板载的一键下载功能电路,以实现一键下载功能。如果不选择,则无法实现一键下载功能。这个是必要的选项(在BOOT0 接GND 的条件下)。

在装载了hex文件之后,我们要下载代码还需要选择串口,这里mcuisp 有智能串口搜索功能。每次打开mcuisp软件,软件会自动去搜索当前电脑上可用的串口,然后选中一个作为默认的串口(一般是您最后一次关闭时所选则的串口)。也可以通过点击菜单栏的搜索串口,来实现自动搜索当前可用串口。串口波特率则可以通过bps那里设置,对于STM32,该波特率最大为230400bps,这里我们一般选择最高的波特率:460800,让mcuisp 自动去同步。搜索完串口之后界面如下图所示:

图3-38 搜索串口

从之前USB串口的安装可知,开发板的串口被识别为COM5了,所以我选择COM5。选择了相应串口之后就可以通过按”开始编程(P)”这个按钮,一键下载代码到STM32上,下载成功后如下图所示:

- 32 - 东南大学成贤学院毕业论文

图3-39 下载完成

上图中,我用圈圈圈出了mcuisp对一键下载电路的控制过程,其实就是控制DTR和RTS电平的变化,控制BOOT0和RESET,从而实现自动下载。另外界面提示已经下载完成(如果老提示:开始连接„,需要检查一下,开发板的设置是否正确,是否有其他因素干扰等),并且从0X80000000处开始运行了,我打开串口调试助手选择COM5,会发现从硬件板发回来的信息,如下图所示:

图3-40 程序开始运行了

接收到的数据和我仿真的是一样的,证明程序没有问题。至此,说明下载代码成功了,并且也从硬件上验证了代码的正确性。

- 33 - 东南大学成贤学院毕业论文

第四章 程序设计与调试

4.1 系统描述

本系统采用基于ARM Cortex-M3内核的STM32作为主控制器,外扩SD卡以及TFT彩屏。系统通过文件系统读取SD卡内存储的BMP、JPEG、JPG格式图片,把多幅图片以幻灯片的形式从TFT屏上显示出来。同时,通过STM32内部的RTC模块使系统具有掉电不遗失日期及时钟的功能。系统框图如图4-1所示。

图4-1 系统框图

4.2 软件设计

4.2.1 文件读取

本设计需要用到FAT(FAT16/32)文件系统来读取SD 卡上的字库和UNICODE到GBK的转换码表到W25X16部分,因此要重点介绍FAT文件系统。FAT文件系统本身比较复杂,所以这里只简单介绍一下。

常用的文件系统有FAT12/16/32等,FAT12是最古老的文件系统,只能管理8M左右的空间,现在基本淘汰了。FAT16则可以管理2G的空间(通过特殊处理也能管理2G以上的空间),而FAT32则能管理到2TB(2048GB)的空间。FAT32较FAT16的优势还在于FAT32采用了更小的簇,可以更有效的保存信息,而不会造成较多的浪费。

XP在SD卡里面建立的文件系统最常用的也就是FAT16和FAT32。这是由XP在格式化SD卡的时候建立的,通常SD卡上的数据信息由MBR、DBR、FAT、FDT和数据区5个部分组成(有的也没有MBR)。我们以FAT32为例做介绍。

MBR称为主引导记录区,该区存储了分区表等信息,位于SD卡的扇区0(物理扇区),在其分区信息里面记录了DBR 所在的位置,SD卡一般只会有一个分区,所以也就只要找到分区1的DBR 所在位置就可以了。

DBR称为操作系统引导记录区,如果没有MBR,那么DBR就位于0扇区,如果有则必须通过MBR区得到DBR所在的地址,然后读出DBR信息。在DBR区,我们可以知道每个扇区所占用的字节数、每个簇的扇区数、FAT表的份数、每个FAT表的扇区数、跟目录簇号、FAT表1所在的扇区等一系列非常重要的信息。

FAT称为文件分配表(FAT表),一般一个卡上会存在2个FAT表,一个用作备份,一个用作使用。FAT表一般紧随DBR,另一个FAT表则紧随第一个FAT表,这样只要知道了第一个FAT表的位置及大小,那么第二个FAT表的位置也就确定了。FAT表记录了每个文件的位置和区域,是一种链式结构,FAT以“F8 FF FF 0F FF FF FF FF”这样的8个字节为表头,用以表示FAT表的开始,后面的数据每四个字节为一个簇项(从第2簇开始),用来标记下一个簇所在的位置,这样每个位置都存储了下一个簇,只要按着这个表走,就可以找到文件的所有内容。如果找到下一个簇位置,里面记录的是“FF FF FF 0F”,代表这个文件到此就结束了,没有后续簇了,这样一个文件的读取就结束- 34 - 东南大学成贤学院毕业论文

了。

FDT称为文件根目录表,这个区域固定为32个扇区,假设每个扇区为512个字节,那么更目录下最多存放512个文件(假设都用短文件名存储,每个短文件名占32个字节)。

文件目录表是另一个重要的部分,FAT文件系统中(仅以短文件名介绍),文件目录项在目录表下以32个字节的方式记录,各字段定义如下:

表4.1 文件目录项各字节定义

从上表可知,我们在文件的目录项就可以找到该文件的其实簇,然后在FAT表里面找到该簇开始的下一个簇,依次读取这些簇就可以把整个文件读出来了。

4.2.2 图像解码与显示

4.2.2.1 BMP文件格式

BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。

部分代码:

//BMP信息头

typedef __packed struct

{

DWORD biSize ;

LONG biWidth ;

LONG biHeight ;

WORD biPlanes ;

//说明BITMAPINFOHEADER结构所需要的字数。

//说明图象的宽度,以象素为单位

//说明图象的高度,以象素为单位

//为目标设备说明位面数,其值将总是被设为1

WORD biBitCount ; //说明比特数/象素,其值为1、4、8、16、24、或32

DWORD biCompression ; //说明图象数据压缩的类型。其值可以是下述值之一:

DWORD biSizeImage ;//说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0

- 35 - 东南大学成贤学院毕业论文

LONG biXPelsPerMeter ;//说明水平分辨率,用象素/米表示

LONG biYPelsPerMeter ;//说明垂直分辨率,用象素/米表示

DWORD biClrUsed ; //说明位图实际使用的彩色表中的颜色索引数

DWORD biClrImportant ; //说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

} BITMAPINFOHEADER ;

//BMP头文件

typedef __packed struct

{

WORD bfType ; //文件标志.只对'BM',用来识别BMP位图类型

DWORD bfSize ; //文件大小,占四个字节

WORD bfReserved1 ;//保留

WORD bfReserved2 ;//保留

DWORD bfOffBits ; //从文件开始到位图数据(bitmap data)开始之间的的偏移量

}BITMAPFILEHEADER ;

//彩色表

typedef __packed struct

{

BYTE rgbBlue ; //指定蓝色强度

BYTE rgbGreen ; //指定绿色强度

BYTE rgbRed ; //指定红色强度

BYTE rgbReserved ;//保留,设置为0

}RGBQUAD ;

//位图信息头

typedef __packed struct

{

//解码这个BMP文件

{

u16 count;

u8 rgb ,color_byte;

u16 x ,y,color,tmp_color ;

u16 uiTemp; //x轴方向像素计数器

u16 countpix=0;//记录像素

u8 realx=0;

- 36 -

BITMAPFILEHEADER bmfHeader;

BITMAPINFOHEADER bmiHeader;

}BITMAPINFO;

BOOL BmpDecode(FileInfoStruct *BmpFileName)

u16 realy=0; //x,y的实际坐标

u8 yok=1;

BITMAPINFO *pbmp;//临时指针 东南大学成贤学院毕业论文

CurFile=BmpFileName;

F_Open(CurFile);//打开文件

F_Read(CurFile,jpg_buffer);//读出512个字节

pbmp=(BITMAPINFO*)jpg_buffer;//得到BMP的头部信息

count=pbmp->its; //数据偏移,得到数据段的开始地址

color_byte=pbmp->ount/8;//彩色位 16/24/32

ght=pbmp->ht;//得到图片高度

th=pbmp->h; //得到图片宽度

//水平像素必须是4的倍数!!

if((th*color_byte)%4)

uiTemp=((th*color_byte)/4+1)*4;

uiTemp=th*color_byte;

else

AI_Drow_Init();//初始化智能画图

//开始解码BMP

x =0 ;

y=ght;

rgb=0;

realy=y*_Fac/10000;

while(1)

{

{

if(color_byte==3) //24位颜色图

{

switch (rgb)

{

case 0:

tmp_color = jpg_buffer[count]>>3 ;

color |= tmp_color;

break ;

tmp_color = jpg_buffer[count]>>2 ;

tmp_color <<= 5 ;

color |= tmp_color ;

break;

tmp_color = jpg_buffer[count]>>3 ;

tmp_color <<= 11 ;

color |= tmp_color ;

break ;

- 37 -

while(count<512) //读取一簇512扇区 (SectorsPerClust 每簇扇区数)

case 1:

case 2 :

} 东南大学成贤学院毕业论文

}

else

{

if(color_byte==2) //16位颜色图

{

}

else

{

if(color_byte==4)//32位颜色图

{

switch (rgb)

{

case 0 :

tmp_color=jpg_buffer[count];

color|=tmp_color>>3;

break ;

tmp_color=jpg_buffer[count];

tmp_color>>=2;

color|=tmp_color<<5;

break ;

tmp_color=jpg_buffer[count];

tmp_color>>=3;

color|=tmp_color<<11;

break ;

- 38 -

switch(rgb)

{

case 0 :

color=jpg_buffer[count]&0x1f;

tmp_color<<=6;

color|=tmp_color;

break ;

tmp_color=jpg_buffer[count];

tmp_color<<=9 ;

color |= tmp_color ;

break ;

tmp_color=jpg_buffer[count]>>5;

case 1 :

}

case 1 :

case 2 :

case 3 :break ;

} 东南大学成贤学院毕业论文

的值

}

}

}

}

}//位图颜色得到

rgb++;

count++ ;

{

}

countpix++;//像素累加

if(countpix>=uiTemp)//水平方向像素值到了.换行

{

y--;

if(y<=0)return TRUE;

realy=y*_Fac/10000;//实际y值改变

if(IsElementOk(realx,realy,0))yok=1;/此处不改变x,yelse yok=0;

x=0;

countpix=0;

color=0x00;

rgb=0;

if(x

{

}

x++;//x轴增加一个像素

color=0x00;

rgb=0;

}

realx=x*_Fac/10000;//x轴实际值

if(IsElementOk(realx,realy,1)&&yok)//符合条件

{

POINT_COLOR=color;

if(rgb==color_byte) //水平方向读取到1像素数数据后显示

LCD_DrawPoint(realx+PICINFO.S_XOFF,realy+PICINFO.S_YOFF-1);

}

if(!F_Read(CurFile,jpg_buffer))break;//读出512个字节,读数失败时自动退出

count=0 ;

}

return TRUE;//BMP显示结束.

4.2.2.2 JPEG文件格式

- 39 - 东南大学成贤学院毕业论文

JPEG 是Joint Photographic Experts Group(联合图像专家组)的缩写,文件后辍名为".jpg"或".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以把1.37MB的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找到平衡点。JPEG 格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。

JPEG/JPG 的解码过程可以简单的概述为如下几个部分:

1、从文件头读出文件的相关信息。

JPEG文件数据分为文件头和图像数据两大部分,其中文件头记录了图像的版本、长宽、采样因子、量化表、哈夫曼表等重要信息,所以解码前必须将文件头信息读出,以备图像数据解码过程之用。

2、从图像数据流读取一个最小编码单元(MCU),并提取出里边的各个颜色分量单元。

3、将颜色分量单元从数据流恢复成矩阵数据。

利用文件头给出的哈夫曼表,对分割出来的颜色分量单元进行解码,把其恢复成8×8的数据矩阵。

4、8×8的数据矩阵进一步解码。

此部分解码工作以8×8的数据矩阵为单位, 其中包括相邻矩阵的直流系数差分解码、利用文件头给出的量化表反量化数据、反Zig-zag编码、隔行正负纠正、反向离散余弦变换等5个步骤,最终输出仍然是一个8×8的数据矩阵。

5、颜色系统YCrCb向RGB转换。

将一个MCU的各个颜色分量单元解码结果整合起来,将图像颜色系统从YCrCb向RGB转换。

6、排列整合各个MCU的解码数据。

不断读取数据流中的MCU并对其解码,直至读完所有MCU为止,将各MCU解码后的数据正确排列成完整的图像。JPEG的解码本身是比较复杂的。

部分代码:

//调用顺序: Initialize_Fast_IDCT() :初始化

// DecodeMCUBlock() Huffman Decode

// IQtIZzMCUComponent() 反量化、反DCT

// GetYUV() Get Y U V

// StoreBuffer() YUV to RGB

int Decode(void)

{

int funcret;

Y_in_MCU=SampRate_Y_H*SampRate_Y_V;//YDU YDU YDU YDU

U_in_MCU=SampRate_U_H*SampRate_U_V;//cRDU

V_in_MCU=SampRate_V_H*SampRate_V_V;//cBDU

H_YtoU=SampRate_Y_H/SampRate_U_H;

- 40 - 东南大学成贤学院毕业论文

V_YtoU=SampRate_Y_V/SampRate_U_V;

H_YtoV=SampRate_Y_H/SampRate_V_H;

V_YtoV=SampRate_Y_V/SampRate_V_V;

Initialize_Fast_IDCT();

//The Digital has been Huffman Decoded andbe stored in

//MCUBuffer(YDU,YDU,YDU,YDU,UDU,VDU) Every DU := 8*8

while((funcret=DecodeMCUBlock())==FUNC_OK) //After Call DecodeMCUBUBlock()

{ interval++;

if((restart)&&(interval % restart==0))

IntervalFlag=TRUE;

else

IntervalFlag=FALSE;

IQtIZzMCUComponent(0); //反量化 and IDCT The Data in QtZzMCUBuffer

IQtIZzMCUComponent(1);

IQtIZzMCUComponent(2);

GetYUV(0);

GetYUV(1);

GetYUV(2);

StoreBuffer(); //To RGB

sizej+=SampRate_Y_H*8;

if(sizej>=th)

{ sizej=0;

sizei+=SampRate_Y_V*8;

}

if((sizej==0)&&(sizei>=ght))break;

}

return funcret;

}

//智能画图

//FileName:要显示的图片文件 BMP/JPG/JPEG

//(sx,sy) :开始显示的坐标点

//(ex,ey) :结束显示的坐标点

//图片在开始和结束的坐标点范围内显示

BOOL AI_LoadPicFile(FileInfoStruct *FileName,u16 sx,u16 sy,u16 ex,u16 ey)

{

int funcret;//返回值

//得到显示方框大小

//得到Y cR cB

if(ey>sy)PICINFO.S_Height=ey-sy;

else PICINFO.S_Height=sy-ey;

else PICINFO.S_Width=sx-ex;

//显示区域无效

- 41 -

if(ex>sx)PICINFO.S_Width=ex-sx; 东南大学成贤学院毕业论文

if(PICINFO.S_Height==0||PICINFO.S_Width==0)

{

}

//显示的开始坐标点

PICINFO.S_YOFF=sy;

PICINFO.S_XOFF=sx;

CurFile=FileName; //文件名传递

if(CurFile->F_Type==T_BMP)//得到一个BMP图像

{ funcret=BmpDecode(CurFile); //得到一个BMP图像

}

else if(CurFile->F_Type==T_JPG||CurFile->F_Type==T_JPEG)//得到JPG/JPEG图片

{ F_Open(CurFile); //得到JPEG/JPG图片的开始信息

//开始时读入1024个字节到缓存里面.方便后面提取JPEG解码的信息

F_Read(CurFile,jpg_buffer); //读第一次

F_Read(CurFile,jpg_buffer+512);//读第二次

InitTable(); //初始化各个数据表

if((funcret=InitTag())!=FUNC_OK)return FALSE;//初始化表头不成功

if((SampRate_Y_H==0)||(SampRate_Y_V==0))return FALSE ;//采样率错误

AI_Drow_Init(); //初始化_Fac,启动智能画图

funcret=Decode();//解码JPEG开始

return funcret;

PICINFO.S_Height=LCD_H;

PICINFO.S_Width=LCD_W;

return FALSE;

}else return FALSE; //非图片格式!!!

if(funcret==FUNC_OK)return TRUE;//解码成功

else return FALSE; //解码失败

}

此部分代码包含了JPEG/JPG以及BMP的解码代码,解码通过AI_LoadPicFile( )函数来实现,在该函数里面先判断文件的类型,然后调用不同的解码函数,解码JPEG由Decode( )函数实现,而解码BMP 则由BmpDecode( )函数实现。AI_LoadPicFile( )函数会将图片以合适的大小显示在液晶上(总是不会超过你给定的区域),对比输入尺寸大的图片,会自动压缩。解码图片完成后返回解码是否成功的信息。

4.2.3 时钟显示

实时时钟(RTC)是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操作,所以在要设置时间之前,先要取消备份区域(BKP)写保护。

RTC由两个主要部分组成(见下图4.2)。第一部分(APB1接口)用来和APB1总线相连。此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作。APB1接口由APB1总线时钟驱动,用来与APB1总线连接。

- 42 - 东南大学成贤学院毕业论文

另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是RTC的预分频模块,它可编程产生最长为1秒的RTC 时间基准TR_CLK。RTC的预分频模块包含了一个20位的可编程分频器(RTC 预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编程计数器,可被初始化为当前的系统时间,一个32位的时钟计数器,按秒钟计算,可以记录4294967296秒,约合136年左右,作为一般应用,这已经是足够了的。

RTC还有一个闹钟寄存器RTC_ALR,用于产生闹钟。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。

图4-2 RTC简化框图

RTC内核完全独立于RTC APB1接口,而软件是通过APB1接口访问RTC的预分频值、计数器值和闹钟值的。但是相关可读寄存器只在RTC APB1 时钟进行重新同步的RTC时钟的上升沿被更新,RTC 标志也是如此。这就意味着,如果APB1接口刚刚被开启之后,在第一次的内部寄存器更新之前,从APB1上的RTC寄存器值可能被破坏了(通常读到0)。因此,若在读取RTC寄存器曾经被禁止的RTC APB1接口,软件首先必须等待RTC_CRL寄存器的RSF位(寄存器同步标志位,bit3)被硬件置1。

接下来,我们介绍一下RTC相关的几个寄存器。首先要介绍的是RTC的控制寄存器,RTC总共有2个控制寄存器RTC_CRH和RTC_CRL,两个都是16位的。RTC_CRH的各位描如下

- 43 - 东南大学成贤学院毕业论文

图4-3 寄存器RTC_CRH 各位描述

该寄存器用来控制中断的,我们将要用到秒钟中断,所以该寄存器必须设置最低位为1,以允许秒钟中断。我们再看看RTC_CRL寄存器。该寄存器各位描述如下图所示:

图4-4 寄存器RTC_CRL 各位描述

本设计我们用到的是该寄存器的0、3~5这几个位,第0位是秒钟标志位,我们在进入闹钟中断的时候,通过判断这位来决定是不是发生了秒钟中断。然后必须通过软件将该位清零(写0)。第3位为寄存器同步标志位,我们在修改控制寄存器RTC_CRH/CRL之前,必须先判断该位,是否已经同- 44 -

发布评论

评论列表 (0)

  1. 暂无评论