1、沈阳理工大学课程设计专用纸 目录 第一章 引言 . - 1 - 第二章 设计目的 . - 2 - 第三章 设计原理 . - 3 - 第四章 关键技术 . - 4 - 4.1 ARM9 处理器 . - 4 - 4.2 嵌入式 C 语言开发技术 . - 4 - 4.3 ADS 开发环境 . - 5 - 4.4 基于 ARM9 的硬件 . - 6 - 第五章 程序流程 . - 7 - 5.1 初始化和结束程序 . - 7 - 5.2 服务于 I/O 请求的函数 . - 7 - 5.3 中断服务程序 . - 9 - 第六章 主要源代码 . - 10 - 6.1 定义与 A/D 转换相关的寄存器 . -
2、 10 - 6.2 对 A/D 转换器进行初始化 . - 10 - 6.3 获取 A/D 的转换值 . - 10 - 6.4 主函数 . - 11 - 6.5 子函数 . - 15 - 第七章 结论 . - 23 - 第八章 心得体会 . - 24 - 参考文献 . - 25 - 沈阳理工大学课程设计专用纸 - 1 - 第一章 引言 由于 Linux 系统是开源系统 ,其内核和各种开发工具都可以从网络上轻易获取 ,使其在嵌入式系统的开发中得到了越来越广泛的应用。但 Linux 系统本身并没有对种类繁多的 硬件设备都提供现成的驱动程序 ,特别是由于工程应用中的灵活性 ,其驱动程序更是难以统一 ,
3、这时就需开发一套适合于自己产品的设备驱动 ,使得 Linux 设备驱动程序的开发在整个嵌入式系统开发工作中占有很重要的地位。而基于 ARM 架构的中高档的嵌入式系统应用已经非常广泛 ,本文针对现在非常流行的一款三星公司生产的 ARM9 嵌入式微处理器 S3C2440,在 Linux 操作系统下实现了多路 AD 转换的驱动 ,通过该驱动程序实例 ,介绍在 Linux 系统下驱动程序编写的一般方法 ,包括驱动程序和测试程序的编写。 1 硬件设备硬件系统核心部分采样的是 韩国三星公司设计的基于 ARM9 的嵌入式微处理器 S3C2440。S3C2440 配合 SDRAM、 FLASH、 USB、网口
4、和串口等就构成了基本的 ARM 嵌入式硬件平台。 本文针对现在非常流行的一款三星公司生产的 ARM9 嵌入式微处理器S3C2410,在 Linux 操作系统下实现了多路 AD转换的驱动 ,通过该驱动程序实例 ,介绍在 Linux 系统下驱动程序编写的一般方法 ,包括驱动程序和测试程序的编写。 沈阳理工大学课程设计专用纸 - 2 - 第二章 设计目的 通过课程设计,熟悉基于 ARM 微处理器的嵌入式系统开发的过程,掌握嵌入式系统开发的 A/D 接口原理,掌握 S3C2410 的 AD 相关寄存器的配置及编程应用方法,锻炼实践动手能力和团队协作能力。 沈阳理工大学课程设计专用纸 - 3 - 第三章
5、 设计原理 A/D 转换器是模拟信号和 CPU 之间联系的接口,它是将连续变化的模拟信号转换为数字信号,以供计算机和数字系统进行分析、处理、存储、控制和显示。在工业控制和数据采集及许多其他领域中, A/D 转换是不可缺少的。 按照转换速度、精度、功能以及接口等因素,常用的 A/D 转换器有以下两种: ( 1)双积分型的 A/D 转换器 双积分型也称为二重积分式,其实质 是测量和比较两个积分的时间,一个是对模拟信号电压的积分时间 T,此时间常是固定的,另一个是以充电后的电压为初值,对参考电源 Vn的反向积分,积分电容被放电至零,所需的时间 Ti。模拟输入电压 Vi 与参考电压 Vref 之比,等
6、于上述两个时间之比。由于 Vref、 T 时间固定,而放电时间 Ti可以测出,因而可以计算出模拟输入电压的大小。 ( 2)逐次逼近型的 A/D 转换器 逐次逼近型也称为逐位比较式,它的应用比积分型更为广泛,通常主要有逐次逼近寄存器 SAR、 D/A 转换器、比较器以及时序和逻辑控制等部分组成。通过逐次把设定的 SAR 寄 存器中的数字量经 D/A 转换后得到电压 Vc与待转换模拟电压 V0 进行比较。比较时,先丛 SAR 的最高位开始,逐次确定各位的数码应为 1还是 0,而得到最终的转换值。其工作原理为:转换前,先将 SAR 寄存器各位清零,转换开始时,控制逻辑电路先设定 SAR 寄存器的最高
7、位为 1,其余各位为 0,此值经 D/A 转换器转换成电压 Vc,然后将 Vc与输入模拟电压 Vx 进行比较。如果 Vx 大于等于 Vc,说明输入的模拟电压高于比较的电压, SAR 最高位的 1应保留;如果 Vx 小于 Vc,说明 SAR 的最高位应清除。然后在 SAR 的次高位 置 1,依上述方法进行 D/A 转换和比较。如此反复上述过程,直至确定出SAR 寄存器的最低位为止,此过程结束后,状态线改变状态,表明已完成一次转换。最后,逐次逼近寄存器 SAR 中的数值就是输入模拟电压的对应数字量。位数越多,越能准确逼近模拟量,但转换所需的时间也越长。 沈阳理工大学课程设计专用纸 - 4 - 第四
8、章 关键技术 4.1 ARM9 处理器 新一代的 ARM9 处理器,通过全新的设计,采用了更多的晶体管,能够达到两倍以上于 ARM7 处理器的处理能力。这种处理能力的提高是通过增加时钟频率和减少指令执行周期实现的。 ARM9 系列包括三种处理器: ARM926EJ-S、 ARM946E-S 和 ARM968E-S。 ( 1) ARM968E-S 面积最小、包含 DSP 增强功能的 ARM9 处理器,针对低功耗、数据密集型、嵌入式实时应用 。 面积最小、功耗最低的 ARM9 处理器是众多实时类型应用的理想之选。通过可轻松从标准接口集成的紧密耦合内存,该处理器可高效工作。 ( 2) ARM946E
9、-S 具有 MPU 的 DSP 增强型高速缓存处理器,针对运行 RTOS 的实时应用 。 一种具有可选高速缓存接口以及完整的内存保护单元的实时处理器。对于大部分代码位于主存储器的应 用,该处理器非常有用,它按需加载到高速缓存中,同时关键的异常处理代码和数据仍本地保留在紧密耦合内存中。 ( 3) ARM926EJ-S 具有 Java 加速、 DSP 扩展和 MMU 的应用处理器,针对基于操作系统的应用 。 ARM926EJ-S 处理器为入门级处理器,可支持完全版操作系统,其中包括 Linux、 Windows CE 和 Symbian。因此,此处理器是众多需要完整图形用户界面的应用的理想之选 1
10、。 4.2 嵌入式 C 语言开发技术 由于现在越来越多的产品都采用嵌入式开发,所完成的计算和控制工作也日趋复杂 ,而嵌入式系统是一种资源十分有限的系统(这主要表现在程序存储器资源的不足上),因此在程序设计时如何使用好这些有限的资源就显得十分重要。用 C 语言变成虽然具有许多的优点,但是生成的代码相对较长,若编程技术不好,生成的代码有可能比汇编语言生成的代码长几倍,因而对编程者来说,应该注意沈阳理工大学课程设计专用纸 - 5 - 到嵌入式 C 语言和一般意义上的标准 C语言的区别,对程序进行适当的优化。 嵌入式 C语言编程不同于一般的 C语言编程的一个显著特点,就是要和程序存储器资源结合起来。虽
11、然其提供的数据类型十分丰富,但其中只有 bit 和 char等数据类型是机器 语言直接支持的数据类型,用此类数据类型的语句所生成的代码较短;而其他的数据类型如整形、浮点型等数据要有一定的内部程序或内部函数的支持,用该类数据类型的语句生成的代码则相对教程。 4.3 ADS 开发环境 1.运行 ADS1.2 集成开发环境( CodeWarrior for ARM Developer Suite),点击 File|New,在 New对话框中,选择 Project栏,其中共有 7项, ARM Executable Image 是 ARM 的通用模板。选中它即可生成 ARM 的执行文件。同时,还要在,P
12、roject name栏中输入项目的名称,以及在 Location 中输入其存放的位置。按确定保存项目。 2.在新建的工程中,选择 Debug 版本,使用 Edit|Debug Settings 菜单对Debug 版本进行参数设置。 3.点击 Debug Setting 按钮,选中 Target Setting 项,在 Post-linker栏中选中 ARM fromELF 项。按 OK确定。这是为生成可执行的代码的初始开关。 4.点击 ARM Assembler ,在 Architecture or Processer 栏中选 ARM920T。这是要编译的 CPU 核。 5.点击 ARM C
13、 Compliler ,在 Architecture or Processer 栏中选ARM920T。这是要编译的 CPU 核。 6.点击 ARM linker ,在 outpur 栏中设定程序的代码段地址,以及数据使用的地址。 RO Base 栏中填写程序代码存放的起始地址, RW Base 栏中填写程序数据存放的起始地址。该地址是属于 SDRAM 的地址。在 options 栏中, Image entry point 要填写程序代码的入口地址,其他保持不变,如果是在 SDRAM 中运行,则可在 0x30000000 0x33ffffff 中选值,这是 64M SDRAM 的地址,但是这里用
14、的是起始地址,所以必须把你的程序空间给留出来,并且还要留出足够的程序使用的数据空间,而且还必须是 4 字节对齐的地址( ARM 状态)。通常入口点Image entry point 为 0x30000000,ro_base 也为 0x30000000。在 Layout 栏中,在 Place at beginning of image 框内,需要填写项目的入口程序的目标文件名,沈阳理工大学课程设计专用纸 - 6 - 如,整个工程项目的入口程序是 2410init.s,那么应在 Object/Symbol 处填写其目标文件名 2410init.o,在 Section 处填写程序入口的起始段标号。
15、7.在 Debug Setting 对话框中点击左栏的 ARM fromELF 项,在 Output file name 栏中设置输出文件名 *.bin,前缀名可以自己取,在 Output format 栏中选择 Plain binary,这是设置要下载到 flash 中的二进制文件。 8. 到此,在 ADS1.2 中的基本设置已经完成,可以将该新建的空的项目文件作为模板保存起来。首先,要将该项目工程文件改一个合适的名字,如 S3C2410 ARM.mcp 等,然后,在 ADS1.2 软件安装的目录下的 Stationary 目录下新建一个合适的模板目录名,如, S3C2410 ARM Exe
16、cutable Image,再将刚刚设置完的S3c2410 ARM.mcp 项目文件存放到该目录下即可。这样,就能看到该模板。、9.新建项目工程后,就可以执行菜单 Project|Add Files 把和工程所有相关的文件加入, ADS1.2 不能自动进行文件分类,用户必须通过 Project|Create Group 来创建文件夹,然后把加入的文件选中,移入文件夹。或者鼠标放在 文件填加区,右键点击,即出! 先选 Add Files,加入文件,再选 Create Group,创建文件夹,然后把文件移入文件夹内。读者可根据自己习惯,更改Edit|Preference 窗口内关于文本编辑的颜色、
17、字体大小,形状,变量、函数的颜色等等设置。 4.4 基于 ARM9 的硬件 ARM9 系统的硬件设计,是一项复杂的系统工程,必须有坚实的准备知识,包括电路基础、模拟电路、数字电路、微机原理、接口技术、嵌入式原理、 ARM系统原理等等。不仅需要硬件相关的知识,而且需要软件方面的知识,如操作系统。由于是复杂的硬件系 统的设计,还需要掌握 EDA 软件。 此外,由于硬件开发还涉及焊接、调试等工序,所以还应该对元器件的封装、电气特性等有所了解,并掌握焊接技术,能对一般的贴片元件进行手工焊接。这方面的知识需要在实践中积累经验,很难一蹴而就。 做 ARM9 系统的硬件设计,一般采用六层板,成本较高。为了避
18、免因设计的错误而付出沉重的代价,应从简单的硬件设计做起,有助于提高 ARM9 系统设计的成功率。 沈阳理工大学课程设计专用纸 - 7 - 第五章 程序流程 驱动程序的组成及设计 驱动程序是操作系统内核与硬件设备的直接接口 ,驱动程序屏蔽了硬件的细节 ,使得应用程序可以像操作普通文 件一样对硬件设备进行操作。 Linux 将设备分为字符设备 ,块设备和网络设备三种。 A/D 转换是属于字符设备。设备驱动程序主要完成如下功能 4: (l)对设备初始化和释放 ; (2)把数据从内核传送到硬件和从硬件读取数据 ; (3)读取应用程序传送给设备文件的数据并回送应用程序请求的数据 ; (4)检测和处理设备
19、出现的错误。 在系统内部 ,I/O 设备的存取是通过一组固定的入口点完成与外部的通信 ,这些入本驱动程序的工作流程如图 1所示 ,主要由 3大模块组成。 5.1 初始化和结束程序 在驱动程序设计中通常通过使用 _init 和 _exit 声明来定义用户自己的初始 化 函 数 和 清 除 函 数 , 然 后 使 用 module_init(mydev_int) 和module_exit(mydev_cleanup) 来 完 成 设 备 驱 动 程 序 的 注 册 和 卸 载 ( 其mydev_init 和 mydev_cleanup 函数即为用 _init 和 _exit 声明的初始化函数和清除
20、函数 )。在本驱动程序中初始化函数 adc_init()主要完成一些初始化的工作 ,包括对硬件设备的初始化、中断的注册、设备的注册等 ,初始化部分仅在驱动程序初始化的时候被调用一次 ,而缷载函数则完成相反的功能。 5.2 服 务于 I/O请求的函数 在系统内部 ,I/O 设备的存取是通过一组固定的入口点完成与外部的通信 ,这些入口点通过一个 file_operations 数据结构在注册设备文件时与外部调用函数关联起来 ,它是字符设备驱动程序的核心 ,结构中的每个成员名字都对应着一个系统调用。该结构实际就是声明了针对各种设备不同操作的函数指针 ,Linux下驱动程序的大部分工作 ,实际上就是完
21、成上述各种操作方法的函数。但是实际的驱动程序中并不需要为每一个操作都编写相应的实现代码 ,对于不需要的操作 ,沈阳理工大学课程设计专用纸 - 8 - 可在初始化 file_oper ations 结构时在相 应的位置赋予空指针 NULL 即可 5。本驱动通过调用 open 入口点 ,为将要进行的 I/O 操作做好准备工作 ,包括初始化中断事件变量、设置 AD 转换通道等 ,在此通过一个 for 循环来设置 4个 AD 转换通道 ,以实现打开 4 个 AD通道的要求 ;通过 read 入口点设置 ADCCON 控制寄存器启动 AD 转换 ,并设置中断事件变量使程序进入等待转换结束 ,在中断事件激
22、活后 ,通过 copy_to_user 内核函数将转换结果传送到用户空间变量指针来完成整个A/D 转换。 AD 转换大部分过程都是在 adc_read()函数 (它为应用程序系统调用 read 函数时调用的函数 )里实现的 ,它是 AD 转换的主体函数 ,在此函数中通过判断通道号实现了多通道 AD 转换 ,部分实现代码如下 : staticssize_tadc_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos) START_ADC_AIN(adcdev.channel,adcdev.prescale);/启动 AD 转换 wait
23、_event_interruptible(adcdev.wait,ev_adc);/通过中断的方式等待结果 if(converter_channel=3)/通道的选择 converter_channel=0; elseconverter_channel+; adcdev.channel=converter_channel;value=adc_data; intr=copy_to_user(buffer,str,len);/将内核空间中的数据拷贝到用户空间 ,以供应用程序使用 沈阳理工大学课程设计专用纸 - 9 - 5.3 中断服务程序 在 Linux 系统中 ,中断是由系统来管理与维护的。中断
24、服务子程序在初始化函数中调用 irq_request 函 数与相应中断号关联 ,并将该中断的相关信息添加到系统的中断信息列表中 ,以便在中断发生时供系统检索。目标机上完成某一 AD转换后 ,将产生一中断号为 IRQ_ADC_DONE 的中断 ,系统将自动检索并调用相应的中断服务子程序。此处的中断服务子程序完成 ADC 寄存器中读取转换结果 (通过adc_data=ADCDAT0实现 )、激活中断事件变量 ,从而 read 函数结束等待状态 ,返回 AD 转换结果 本次课程设计仅使用实验教学系统的 CPU 板。在进行本实验时, LCD 电源开关、音频的左右声道开关、 AD 通道选择开关、触摸屏中
25、断 选择开关等均应处在关闭状态。 在 PC机并口和实验箱的 CPU 板上的 JTAG 接口之间,连接仿真调试电缆。使用串口线连接 PC 机串口 1 和实验箱 CPU 板的串口,使用直连线连接底板串口 2和 PC 机上的串口 2 之间的电缆。 检查连接是否可靠,可靠后,接入电源线,系统上电。拨码开关 SW3 为选中的 A/D 转换的通道,值得注意的是本实验系统八个通道可以同时采集一个信号源。实验时要选中采集的通道号,即对应的 SW3 开关拨到 ON 状态。例如 SW3 的1拨到 ON 状态,说明用 AD 转换器的通道 1采集,如果, 8 个通道全部选择为 ON,则表示用 8 个通道采 集。本实验
26、程序使用通道 1采集数据,所以, SW3 的 1 应该拨到 ON 状态。要给 ADIN 一个输入信号 ,可以是底板上的 SQUARE 信号和 SINE 信号 ,也可是外部信号 ,但是必须注意 ,接外部电压信号时 ,要共地 ,以及信号的电压范围为 0 2.5V 打开 ADS1.2 开发环境 ,连接编译运行通过后,全速运行映象文件。打开 LCD电源开关, 检查 SW3 上选择的是通道几。确认后,观察 LCD 上 1通道当前采集的情况。由于液晶的显示速度比波型慢许多,所以要暂停程序才会看到比较清楚的波形。由于信号源输出后,电压经过缩放和偏置处理。使得的 ARM CPU 板所采集到的电压值的变化范围不足 0 2.5V,故而采集到的数字值,不能满程。但这些不会影响实验原理的显示。