第八章 ARM9硬件平台上的开发实例
本章首先对ADT开发工具作了一个粗步介绍,然后介绍了基于ARM9嵌入式处理器的一些开发实例。这些实例虽然是基于一款特定的三星S3C2410微处理器实验箱,但这些开发过程和对处理器不同功能部件的使用是完全相同的。在不同的开发平台上,只需要对内存配置文件的地址进行修改就可以完成相应的运行验证工作。S3C2410是一款ARM9内核的嵌入式微处理器,在国内的ARM9嵌入式实验系统中占主导地位。通过本章的学习,可以帮助读者较好地掌握该处理器的应用和编程方法,为进一步进行产品开发打下基础。
实例分为两部分,一部分是针对S3C2410处理器片上功能模块的介绍和驱动代码分析,以帮助读者掌握高档嵌入式处理器的一些特殊功能模块的使用和编程;另一部分是利用这些特殊功能模块组合具有完成一定功能的应用系统实例,以帮助读者掌握在高档处理器中多模块协同工作的编程方法。由于操作系统的移植涉及的内容太多,因此在本章中未涉及操作系统的移植和开发工作,有兴趣的读者可以查找相关资料专门进行学习。
8.1 JXARM92410ARM嵌入式教学实验系统硬件组成
本实验系统以三星公司生产的S3C2410处理器为核心部件,通过实验箱的扩展,可以完成嵌入式系统的各类嵌入式软件开发实验。不同厂家生产的实验箱在内存地址分配上可能会与本实验箱有所不同,但是对各功能模块进行初始化设置的方法和代码是相同的。通过本章的学习,可以将其应用到其他厂家生产的基于S3C2410处理器的实验箱中,也可以在实际的产品开发、设计中使用和借鉴本章所介绍的实例。本章所使用的实验箱硬件结构如图8-1所示。
所有硬件从结构上分成两个部分,一部分是安装于实验箱底板的不可移动资源,包括基本模块、通信模块、人机交互模块、A/D及D/A模块、工业控制模块、IDE/CF/SD/MMC接口模块等;另一部分是通过一定接口形式,插接在实验箱底板上的可移动资源,包括ARM单片机最小系统模块、GPRS模块、GPS模块、DSP模块、100M以太网、FPGA等。其中,ARM单片机最小系统模块是必须的,其他模块可根据需要进行选配,以丰富实验箱的功能。
图8-1 JXARM9-2410ARM嵌入式教学实验箱总体结构
由于ARM9以上的处理器引脚非常多,而且还需要进行存储器扩展,所需的电路较复杂,一般使用6层以上电路板设计实现。因此,在很多工程实践中,往往不单独开发设计ARM9的核心电路,而是直接购买成熟产品,这样既可以减少产品开发的复杂程度,又可以提高系统的灵活性。当然,如果系统对体积、可靠性、功耗等有特殊要求时,就只能单独开发了。
8.1.1 JXARM9-2410ARM嵌入式教学实验箱硬件模块
JXARM9-2410教学实验系统的硬件部分包括基本模块、调试模块、通讯模块、人机交互模块、A/D D/A模块、工业控制模块、IDE/CF/SD/MMC接口模块;选配模块包括GPRS模块、GPS模块。
1.基本模块
(1)SDRAM存储器。主板包含64MB SDRAM,由两片16位数据宽度的SDRAM存储器组成,地址从0x30000000~0x33fffffff。实验过程中编写的代码将存放在该存储空间中,关机后实验代码将丢失。
(2)Flash存储器。主板包含32MB NOR Flash存储器和8MB NAND Flash。NOR Flash内部存放启动代码Bootloader、Linux内核映象、IIS测试声音文件等,其数据宽度为32位,地址从0x00000000~0x01ffffff;NAND Flash中包含一个cramfs文件系统,在Linux中使用。在实验过程中,由于没有将代码烧写到Flash中,因此这个存储器我们没有使用。如果将代码烧写到这个存储器中,则关机后实验代码不会丢失,开机后可自动运行。这也是在真正的嵌入式系统中所采用的代码存放方法。当然,不同的厂家可以根据自己的设计需要设计不同容量和不同形式的存储器。
(3)串行通讯口。本实验箱的主板包含3个UART接口,即UART0、UART1、UART2。其中,UART1用作RS232串行接口,UART2用作RS485接口。UART0在Bootloader、演示程序、Linux和多个实验中用于人机交互(通过超级终端)以及文件传输。串行通信由于操作简单,几乎是所有嵌入式开发板的基本配置,它可以完成嵌入式开发板与计算机之间的信息交互,从而了解嵌入式开发板上的工和状况等。
(4)IIS录放音接口。主板有一个可以基于DMA操作的IIS总线接口,可进行立体声录放音。
(5)I2C总线接口,与24C08芯片接口,可以存放一些固定的配置数据。
(6)4个LED跑马灯,可独立软件编程。
(7)6个共阳7段数码管。
(8)外部中断测试。两个按键用于外部中断2、3的测试。
(9)复位按键,用于CPU复位。
(10)两通道通用DMA。两通道具有外部请求引脚的外设DMA。
(11)5个PWM定时器和一个内部定时器。PWM0能够输出到蜂鸣器,使蜂鸣器发声。
(12)看门狗定时器。
(13)8通道10-bit ADC。其中,AIN0、AIN1接板上可调电阻,用于A/D转换实验;AIN5、AIN7可用于电阻式触摸屏读值。
2.调试模块
(1)标准JTAG接口。20针标准JTAG接口,该接口用于连接仿真器进行高速调试。该仿真器价格昂贵,并未作为实验基本部件提供。
(2)简易JTAG调试接口。直连标准计算机并口,作为调试接口。该接口用于简易仿真调试,主要功能包括程序下载、断点信息交互等,是实验的基本部件。
3.通讯模块
(1)以太网通讯接口。10M以太网卡,可用于联接嵌入式实验箱与计算机主机系统。
(2)USB接口。两个USB HOST接口,可以挂接U盘、USB鼠标、USB摄像头等USB备,遵循USB1.1标准。
(3)标准计算机打印口(并口)。用于模拟计算机的并行口输出数据。
4.人机交互模块
(1)显示器/触摸屏。7英寸、TFT16位色LCD显示器,分辨率640×480。
(2)板载按键。4×4机械按键。
(3)PS/2键盘和鼠标接口。
(4)USB鼠标和键盘接口。
5.工业控制模块
(1)两相步进电机驱动电路。
(2)RS485总线接口电路。
(3)CAN总线接口电路。
6.IDE/CF/SD/MMC接口模块
(1)标准IDE硬盘40针接口电路。
(2)标准CF卡接口电路。
(3)SD/MMC卡接口电路。
7.可选配模块
(1)GPRS无线通讯模块。
JXARM9-2410教学实验系统的外部结构如图8-2所示。
图8-2 JXARM9-2410ARM嵌入式教学实验箱外部结构图
8.1.2 JXARM9-2410ARM嵌入式教学实验箱硬件资源分配
1.地址空间分配以及片选信号定义
JXARM9-2410地址空间分配详见表8-1所示。
表8-1 JXARM9-2410地址空间分配表
2.外部中断分配
JXARM9-2410外部中断分配详见表8-2所示。
表8-2 JXARM9-2410外部中断分配表
续表8-2
3.A/D端口分配
JXARM9-2410 A/D端口分配详见表8-3所示。
表8-3 JXARM9-2410 A/D端口分配表
4.RAM空间组织
存储空间的定制是嵌入式系统开发的一个特色,我们可以根据自己的需要自行规定内存的使用。在本教学实验系统中,SDRAM地址范围从0x30000000~0x33ffffff共64Mbytes。在不同的程序中,SDRAM空间范围被分配成不同的区域用于不同的用途,下表是实验测试程序所用的一个默认分配方式,它的代码空间和数据空间分配如表8-4所示。
表8-4 用户程序SDRAM空间分配表
5.Flash空间组织
在本实验系统的硬件平台上,Flash地址范围从0x00000000~0x01ffffff共32Mbytes。其空间组织如表8-5所示。
表8-5 Flash空间分配表
8.2 ADT IDE集成开发环境
8.2.1 ADT IDE for ARM组成
ADT(ARM Development Tools)IDE(Integrated develop environment)for ARM是一套应用于ARM嵌入式软件开发的集成软件开发平台。它为基于ARM核的嵌入式应用提供了一整套完备的开发方案,包括程序编辑、工程管理和设置、程序编译、程序调试等。
ADT IDE for ARM主要包括以下工具:
(2)工程管理器(project manager);
(3)工程编译器(builder);
(4))集成调试环境(integrated debug environment)。
由于ADT IDE软件是一套基于GNU GCC编译系统的C/汇编程序开发环境,具有良好的开源特性,因此也十分有利于其升级和用户按需修改。
8.2.2 ADT IDE for ARM(简称ADT IDE)的主要特点
(1)可运行于Windows98、NT、2000、XP等平台,可支持ARM7、ARM9系列微处理器。
(2)中、英文版本支持,具有英文版和汉化版两个版本,可同时运行。
(3)可视化的源码编辑和工程管理功能。ADT IDE提供全图形化的用户界面,包括图形化工程管理、源码编辑、辅助编辑等功能,可实现文件级、文件目录级、工程级的多级编译连接选项管理以及工程级的调试参数管理;标准的文本编辑功能,支持C语言、汇编语言语法高亮显示;多剪贴板、代码模板、头文件和源文件切换、注释、符号配对书写等辅助编辑工具,可极大地提高程序编写效率。
(4)良好的交叉编译功能。ADT IDE使用GNU的GCC交叉编译工具,支持ANSI C、Embedded C++、嵌入式汇编等程序的交叉编译;提供完全图形化的工程级、文件目录级、文件级编译参数设置。
(5)强大的源代码级调试功能,同时提供了图形和命令行两种调试方式,可支持软件断点和硬件断点的调试,允许程序以单步执行方式运行;对程序中的变量提供监视功能,可随程序运行同步更新变量,可自动/手动刷新变量内容以十进制/十六进制模式显示;可实现ARM各模式下寄存器内容与程序运行同步的查看与修改,提供当前模式指示,寄存器值变动时红色突显;可对存储器内容进行查看与修改,可设置自动/手动刷新方式、字节/双字节/四字节显示、大/小端方式显示,存储器内容修改时红色突显;可以完成函数堆栈显示,以自动/手动刷新方式更新、十进制/十六进制显示、参数值显示,参数类型显示等;支持源程序、反汇编程序和混合窗口方式显示,支持ARM/THUMB方式显示。
(6)完善的程序下载手段。支持基于并口模拟的简单调试接口方式和基于JTAG接口的仿真器调试模式;可将数据/程序在线下载到随机存储或Flash存储器上进行运行和调试;能够对Flash进行在线编程,支持多种Flash芯片的空白检查、擦除、编程、校验等操作,支持8/16/32位Flash访问宽度,多片Flash同时编程,编程速度达15Kbytes/s;提供统一的Flash编程接口,可以方便地添加Flash编程方案。
(7)丰富的示例程序。
8.2.3 ADT IDE安装要求
(1)软件环境:Microsoft Windows98、Windows NT、Windows 2000、Windows XP。
(2)硬件要求:486以上CPU,建议采用Pentium II及更高级的处理器;64M以上内存,建议采用128M以上;200M空间的可用硬盘空间;CD-ROM驱动器;并行打印机端口
8.2.4 ADT IDE软件安装后的目录结构
ADT IDE For ARM的所有文件将被安装在一个目录分支下,例如在软件安装过程中,如果用户选择的安装目录为C:\ADTIDE,安装程序将在该目录下创建各级目录,并且根据模块和功能划分,将ADT IDE系统的全部文件拷贝到该目录及其子目录下(如下所示,在C:\ADTIDE下创建的目录和文件及功能划分)。
.\Bin系统运行所需的全部应用程序
.\Plugin系统运行所需要的部分动态链接库
.\Gnutools GNU交叉编译器目录,包含编译器、汇编器、连接器以及标准C/C++库。
.\Flash Flash编程器
.\Doc系统帮助说明文件目录
.\Examples所有例程目录
.\Lib与各种CPU或目标版相关的设置文件和函数库
.\License.txt系统发布时许可协议文件
.\Readme.Txt系统发布附带信息文件
8.2.5 ADT IDE的文件类型
8.3 ADT IDE开发步骤和方法
本节将以一个实验性工程leddemo为例,讲述在ADT IDE集成开发环境下如何编写、编译、连接和调试程序。
8.3.1 硬件准备
首先,在上电和进行其他设备连接前,应检查实验箱上硬件的连接情况,包括检查实验箱配件是否齐全,包括主板、核心板、LCD、电源等连接是否牢靠。
其次,确认简易调试模块的调试线或仿真器是否正确连接(JXARM9-2410教学实验系统支持内置的简易调试器下载和仿真器下载调试两种方式,使用内置调试模块时,速度会比使用仿真器慢。不同的实验箱在更换调试器时可能需要改变相应跳线,请注意查阅说明),确认RS23串行线或对连式的网线是否已正确连接。使用RS232连接时应连接到UART0端口,利用串口或网线可以反馈得到程序下载后的运行情况。
8.3.2 工程编辑、编译和调试
(1)建立工程。打开ADT IDE,点击“File->New菜单”,弹出New对话框,如图8-3所示,选择Project页,在Project页中选择调试设备。调试设备分别表示:“SoftSim”软件仿真调试、“ARM7LPT”使用仿真器的并口调试ARM7目标系统、“ARM9LPT”使用仿真器的并口调试ARM9目标系统、“ARM7Simple”使用简易仿真方式调试ARM7目标系统、“AMR9Simple”使用简易傎仿真方式调试ARM9目标系统。在本实验中,我们使用实验箱上的简易仿真口进行调试ARM9系统,因此选择“ARM9 Simple”,在“Project name”和“Location”中输入工程名称和路径,注意路径和工程名中不能包含空格。然后在工程类型中选择“EXEC”。
图8-3 新建工程
图8-4 加入文件到工程示意图
图8-5 文件选择对话框
该文件为链接脚本文件,其意义和编写方法请参考“附录A链接定位脚本”。该文件必须通过第5步中的工程设置对话框设置到链接参数中才有效。对于不同地址环境的硬件,只需要改变相应的起始地址就可以了。
(5)如图8-6所示,在工作区窗口中的leddemo工程名上右键点击并选择“Setting”菜单项。
图8-6 工程设置示意图
弹出工程设置对话框,选择“Link”页,在“Link script”中点击右侧按钮选择该ldscript文件,然后点击“OK”按钮,进入下一步。如图8-7所示。
图8-7 Link相关选项
(6)完成相关设置工作后,开始编译整个工程,在工作区窗口中的leddemo工程名上右键点击并选择“Build”菜单项。如图8-8所示。
图8-8 工程编译示意图
编译成功后的结果如图8-9所示。如果编译不成功,将会在最下面的提示窗口提示出错的位置和错误原因,按照提示信息进行相关修改后再次编译,直到编译成功为止。
图8-9 编译结果示意图
(7)编译完成后,需要将编译好的二进制可执行文件通过一定的手段下载到实验箱中运行,将仿真器或调试电缆连接到JXARM9-2410 JTAG连接,并将仿真器和JXARM9-2410上电,然后在ADT IDE工具中点击“Debug”菜单的“Remote Connect”进行连接,如图8-10所示。
图8-10 调试菜单连接示意图
如果连接正确,将会在软件最下方提示连接成功的信息,否则将会出现连接错误的提示。如果出现错误,应关闭实验箱和仿真器再次确认硬件是否连接正确,以及板上的选择跳线是否正确。当正常连接时,显示结果如图8-11所示。
图8-11 连接结果示意图
如果连接正确,集成开发工具的“Debug”菜单项将如图8-12所示。
图8-12 正确连接后的调试菜单示意图
(8)点击Debug->Download菜单选项,将编译生成的二进制文件下载程序到实验箱的SDRAM中,准备运行测试。如图8-13所示。
图8-13 程序下载操作示意图
下载可能会占用一定时间。在开发工具的最下面会有一个进度条,标识下载进度,下载成功后,集成工具上将显示入口点的源代码,如图8-14所示。
图8-14 下载成功后的调试窗口示意图
(9)运行程序观察运行结果,点击Debug->Go菜单项,运行该程序。如果运行正常,JXARM9-2410上的6个8段数码管将循环往复显示0~F的字符。如图8-15所示。
图8-15 运行程序
(10)如果要进行其他调试工作,如插入断点、单步执行等,可点击Debug->Stop停止程序运行,然后再进行其他相关操作。具体的操作步骤与其他集成开发环境基本相同,只是在错误时需要修改错误代码,然后再次从第6步开始执行相关步骤。
8.4 S3C2410功能模块驱动代码
8.4.1 LCD驱动控制代码
1.S3C2410LCD控制器
LCD显示屏作为一种友好的用户界面设备,在嵌入式系统中得到广泛应用,但是LCD显示屏的使用却需要一定的技术和方法。
常用的LCD接口方式有两种,一种是总线驱动方式,另一种是扫描器控制方式。
(1)总线驱动方式
一般带有驱动模块的LCD显示屏会使用总线驱动方式,这种LCD可以方便地与各种低档单片机进行接口,如常用的LM1602、JHD12864等,都可以与8051、MEGA8等8位单片机连接使用。由于LCD已经带有驱动硬件电路,因此模块给出的是总线接口,便于与单片机的总线进行接口。驱动模块具有8位数据总线,外加一些电源接口和控制信号。而且还自带显示缓存,只需要将要显示的内容送到显示缓存中就可以实现内容的显示。由于只有8条数据线,因此常常通过引脚信号来实现地址与数据线的复用,以达到把相应数据送到相应显示缓存的目的。
(2)扫描器控制方式(www.xing528.com)
另外一种LCD显示屏没有驱动电路,需要与驱动电路配合使用。这种LCD体积小,但需要另外的驱动芯片,通常可以使用带有LCD驱动能力的高档MCU驱动,如ARM系列的S3C2410。S3C2410中具有内置的LCD控制器,它具有将显示缓存(在系统存储器中)中的图象数据传输到外部LCD驱动电路的逻辑功能。S3C2410中内置的LCD控制器可支持灰度LCD和彩色LCD。在灰度LCD上,使用基于时间的抖动算法(Time-based Dithering Algorithm)和FRC(Frame Rate Control)方法,可以支持单色、4级灰度和16级灰度模式的灰度LCD;在彩色LCD上,最高可以支持24位真彩。对于不同尺寸的LCD,具有不同数量的垂直和水平象素、数据接口的数据宽度、接口时间及刷新率,而LCD控制器可以进行编程控制相应的寄存器值,以适应不同的LCD显示板。
S3C2410中内置的LCD控制器的逻辑框图如图8-16所示,它用于传输显示数据并产生必要的控制信号,如VFRAME/VSYNC/STV、VLINE/HSYNC/CPV、VCLK/LCD_HCLK、VM/VDEN/TP、LEND/STH、LCD_PWREN。除了控制信号,还有显示数据的数据端口VD[23:0]。LCD控制器由寄存器组REGBANK、DMA控制器LCDCDMA、数据接口电路VIDPRCS、时钟发生电路TIMEGEN等组成。REGBANK包括17个可编程的专用寄存器和一个256×16bit的调色板,用于配置LCD控制器。LCDCDMA为专用DMA,它可以自动地将显示数据从帧内存中传送到LCD驱动器中。通过专用DMA,可以在不需要CPU介入的情况下显示数据。
图8-16 LCD控制器逻辑框图
S3C2410内置的LCD控制器可支持STN型的LCD显示器和TFT型的LCD显示器。与不同类型显示器接口时,其信号功能有所区别,具体信号功能描述如表8-6所示。
表8-6 S3C2410 LCD控制器接口
2.LCD控制器寄存器
S3C2410的LCD控制器包含17个可编程的控制寄存器,表8-7中列举了各个显示器的基本含义,更加详细的使用说明请参考S3C2410的数据手册。
表8-7 LCD控制器寄存器
续表8-7
3.LCD的显示方式和代码分析
(1)基本图形显示函数
JXARM9-2410的LCD显示模块由S3C2410的LCD控制器和16位色的彩色LCD显示屏组成。其显示方式以直接操作显示缓冲区的内容进行,LCD控制器会通过DMA从显示缓冲区中获取数据,不需要CPU干预。本系统采用的LCD分辨率为640×480,工作在16位色显示模式。在该模式下,显示缓冲区中的一个字节数据代表LCD上的一个点的颜色信息,因此,所需要的显示缓冲区大小为640×480×2字节。其中,VD输入时各引脚的数据内容与色彩的关系如图8-17所示(采用5∶6∶5颜色模式)。
图8-17 彩色数据格式示意图
在JXARM9-2410中以图形方式显示之前必须对LCD控制器进行初始化,其过程包括:
首先,初始化LCD端口,由于LCD控制端口与CPU的GPIO端口是复用的,因此必须设置相应寄存器,将其设置为LCD驱动控制端口;
其次,初始化LCD控制寄存器,包括设置LCD分辨率、扫描频率、显示缓冲区等。
详细的LCD初始化代码在程序LCDLIB.C的lcd_init()函数,该函数根据调用的参数进行不同的初始化,本实验的传入参数为“MODE_TFT_16BIT_640480”,main.c程序中对LCD初始化相关代码如下:
从以上代码可以看出,LCD控制器的初始化是通过对LCD控制寄存器的相关参数进行设置来完成的,这些设置值将根据连接的LCD显示屏的不同而有所调整。
在LCD初始化及相关输出信号使能后,可以向显示缓冲中写入像素点颜色实现显示。主要的显示函数包括:
最直观的图形显示方式,就是将图形中的颜色信息一个点一个点的输出到LCD的相应位置。有了上面的基础,实现整屏图形显示或者部分图形显示就变得非常简单。最关键的打点函数的代码分析如下:
函数中x表示显示屏的水平坐标,y表示显示展的垂直坐标,c表示坐标上点的显示颜色值,该值只有低16位有效。由于每个像素点需要两个字节来显示正确的颜色值,但是frameBuffer16Bit Tft640480的每个成员变量的大小为32bit。因此,在对显示像素的颜色赋值时需要做相应处理。当x为偶数时,~(0xffff0000>>((x)% 2)×16))结果为0x0000ffff,而((c&0x0000ffff)<<((2-1-((x)% 2))×16))的结果为c的低16位。向左移动16位,形成32位数据的高16位,最终颜色值c,放到对应的显示缓冲区frameBuffer16Bit Tft640480[(y)][x/2]中32位数据的高16位。当x为奇数时,~(0xffff0000>>((x)% 2)×16))结果为0xffff0000,((c&0x0000ffff)<<((2-1-((x)% 2))×16))的结果为c的低16位值,并存放到显示缓冲区地址frameBuffer16Bit Tft640480[(y)][x/2]中32位数据的低16位。
在画点的基础上,画线、面和矩形则变得十分简单了,画线的函数只需要在规定的坐标范围内连续打点就可以连成一条线;画面只需要连续画多根长度相关的线就可以实现。
(2)字符显示函数
LCD字符显示就是将字库(汉字字库、英文字库或者其他语言字库)中的字模以图形方式显示在LCD上,其显示原理和图形显示没有差别,只要把汉字当成一幅画,画在显示屏上就可以了。其关键在于如何取得字符的图形,也就是字符的点阵字模。
常用的汉字点阵字库文件,例如常用的16×16点阵HZK16文件,按汉字区位码从小到大依次存有国标区位码表中的所有汉字,每个汉字占用32个字节,每个区为94个汉字。在计算机中,汉字是以机内码的形式存储的,每个汉字占用两个字节:第一个字节为区码(qh),为了与ASCII码区别,范围从十六进制的A1H开始(小于80H的为ASCII码字符),对应区位码中区码的第一区;第二个字节为位码(wh),范围也是从A1H开始,对应某区中的第一个位码。这样,将汉字机内码减去A0A0H就得该汉字的区位码。因此,汉字在汉字库中的具体位置计算公式为:
location=[94×(qh-1)+wh-1]×一个汉字字模占用字节数一个汉字字模占用的字节数根据汉字库汉字的大小不同而不同。以HZK16点阵字库为例,字模中每一点使用一个二进制位(Bit)表示,如果是1则说明此处有点,若是0则说明没有。这样,一个16×16点阵的汉字总共需要16×16/8=32个字节表示。字模的表示顺序为:先从左到右,再从上到下,也就是先画第1行左上方的8个点,再画右上方的8个点,然后是第2行左边8个点,右边8个点,依此类推,画满16×16个点。因此在HZK16中,汉字在汉字库中具体位置的计算公式为:[94×(qh-1)+(wh-1)]× 32。例如汉字“房”的机内码为十六进制的“B7BF”,其中“B7”表示区码,“BF”表示位码,所以“房”的区位码为0B7BFH-0A0A0H=171FH。将区码和位码分别转换为十进制得汉字“房”的区位码为“2331”,即“房”的点阵位于第23区的第31个字的位置,相当于在文件HZK16中的位置为第32×[(23-1)×94+(31-1)]=67136B以后的32个字节为“房”的显示点阵。
相关定义在glib.c文件中的主要函数包括:
(1)ASCII码字符显示函数Glib_disp_ascii16x8(int x,int y,char*s,int colour);(2)汉字显示函数Glib_disp_hzk16(int x,int y,char*s,int colour)。
ASCII码字模通过ascii.h文件定义,汉字字模通过hzk16.h文件定义。显示汉字或字符时需要将这两个文件包含在程序中。这两个函数的代码分析如下:
8.4.2 触摸屏驱动控制代码
1.S3C2410触摸屏控制器
S3C2410微处理器的触摸屏控制电路如图8-18所示。该触摸屏为4线电阻式触摸屏,可以支持中断模式、自动读取模式、“X,Y”坐标分离获取模式。在中断模式下,每次触摸会产生一个ADC中断,由中断处理程序对该触摸进行坐标读取等操作;自动读取模式可以与中断模式配合,在中断处理程序中自动获取触摸屏的坐标值;“X,Y”坐标分离获取模式,由程序控制过程分别读取X坐标和Y坐标。
S3C2410提供专用触摸屏接口,可以在专用接口的支持下通过ADC端口获得触摸屏坐标值。触摸屏的X、Y方向读取点分别与AIN5、AIN7连接,X、Y值的数据采集过程就是通过两个A/D通道来完成。
采集X方向的数据:将XP(EINT21输出低电平)接外部电源,XM(EINT20输出高电平)接地,YP接A[5](EINT23输出高电平),YM悬空(EINT22输出低电平),通过采集通道AIN5可读到X的坐标电压值(存放于ADCDAT0寄存器)。
采集Y方向的数据:将YP(EINT23输出低电平)接外部电源,YM(EINT22输出高电平)接地,XP接A[7](EINT21输出高电平),XM悬空(EINT20输出低电平),通过采集通道AIN7可读到Y的坐标电压值(存放于ADCDAT1寄存器)。
取得的电压值为10位,即ADCDAT0。ADCDAT1的低10位为读出的X、Y有效值。为了保证准确性,通常采集5次以上数据,并通过求平均值的方式减小读取误差。
图8-18 JXARM9-2410教学实验系统的的触摸屏电路图
表8-7 S3C2410的ADC控制器寄存器ADCCON
表8-8 S3C2410的ADC触摸控制器寄存器ADCTSC
2.数据采集口初始化
S3C2410X带有专用的触摸屏控制口,可以通过对相关专用寄存器的设置实现X、Y方向电压的设置和读取,不需要对引脚作设置。主要的特殊功能寄存器包括ADC转换控制寄存器r ADCCON、触摸屏控制寄存器r ADCTSC,详见表8-8和表8-8所示。寄存器初始化方式如下:
//设置触摸屏控制参数
//将触摸屏设置为等待中断模式
3.等待触摸事件
本实验通过中断方式响应触摸屏事件,触摸屏处理函数指针为pISR_ADC。当触摸屏被点击后将产生ADC中断,程序将转入对应的中断处理程序函数Adc_or_TsSep()。该函数首先完成对触摸屏坐标位置的左上角和右下角相对参数的读取,以确定后续触摸点的坐标。
4.采集数据
数据采集通过A/D转换来实现。为了保证准确性,我们通常采集5次数据,并采用求平均值的方式来减小读取误差。首先采集Y方向的数据,这时需要将X+输出高电平,X-输出低电平;其次采集X方向的数据,这时需要将Y+输出高电平,Y-输出低电平。由于转换值以10位二进制方式表示,因此,转换后的X、Y取值范围为均为(0~1023),转换后对应的“X,Y”坐标需要进行一定的变换。
(1)中断处理程序中采集X方向数据的代码
Pty[5]=(Pty[0]+Pty[1]+Pty[2]+Pty[3]+Pty[4])/5;//取5次的平均值通过两次转换后,X、Y值被读出,再通过与显示屏的相对位置校正,就可以和显示屏联合到一起作为交互式图形界面的开发和使用了。
8.4.3 PWM波控制代码
1.脉宽调制(PWM)的基本原理
模拟电压和电流可直接用来进行控制,如汽车收音机音量的控制、电机转速的调整等。尽管模拟控制看起来直观而简单,但它并不总是经济或可行的。其中重要的一个原因就是,模拟电路容易随时间漂移,因而难以调节。能够解决这个问题的精密模拟电路可能非常庞大、笨重和昂贵,而且模拟控制电路有可能产生严重发热,还可能对噪声敏感,任何扰动或噪声都可能会改变控制系统中电流值的大小。
如果通过数字方式来控制模拟电路,则可以大幅度降低系统的成本和功耗。最常使用的一种数字控制方式就是脉冲宽调制技术。脉宽调制(PWM)是利用微处理器,以数字量输出的方式来实现对模拟电路控制的一种技术,被广泛应用于测量、通信、功率控制、转速控制等许多领域。PWM的一个优点是从处理器到被控系统信号都是数字式的,无需进行数模转换。信号以数字形式传递可将噪声对系统的影响降到最低,噪声信号只有强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,才能对数字信号产生影响。
PWM是通过对模拟信号电平进行数字编码的方法来实现控制的一种技术方法。将模拟信号用数字方式进行编码,如果需要输出一定的模拟量,则以一个数字值来表示,该数字值可以控制计数器按一定占空比开关电路,让电流以通、断、通、断的形式输出,从而达到调整输出模拟信号的目的。PWM控制输出的是一个方波形式,其任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
图8-19显示了三种不同的PWM信号。一个是占空比为10%的PWM输出,即在信号周期中,10%的时间通,其余90%的时间断。另外两个显示的分别是占空比为50% 和70%的PWM输出。这三种PWM输出编码的区别是强度为满度值的10%、50%和70%的三种不同模拟信号值。例如,假设供电电源为9V,占空比为10%,则对应的是一个幅度为0.9V的模拟信号。
图8-19 PWM驱动的简单电路
图8-19还画出了一个可以使用PWM进行驱动的简单电路。图中使用9V电池来给一个白炽灯泡供电。如果将连接电池和灯泡的开关闭合50ms,灯泡在这段时间中将得到9V供电。如果在下一个50ms中将开关断开,灯泡得到的供电将为0V。如果在1秒钟内将此过程重复10次,灯泡将会点亮并像是连接到了一个4.5V电池(9V的50%)上一样。这种情况下,占空比为50%,调制频率为10Hz。
大多数负载(无论是电感性负载还是电容性负载)需要的调制频率高于10Hz。设想一下,如果灯泡先接通5秒再断开5秒,然后再接通、再断开……占空比仍然是50%,但灯泡在头5秒钟内将点亮,在下一个5秒钟内将熄灭。要让灯泡取得4.5V电压的供电效果,通断循环周期与负载对开关状态变化的响应相比,时间必须要足够短。要想取得调光灯(保持点亮)的效果,必须提高调制频率。在其他PWM应用场合也有同样的要求,通常调制频率为1k Hz~200k Hz之间。
2.PWM硬件控制器
许多微控制器内部都包含PWM控制器。一般都可以选择接通时间和周期。占空比是接通时间与周期之比;调制频率为周期的倒数。具体的PWM控制器在编程细节上会有所不同,但它们的基本思想通常是相同的。执行PWM操作之前,微处理器要求在软件中完成以下工作:
(1)设置提供调制方波的片上定时器/计数器的周期;
(2)在PWM控制寄存器中设置接通时间;
(3)启动定时器。
3.S3C2410X的PWM控制器
S3C2410X处理器有5个16位定时器,其中定时器0/1/2/3有PWM脉冲输出功能。图8-20描述了S3C2410X定时器的结构框,定时器0和定时器1使用相同的分频器,但它们的计数器以及控制器是各自独立的,定时器2/3/4、各定时器的精度见表8-9。
图8-20 S3C2410X定时器结构图
表8-9 定时器精度
另外,S3C2410X的定时器还有一个特殊的功能,即双缓冲功能,使用该功能可以在不停止本次操作的情况下改变下一个周期值。比如当前的周期为1秒,在运行过程中,我们可以更改周期值,而不会影响当前的这个周期,新的周期值直到本次定时结束后才被更新到寄存器中。
4.S3C2410X定时器有关的寄存器
(1)PWM定时器配置寄存器
用于设置定时器的分频值以及工作模式。对分频值的设定共有两个特殊功能寄存器管理,其中一个管理预分频值,另一个管理定时器工作模式。见表8-10、表8-11、表8-12所示。
表8-10 定时器配置寄存器
表8-11 TCFG0寄存器功能描述
表8-12 TCFG1寄存器功能描述
续表8-12
(2)PWM定时器初值计数器以及比较计数器
在PWM信号中除了需要设置PWM波的输出频率外,还有一个十分重要的内容就是要控制其输出信号的占空比。占空比也是通过设置相应计数寄存器来实现的。在S3C2410中,每一路PWM波设置两个寄存器用于控制其PWM波的占空比输出,一个是计数缓冲寄存器TCNTB,用于描述每个PWM所占的定时长度;另一个是比较缓冲寄存器TCMPB,用于描述每个PWM波中高电平所用的定时长度。TCMPB的值必须小于TCNTB的值。
(3)PWM定时器控制寄存器
对于定时器的工作模式,还设置了另一个寄存器TCON,该寄存器用于设置5个定时器的工作模式。该寄存器功能描述见表8-13所示。
表8-13 TCONP定时器控制寄存器功能
续表8-13
5.S3C2410XPWM波驱动代码分析
PWM驱动控制代码主要包括两部分内容:一个是对输出PWM波频率的控制,另一个是对PWM输出占空比的控制。代码分析如下。
(1)编程改变PWM输出的频率
8.5 ARM9硬件平台上的综合应用开发实例
本节将围绕ARM9硬件平台上的资源,通过合理组织和管理,实现具有一定现实功能的综合应用装置。通过本节的介绍,读者可以了解ARM9系统的综合开发过程和编程思想,为进一步实践打下基础。
8.5.1 简单电子琴系统设计及分析
本实例将利用实验箱上的4×4键盘和PWM波功能控制蜂鸣器发声,根据不同的按键输出不同的声音频率,并在LCD上显示出对应的频率示意图。由于代码较简单,书中给出整个系统的流程图,及部分功能函数代码,读者可以根据流程图自己完成相关验证工作。
系统工作原理如下:在完成初始化工作后,读取按键的键值,根据键值的不同,查表求得对应音符的频率值,并利用该值控制PWM波输出一定时间的该频率,可以通过调整占空比来调整音色。简谱中各个音的频率值数组为{523,578,659,698,784,880,
系统总体流程图如图8-21所示。
图8-21 简单电子琴程序流程图
8.5.2 简易电子画笔设计与分析
本实例将利用实验箱的触摸屏和LCD显示屏,设计一个简易的电子画笔系统。其基本思想是反复采集触摸屏上的触摸信息,转换为与显示屏对应的位置信息,在显示屏上进行图像绘制。本书将给出主要的坐标校正的函数代码分析和系统实现流程图,读者可以自己根据流程图完成相关验证工作。
1.触摸屏坐标与LCD显示屏坐标的校正函数分析
坐标校正分两步进行,首先初始化触摸屏相关寄存器后,提示开始校正,并显示一个十字作为校正标志;其次在触摸屏中断处理程序中完成第一次校正操作的读取,并提示第二个校正点的坐标和标志,启动相应中断。第二次校正操作读取后将进行校正计算处理,校正处理完成后,还应继续打开触摸屏中断。这时系统处于正常工作状态,如果有触摸动作,中断处理程序将读取相应的触摸点,并根据读取坐标经校正后,调用显示函数显示到LCD上。
2.简易画笔系统流程图
在本流程图中,并没有设计不同颜色和粗细的画笔选择功能,读者可以自己在流程图中加入相关动作,并编程实现,以使得该简易画笔功能更为完整。详见图8-22。
8.5.3 简易连连看游戏设计与分析
本实例将介绍一个基于实验箱的交互式连连看游戏的设计与分析,该系统设计的关键点包括:(1)如何利用工具将位图信息转换成对应的图形数组信息;(2)如何将图形数组放到LCD上显示;(3)如何分布各图片,得到不同的游戏界面;(4)如何确定坐标后的消除算法。接下来将分别介绍各个相关函数的实现。
我们通常取得的图片文件为JPG、BMP等,但是在无法读取外部文件的情况下,函数如何获得图片的相关信息呢?在嵌入式系统设计中,最常采用的方法就是将这些图片文件通过工具转换成一个数组,并将这个数组作为程序的静态数据放入可执行代码。虽然采用这种方式可能会增加可执行代码的长度,但是却十分简单高效。当然,我们也可以直接将图片文件作为静态数据放入执行代码,但是这些图片文件却包含有格式信息,在使用时还需要进行格式分析。因此,直接将图片文件放入程序的做法并不多见。这样的转换工具很多,如BMP2C、BMP2H等,当然也可以自己编程实现。转换后,每个像素点用两个字节描述,只要按图片大小正确显示到LCD上就可以了。
将图片数组显示到LCD的函数分析如下:X、Y为待显示图片的起点位置,bmp[]为待显示图片的数组指针,该函数将一个40×40像素的图片数组显示到LCD的指定坐标。
图8-22 简易电子画笔系统流程图
将若干图片随机布局到游戏界面的函数分析如下。
连连看游戏需要使每次图像的布局有所不同才具有可玩性。该函数通过调用一个随机函数的方式得到一个随机分布图来完成这个功能。数组arr[NSIZE+2][NSIZE+2]的大小可以根据图片大小和显示屏大小确定。随机分布采取两步随机方式获得不同游戏界面,第一步是随机获取待显示的图片,并保证游戏界面中有偶数个该图片;第二步是随机获取位置坐标,并通过随机交换位置的方式来实现游戏界面的变化,同时保证图片数量和比例不变。
由于不同连通状态的游戏计分值有所不同,所以在保证连通消除的同时,还需要对连通行为进行判断和计分。这里的基本算法如下。
(1)对于直连型关系而言,由于两者处于一个一维关系下,直接判断一维关系下的连通即可。
图8-23 有一次转折的连通情况示意图
(2)对需要有一个转折的情况,相当于以两个被选点为对角顶点,划一个矩形,通过对该矩形边的判断来判断是否连通。如图8-23所示红色棋子的连通情况,右上角打叉的位置就是折点。
(3)具有二次转折的连通情况。这种情况更具有普遍性。判断是否具有二次转换连通性需要做两个方向的扫描,即水平扫描和垂直扫描。可以先看水平方向,首先,要找到被选点左右可延伸范围,也就是空缺位置;其次,计算水平坐标上两个被选点延伸后是否具有公共水平坐标;最后,判断水平坐标是否可以垂直连通(没有隔断点),如图8-24(a)、8-24(b)所示。
图8-24 具有二次转折的连通示意图1
由图8-24(b)可以看出,左边缘有一对叉可以直连,所以红色棋子是可以“二次转折连通”的。垂直方向也同样可以采用这种方式进行判断,如图8-25(a)、8-25(b)所示。
图8-25 具有二次转折的连通示意图2
8-25(b)可以看出,上边缘有一对叉可以直连,第2行也有一对,所以红色棋子是可以“二次转折连通”的。
其代码实现和分析如下。通过上面的分析不难发现,对于二次转折连通的判断,实际也可以用于判断“直连型”和“一次转折型”的连通性,它们都是“二转折型”的特例。所以在代码实现时只需要在一个具有通用的“二次转折型”连通算法就够了。函数中的arr [NSIZE+2][NSIZE+2]表示游戏中的布局情况,ai、aj表示第一个被选点的坐标,bi、bj表示第二个被选点的坐标。
本章介绍的几个实例都具有一定的趣味性,有兴趣的读者可以在本章的指导下,利用类似的硬件实验平台完成相关的系统实现和验证工作。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。