资源描述
摘要本课程设计要求利用实验室提供的ARM2410实验箱进行相应的设计,主要包括理解LED原理,掌握在Linux下常用编辑器的使用,掌握MAKEFILE的编写和使用,掌握LINUX下的程序编译与交叉编译过程,有一定的数字电路的知识,能够设计出新颖的显示图样,最后通过上下位机实现结果的显示。嵌入式系统一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统、用户应用程序4个部分组成。Linux操作系统是-个开放源代码的免费操作系统,它不仅安全、稳定、成本低,而且很少发现有病毒传播,越来越的服务器、工作站和个人电脑开始使用Linux软件,基于Linux具有稳定、可靠和强大的网络功能这些优点。关键字:嵌入式;LINUX;ARM2410;LED目录一、引言1二、实验内容22、1 实验目的22、2 实验设备及工具22、3 实验基础22、4 实验平台22、4、1 嵌入式系统简介22、4、2 建立开发环境32、4、3 给下位机烧写软件系统3三、基本原理43、1 LED显示控制原理43、1、1 7段(8段)LED原理43、1、2 点阵式LED原理53、2 74HC273基本原理63、3 74HC273在开发板上的连接73、3、1 7段(8段)LED的连接73、3、2 点阵式LED的连接73、4 LED 编程93、4、1 7段LED的段码表93、4、2 点阵式LED的显示缓冲区93、4、3 C语言编程9四、实验环境连接10五、程序分析14六、 实验步骤15七、结果分析17八、总结18九、参考文献19附录20一、引言 LED电子显示是利用发光二极管点阵模块或像素单元组成的平面式显示屏幕。它是集成微电子技术、光电子技术、计算机技术、信息处理技术于一体的显示系统,是目前国际上极为先进的显示媒体。由于它具有发光效率高、使用寿命长、组态灵活、色彩丰富、工作性能稳定以及对室内室外环境适应能力强等优点而日渐成为显示媒体中的佼佼者。在我国改革开放之后,特别是进入90年代国民经济高速增长,对公共场合发布信息的需求日益增强,LED显示屏的出现正好适应了这一市场形势,因而在LED显示的设计制造技术与应用水平上都得到了迅速的提高,生产也得到了迅速的发展,并逐步形成产业,成为光电子行业的新兴产业领域。LED显示经历了从单色、双色图文显示屏的发展过程。随着信息产业的高速发展,LED显示屏作为信息传播的一种重要手段成为现代信息化社会的一个闪亮标志。近年LED显示屏已广泛应用于室内、外需要进行服务内容和服务宗旨宣传的公众场所如银行、营业部、车站、机场、港口、体育场馆等信息的发布,政府机关政策,各类市场行情信息的发布和宣传等。目前,对于那些需要显示的信息的信息量不是很大,分辨率不是很高,有需要制造成本相对比较低的场合,使用小屏幕LED点阵显示器是比较经济使用的。LED之所以受到广泛重视而得到迅速发展,是与它本身所具有的优点分不开的。这些优点概括起来是:亮度高、工作电压低、功耗小、小型化、寿命长、耐冲击和性能稳定。LED的发展前景极为广阔,目前正朝着更高亮度、更高耐气候性、更高的发光密度、更高的发光均匀性,可靠性、全面化方向发展。 二、实验内容2、1 实验目的(1) 学习LED的相关知识(2) 掌握74HC273芯片的工作原理(3) 了解SPI接口的相关知识2、2 实验设备及工具硬件:UP-TECH S2410/P270 DVP 嵌入式实验平台、PC 机 Pentium 500 以上, 硬盘 10G 以上。软件:PC 机操作系统 REDHAT LINUX 9.0MINICOMARM-LINUX 开发环境 2、3 实验基础 目的是为后续实验搭建好软、硬件环境,配置好相关的协议、服务,并通过编写最简单的HelloWorld程序进行测试。由于实验都要依靠前面的配置,本段只着重叙述实验的具体实现。2、4 实验平台 2、4、1 嵌入式系统简介 嵌入式系统是基于单片机的一种升级版,它是以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。我们可从几方面来理解嵌入式系统: 1、嵌入式系统是面向用户、面向产品、面向应用的,嵌入式系统是与应用紧密结合的,它具有很强的专用性,必须结合实际系统需求进行合理的裁减利用。嵌入式系统和具体应用有机地结合在一起,它的升级换代也是和具体产品同步进行,因此嵌入式系统产品一旦进入市场,具有较长的生命周期。 2、嵌入式系统是将先进的计算机技术、半导体技术和电子技术和各个行业的具体应用相结合后的产物。这一点就决定了它必然是一个技术密集、资金密集、高度分散、不断创新的知识集成系统。 3、嵌入式系统必须根据应用需求对软硬件进行裁剪,满足应用系统的功能、可靠性、成本、体积等要求。为了提高执行速度和系统可靠性,嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。 4、嵌入式系统本身不具备自主开发能力,即使设计完成以后用户通常也是不能对其中的程序功能进行修改的,必须有一套开发工具和环境才能进行开发。实际上,凡是与产品结合在一起的具有嵌入式特点的控制系统都可以叫嵌入式系统。现在人们讲嵌入式系统时,某种程度上指近些年比较热的具有操作系统的嵌入式系统。 2、4、2 建立开发环境 1在下位机断电的情况下,利用实验箱中自带的串口线将上位机的com1口与下位机的RS232-0口进行连接。 2利用实验箱中自带的直连网线将上位机与下位机进行连接。 3根据下位机中安装的核心模块,选择相应的嵌入式系统开发软件光盘。 4将选择好的嵌入式系统开发软件光盘放入上位机的光驱中,在终端命令窗口中挂载该光盘。mount o iocharset=gb2312 /dev/cdrom /mnt 5进入光盘的Linux工具软件目录。执行该目录下的shell文件“install.sh”,Linux工具软件会自动安装完成。对于S2410,会将程序安装在目录“arm2410cl”下,交叉编译器安装在目录“/opt/host”下。用户可以通过使用命令“armv41-unknown-linux-gcc”运行交叉编译器。 6启动minicom超级终端程序,选择“Serial port setup”进入串口配置界面进行串口配置。然后可以打开下位机的电源,通过minicom对下位机进行操作。 7使用命令ifconfig分别查看上位机和下位机的IP地址,判断上位机与下位机是否处于同一个网段。若它们不在同一网段,使用命令ifconfig或者KDE桌面的工具,将它们配置在同一网段。使用命令ping查看上位机与下位机的网络连接是否正常,如不正常,请检查网线的连接、IP地址的配置、IP地址是否冲突等。 8将上位机配置为NFS服务器,设置共享目录为“/arm2410cl”。 9在上位机中启动NFS服务,下位机使用命令mount挂载上位机的共享目录。 mount t nfs 192.168.0.252:arm2410cl /mnt/nfs 2、4、3 给下位机烧写软件系统下位机的软件系统由Bootloader、系统内核、根文件系统和应用程序四部分组成。Bootloader相当于PC机上的BIOS,在下位机加电时自动运行,执行硬件初始化和调用系统内核的功能。Bootloader分为U-boot、Vivi、Blob、ARMBoot、RedBoot等多种,本实验使用实验箱自带光盘中的vivi。系统内核就是运行在下位机上的操作系统内核,本实验使用实验箱自带光盘中的zImage,是ARM-Linux的内核,版本号为2.6。根文件系统是Linux系统必不可少的一部分,用来管理下位机中的文件。本实验使用实验箱自带光盘中的root.cramfs。Cramfs是专门针对Flash设计的只读压缩的文件系统,其容量上限为256M,采用zlib压缩,文件系统类型可以是EXT2或EXT3,经常作为下位机的根文件系统。应用程序是需要烧写到下位机,在下位机中运行的程序,在上位机中以压缩文件包的形式保存,本实验使用实验箱自带光盘中的yaffs.tar.bz2。应用程序所的文件系统为Yaffs(Yet Another Flash File System),Yaffs是一种专门为Flash设计的嵌入式文件系统,运行速度快、占用内存小,提供写均衡、垃圾收集等底层功能。给下位机烧写软件系统的步骤:1烧写Vivi到下位机;2在上位机的Windows XP中配置超级终端,连接下位机;3烧写系统内核到下位机;4烧写根文件系统到下位机;5烧写应用程序到下位机。三、基本原理3、1 LED显示控制原理LED是发光二极管英文Light Emitting Diode的缩写格式,LED器件种类繁多,早期的LED产品是单个发光管,随着数字化设备的出现,适应了信息化社会发展的需要,成为了大众传媒的重要工具。 LED发光灯按类型可以分为单色发光灯、双色发光灯,三色发光灯、面发光灯、闪烁发光灯、电压型发光灯等;按发光强度可以分为普通亮度发光灯、高亮度发光灯、超高亮度发光灯等。 3、1、1 7段(8段)LED原理 LED的7个字段分别称为a、b、c、d、e、f、g,有时还有一个小数点段h,图1(a)所示。通过7个(或8个)发光段的不同组合,显示09和AF共16个字母数字,从而实现十六进制的显示。为使7段显示器显示数字或字符,就需点亮相应的段,每个段分别由数据线进行控制,通常数据线D0D7顺序控制ah段,如图11-34(b)所示,所需的控制信号称为段码。由于数字与段码之间没有规律性,因此必须进行数字与段码之间的转换以便显示数字。常用的转换方法是将要显示字形的段码列成一个表,称为段码表。显示时,根据字符查段码表,取出其对应的段码送到数据线上来控制显示。 图3.1 8段LED 显示器外形及各段对应的数据线LED有两种不同的形式: 一种是8个发光二极管的阳极都连在一起,称为共阳极,如图3.2(a)所示;另一种是8个发光二极管的阴极都连在一起,称为共阴极,如图3.2(b)所示。图3.2 8段LED 显示器原理图 3、1、2 点阵式LED原理点阵式LED的显示单元一般由8行8列LED组成,其外形及内部连接如图3所示,可以再由这8行8列的LED拼成更大的LED阵列。点阵式LED显示器能显示各种字符、汉字及图形、图像,并具有色彩。点阵式LED中,每个LED表示一个像素,通过每个LED的亮与灭来构造出所需的图形,各种字符及汉字也是通过图形方式来显示的。对于单色点阵式LED,每个像素需要1位二进制数表示,1表示亮,0表示灭。对于彩色点阵式LED,则每个像素需要更多的二进制位表示,通常需要一个字节。点阵式LED显示器的显示控制采用扫描方式,在数据存储器中开辟若干个存储单元作为显示缓冲区,缓冲区中存有所需显示图形的控制信息。显示时依次通过列信号驱动器输出一行所需所有列的信号,然后再驱动对应的行信号,控制该行显示。只要扫描速度适当,显示的图形就不会出现闪烁。图3.3 点阵式LED的外形和内部连接3、2 74HC273基本原理 74HC273是一款高速CMOS器件,74HC273引脚兼容低功耗肖特基TTL(LSTTL)系列。74HC273具有八路边沿触发,D 型触发器,带独立的D输入和Q输出。74HC273的公共时钟(CP)和主复位(MR)端可同时读取和复位(清零)所有触发器。每个D输入的状态将在时钟脉冲上升沿之前的一段就绪时间内被传输到触发器对应的输出(Qn)上。一旦MR输入电平为低,则所有输出将被强制置为低,而不依赖于时钟或者数据输入。74HC273适用于要求原码输出或者所有存储元件共用时钟和主复位的应用。74HC273的芯片形状以及引脚分布如图3.4所示: 图3.4 74HC273的芯片形状以及引脚分布图各个引脚的作用如下(参照图3.4说明):表1 74HC273芯片的引脚作用引脚符号引脚编号说明-MR1主复位输入(低复位)Qn2,5,6,9,12,15,16,19触发器输出nDn3,4,7,8,13,14,17,18数据输入nGND10地CP11时钟输入(上升沿触发)Vcc20电源电压3、3 74HC273在开发板上的连接 3、3、1 7段(8段)LED的连接 开发板上设置了2个数码管,由74HC273控制,如图4所示。74HC273是同步串行转并行的锁存器,在此通过SPI总线和CPU连接,锁存数据后驱动数码管发光。图3.5 开发板上7段LED的连接 3、3、2 点阵式LED的连接点阵式LED在开发板上的连接如图5所示。点阵式LED 驱动器逻辑中设置了8 个字节的缓冲区,每个字节按位对应点阵式LED 模块上的一列8个点。驱动器中的扫描电路会将缓冲区的内容不断输出到LED模块,CPU 可以读写此缓冲区,从而可以更新现实内容。 上面一副图的最左边接的是下面图的最右边。图3.6 开发板上点阵式LED的连接点阵LED寄存器组共8个字节寄存器,地址A4A3A2A1=从0000 到0111,按地址递增顺序分别对应点阵LED模块从左到右的8个列。每个字节寄存器对应一列,字节寄存器内8 个位对应该列的8 个LED,从Bit0 到Bit7 分别对应从上到下的LED,如图3.7所示。图3.7 点阵式LED寄存器组3、4 LED 编程本次实验中,利用 LED驱动程序“s3c2410-led.o”提供的函数控制LED显示。可在相同目录下找到其源程序“s3c2410-led.c”进行分析。 3、4、1 7段LED的段码表由于开发板上两个数码管的连接是共阳极,分别显示“十位”和“个位”数字,中间是一个点号,总是让它置“1”。所以当想要其中之一显示为“0”时,那么其对应的段码应为“11000000”,转化为十六进制即为0xc0。同理可以给出“1”“9”的段码,从而形成如下段码表:unsigned char LEDCODE10=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;注意:前10个表示字符“0”“9”的段码,最后一个表示各段全灭,不显示。用户程序使用ioctl函数用来控制2个数码管的显示: ioctl(fd,0x12,LEDWORD);由于两个8字数码管需要同时显示,故需要将“十位”的段码左移8位,拼接上“个位”的段码,形成一个16位的LEDWORD。3、4、2 点阵式LED的显示缓冲区点阵式LED 驱动器逻辑中设置了8 个字节的缓冲区,每个字节按位对应点阵式LED 模块上的一列8个点。如要显示字符或图形,需要先给出对应点阵数据存储在缓冲区才能显示。图7所示的是字符“0”和心形图的点阵,参照图6分别给出各自8个字节中的数据为: “0”: 0x00,0x00,0x7c,0x82,0x82,0x82,0x7c,0x00 心形图: 0x00,0x0c,0x12,0x22,0x44,0x22,0x12,0x0c通过调用write函数控制点阵式LED显示对应字符或图形。图3.8 字符“0”和心形图的点阵 3、4、3 C语言编程 利用嵌入式实验平台和LED的工作原理,进行C语言编程,在本设计中的C语言编程见附录。四、实验环境连接1 、建立工作目录 rootzxt smile# mkdir hello rootzxt smile# cd hello2、编写程序源代码用下面的命令来编写 hello.c 的源代码,进入 hello 目录使用 vi 命令来编辑代码: rootzxt hello# vi hello.c按“i ” 或者“a ” 进入编辑模式,将上面的代码录入进去,完成后按 Esc 键进入命令状态,再用命令“:wq” 保存并退出。这样我们便在当前目录下建立了一个名为 hello.c 的文件。进入/arm2410cl/exp/basic/10_led 目录,使用 vi 编辑器或其他编辑器阅读理解源代码 3、编译应用程序运行 make 产生 test_led 可执行文件 test_led.o4、 编写Makefile在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返回值可以当做变量来使用。makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,VisualC+的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。Makefile文件编写的规则:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。 2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。 3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。5、编译应用程序在 hello 目录下运行“make” 来编译我们的程序了。如果进行了修改,重新编译则运行:rootzxt hello# make cleanrootzxt hello# make6、下载调试在宿主 PC 计算机上启动 NFS 服务,并设置好共享的目录,在建立好 NFS 共享目录以后,我们就可以进入 MINICOM 中建立开发板与宿主 PC 机之间的通讯了。(1)服务器设置,输入命令”setup”分别进行对系统服务及防火墙配置。 图4.1 服务器配置(2) 为宿主PC机配置了NFS服务NFS(Network File System)指网络文件系统,它实现了文件在不同的系统间使用。当我们想用远端档案时,只需调用“mount”就可以远端系统挂接在自己的档案系统之下。每次重启宿主PC机时,先输入命令”service portmap restart”和”service nfs restart”,以启动nfs服务。(3)启动vi编辑器查看网段输入命令”Vi /etc/exports”查看网段为”192.168.0.*”,按键”ESC”,输入”: wq”存盘退出。(4)重新启动NFS服务,再输入”ifconfig eth0 192.168.0.105”完成主机IP地址设置。图4.2 NFS服务器配置(5)进入共享文件”cd /root/share/exp/basic/10_led”,输入”ls”查看10_led下的两个.c文件。依次输入”make clean”,”make”生成两个.o文件。转入超级终端硬件连接:连接宿主机和UP-TECH S2410/P270 DVP 嵌入式实验平台。打开宿主PC 机电源,进入 Linux操作系统。7、配置超级终端(1)建立超级终端:运行Windows系统下(以WindowsXP为例)开始所有程序附件通讯超级终端(HyperTerminal)。(2)新建一个通信终端。如果要求输入区号、电话号码等信息请随意输入,出现如图所示对话框时,为所建超级终端取名为arm,可以为其选一个图标。单击“确定”按钮图4.3 新建超级终端(3) 在接下来的对话框中选择ARM开发平台实际连接的PC机串口(如COM1),按确定后出现如图所示的属性对话框,设置通信的格式和协议。这里波特率为115200,数据位8,无奇偶校验,停止位1,无数据流控制。按确定完成设置。完成新建超级终端的设置以后,可以选择超级终端文件菜单中的另存为,把设置好的超级终端保存在桌面上,以备后用。用串口线将PC机串口和平台UART0正确连接后,就可以在超级终端上看到程序输出的信息了。图4.4 超级终端端口设置(4) 启动实验平台 ::打开电源开关,系统会由VIVI开始引导。正常启动时会显示启动信息到“Press Return to start the LINUX now, any other key for vivi”,按除回车键外的其它键则进入vivi控制台。弹出如下对话框: 图4.5 启动超级终端平台 图4.6 超级终端命令输入(5)依次输入”ping 192.168.0.105”和”ping 192.168.0.121”查看是否连通,若成功连接,按”Ctrl+C”结束,在进行挂载后,查找根目录下的文件”cd /host/exp/basic/10_led”,通过“ls”查看文件,然后使用“insmod s3c2410-led.o ”命令完成将一个可动态加载的模块加载到内核中。输入” lsmod” 显示当前内核加载的模块,输入命令”./test_led”进行程序测试。显示如下对话框:图4.7 下位机程序调试运行五、程序分析重要代码片断分析如下:unsigned charLEDCODE10=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;/这个是10个数字的编码在这里主要是用到编码的过程 假设a是8字型数码管的最上一横,以顺时针以次列出b,c,d,e,f.中间那一横为g,如果要显示为0的话,由于在开发板中的连接是共阳极(请参考我们的电路图),所以只需要满足a,b,c,d,e,f为0即可,而g为1,因为两个数码管的中间是个点号,我们用h表示,并且总是让它置为1。因为我们在开发板的连接上可以看到a对应d0,b对应d1,.h对应d7,所以当想显示为0的时候,那么应该是11000000。转化成为16进制的数据,也就成了0Xc0.对应我们在LEDCODE【10】数组中的第一位。其他的每一位值,大家可以根据上面的方法依次类推。在for循环中我们写了如下语句。LEDWORD=(LEDCODEi8)|LEDCODE9-i; 那是因为LEDWORD是一个16位的数。我们是需要将两个8字数码管同时显示,所以将LEDCODEi左移8位,然后再加上个位使得十位和个位同时显示。 至于显示点阵数码管还是显示8字数码管,主要是通过IOCTL函数中的命令来实现的,也就是在代码中出现的ioctl(fd,0x12,LEDWORD); ioctl(fd,0x11,LEDWORD); 下面分析这个IOCTL函数的原型static int s3c2410_led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg) /printk(DOT buffer is %xn ,arg ); switch(cmd) case LED_TUBE_IOCTRL:/如果是0x11命令,那么点亮8字数码管return *(volatile unsigned short *)s3c2410_led_tube_base=arg; case LED_DIG_IOCTRL:/如果是0x12命令 ,那么点亮点阵数码管return *(volatile unsigned short *)s3c2410_led_dig_base=arg; default : return printk(your command is not exist); return 0; 其中宏定义#define LED_TUBE_IOCTRL 0x11#define LED_DIG_IOCTRL 0x12 由于在s3c2410_led_init函数中s3c2410_led_tube_base = (unsigned int) ioremap(LED_TUBE_PHY_START, 0x01);/IO映射s3c2410_led_dig_base = (unsigned int) ioremap(LED_DIG_PHY_START, 0x01);/将物理地址转换成为虚拟地址 由于我们操作的是虚拟地址,而不是物理地址,所以需要将物理地址转换成为物理地址。物理地址在开发板的电路图中有表明很清楚。在驱动中我们也有定义#define LED_TUBE_PHY_START 0x08000100 #define LED_DIG_PHY_START 0x08000102 所以上面IOCTL函数的功能就是当下达不同的命令时,也就是让不同的数码管显示其信息。应用程序中我们还用到了一些延迟的函数 ,如jmdelay(1000); 等。主要是给一些停顿,让人的视觉能够清晰的识别数码管中的数字。六、 实验步骤1、阅读理解源码 进入/arm2410cl/exp/basic/10_led 目录,使用 vi 编辑器或其他编辑器阅读理解源代码。 2、编译应用程序 运行 make 产生 test_led 可执行文件 test_ledrootBC exp/basic# cd 10_led rootBC 10_led# make armv4l-unknown-linux-gcc -c -I. -Wall -O -D_KERNEL_ -DMODULE -I/home/kernel/linux-2.4.18-2410cl/include s3c2410-led.c -o s3c2410-led.o armv4l-unknown-linux-gcc -I. -Wall -O -D_KERNEL_ -DMODULE -I/home/kernel/linux-2.4.18-2410cl/include -c -o test_led.o test_led.c rootBC 2410-Classics LED# ls Makefile readme s3c2410-led.c s3c2410-led.o test_led test_led.c test_led.o3、下载调试 切换到 minicom 终端窗口,使用 NFS mount 开发主机的/arm2410cl 到/host 目录,然后进入 /host/exp/basic/10_led 目录,用 insmod s3c2410-led.o 命令插入 led 驱动,并用 lsmod命令查看是否已经插入。/mnt/yaffsmount -t nfs -o nolock 192.168.0.189:/arm2410cl /host /host/exp/basiccd 10_led/ /host/exp/10_ledls Makefile readme s3c2410-led.c s3c2410-led.o test_led test_led.c test_led.o /host/exp/10_ledinsmod s3c2410-led.o Using s3c2410-led.o 0-numeric tube : Dprintk device open s3c2410-hc273 initializedUsing exio.o /host/exp/10_ledlsmod Module Size Used by Tainted: P s3c2410-led 2048 0 (unused) /host/exp/10_led./test_led 即可以看到8字数码管和点阵数码管工作。七、结果分析 在下位机的minicon窗口执行“./test_led ”命令,点阵式LED和8段LED显示结果。点阵式LED驱动器逻辑中设置了8个字节的缓冲区,每个字节按位对应点阵式LED模块上的一列8个点。如要显示字符或图形,需要先给出对应点阵数据存储在缓冲区才能显示。实验结果共产生八个图案“Q”“I”“N”“喜”“怒”“哀”“乐”“心”,点阵数码管8*8,矩阵0x3c,0x42,0xa5,0x99,0x99,0xa5,0x42,0x3c,0,0第i个数代表数码管第i列,依次将十六进制转化为二进制数,其中“1”表示亮,“0”表示暗。例如“0x3c”转化为二进制为“00111100”,表示第九、十列从下至上依次为暗暗亮亮亮亮暗暗;“0x42”转化为二进制为“01000010”,表示第九、十列从下至上依次为暗亮暗暗暗暗亮暗;“0xa5”转化为二进制为“10100101”,表示第九、十列从下至上依次为亮暗亮暗暗亮暗亮;“0x99”转化为二进制为“10011001”,表示第九、十列从下至上依次为亮暗暗亮亮暗暗亮。其图案为“哀”。其他图案原理也相同。通过调用write函数控制点阵式LED显示对应字符或图形。LEDCODE10=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;前10个表示字符“0”-“9”的段码,最后一个表示各段全灭,不显示。用户程序使用ioctl函数用来控制两个数码管的显示:icotl(fd,0x12,LEDWORD);由于两个数码管需要同时显示,故需要将“十位”的段码左移8位,拼接“个位”的段码,形成一个16位的LEDWORD。 点阵数码管上依次显示的结果如下图所示: a. Q b. I c. N d. 喜 e. 怒 f. 哀 g. 乐 h. 心八、总结 在这次课程设计,可以说是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识。而且学到了许多在书本上所没有学到过的知识。在设计的过程中遇到问题,可以说是困难重重,这毕竟是第一次做的,难免会遇到各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解的不够深刻,掌握的不够牢固,通过这次课程设计,让我学到了以下几点,每次动手前一定要多查询资料,做到谋而后动这可以减少实践过程中的无用功。而且做事一定要认真,否则一点小小的错误都会让整个程序错误。在该次课程设计的初期,我们将任务分配好,每个人各就其职,各尽所能。当然,在一开始我们就遇到了一些问题,解决问题的方法是跑到图书馆查看有关书籍,或上网查阅有关信息,或请教老师。终于在大家的相互帮组和大家的齐心协力下,我们最终完成了该次的课程设计。 通过这次课程设计不仅考察了我们对课堂上所学专业知识的理解程度,也锻炼了我们的动手能力。提高了我们独立思考文理,解决问题的能力。总体上看,我觉得这次课程设计是我自身的知识丰富了不少,但同时也发现了自己的不足之处。例如在动手方面,和知识融合方面,不能与实践相结合。软件操作不够熟练,不能灵活运用。是我了解要先学好理论知识才能很好地与实践相结合,才能熟练地运用到生活中。通过本次课程设计,使我们详细的了解了LED的发光原理,和LED的显示原理,对嵌入式开发及虚拟机的安装使用有了更深刻的理解。九、参考文献【1】赵宏、王小牛、任学慧. 嵌入式应用教程. 人民邮电出版社【2】杨刚.嵌入式基础实践教程. 北京大学出版社【3】杜春雷. ARM体系与编程. 清华大学出版社【4】覃团发、姚海涛、覃远年、陈海强. 移动通信. 重庆大学出版社【5】王宜怀、刘晓升. 嵌入式技术基础与实践. 清华大学出版社【6】博创公司. 2410经典实验指导书3.2. 北京博创兴业科技有限公司【7】博创公司. 270经典实验指导书1.1. 北京博创兴业科技有限公司 【8】张石. 嵌入式系统技术教程. 人民邮电出版社【9】 2009.2.1.【10】http:/en.wikipedia.org/wiki/ARM_architecture, 2009.7.4.附录S3c2410-led.c#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* debug macros */#undef DEBUG#define DEBUG#ifdef DEBUG#define DPRINTK( x. )printk(s3c2410-led: x)#else#define DPRINTK( x. )#endif#define DEVICE_NAME s3c2410 led#define LED_TUBE_PHY_START 0x08000110#define LED_DIG_PHY_START 0x08000100#define LED_TUBE_IOCTRL 0x11#define LED_DIG_IOCTRL 0x12static int ledMajor = 0;#define LED_MINOR 1#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_led_dir,devfs_led;#endifstatic u32 s3c2410_led_tube_addr = IDE_BASE + 0x100;static u32 s3c2410_led_dig_vaddr = IDE_BASE + 0x110;static int s3c2410_led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg)/printk(DOT buffer is %xn ,arg8 ); switch(cmd) case LED_DIG_IOCTRL: return *(volatile unsigned long *)s3c2410_led_dig_vaddr=(arg8) | arg 16; ; default : return printk(your command is not exist); return 0;static ssize_t s3c2410_led_write(struct file *filp, const char *buf, size_t count, loff_t * f_pos)int i;unsigned char mdata16;if (copy_from_user(mdata,buf,10) return -EFAULT;for (i=0;i8;i+)/printk(:%d ,mdatai);/*(volatile unsigned char *)(s3c2410_led_tube_addr+i)=0xff;*(volatile unsigned char *)(s3c2410_led_tube_addr+i*2)=mdatai;/printk(:%x ,*(volatile unsigned short *)(s3c2410_led_tube_addr+i);/printk(n); return 0;static int s3c2410_led_open(struct inode *inode, struct file *filp) MOD_INC_USE_COUNT; printk(led device open sucess!n); return 0;static int s3c2410_led_release(struct inode *inode, struct file *filp) MOD_DEC_USE_COUNT; printk(led device releasen); return 0;static struct file_operations s3c2410_led_fops = owner:THIS_MODULE, open:s3c2410_led_open, ioctl:s3c2410_led_ioctl, write:s3c2410_led_write, release:s3c2410_led_release,;int _init s3c2410_led_init(void) int ret;BWSCON = (BWSCON & (BWSCON_ST1 | BWSCON_WS1 | BWSCON_DW1) | (BWSCON_ST1 | BWSCON_DW(1, BWSCON_DW_16);BANKCON1= BANKCON_Tacs4 | BANKCON_Tcos4 | BANKCON_Tacc14 |BANKCON_Toch4 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC1;GPACON|=(112); ret = register_chrdev(0, DEVICE_NAME, &s3c2410_led_fops); if (ret 0) DPRINTK(DEVICE_NAME cant get major numbern); return ret; #ifdef CONFIG_DEVFS_FS devfs_led_dir = devfs_mk_dir(NULL, led, NULL); devfs_led = devfs_register(devfs_led_dir, 0raw, DEVFS_FL_DEFAULT, ledMajor,LED_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_led_fops, NULL);#endif DPRINTK (DEVICE_NAMEtdevice initializedn); return 0; void _exit s3c2410_led_exit(void)#ifdef CONFIG_DEVFS_FSdevfs_unregister(devfs_led);devfs_unregister(devfs_led_dir);#endifunregister_chrdev(ledMajor, DEVICE_NAME);module_init(s3c2410_led_init);module_exit(s3c2410_led_exit);test-led.c#include #include #include #include #include #include /#include #define TUBE_IOCTROL 0x11#define DOT_IOCTROL 0x12void jmdelay(int n) int i,j,k; for (i=0;in;i+) for (j=0;j100;j+) for (k=0;k500;k+);int main() int fd; int i,j,k; unsigned int LEDWORD; unsigned int MLEDA8; unsigned char LEDCODE10=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;unsigned char dd_data1610=0x00,0x3c,0x42,0x52,0x62,0x3c,0x20,0x00,0,0,0x00,0x3c,0x42,0x52,0x62,0x3c,0x20,0x00,0,0, 0x00,0x00,0x42,0x7e,0x42,0x00,0x00,0x00,0,0, 0x00,0x00,0x42,0x7e,0x42,0x00,0x00,0x00,0,0, 0x00,0x7e,0x04,0x08,0x10,0x40,0x7e,0x00,0,0, 0x00,0x7e,0x04,0x08,0x10,0x40,0x7e,0x00,0,0, 0x3c,0x46,0x93,0xa5,0xa5,0x93,0x46,0x3c,0,0, 0x3c,0x46,0x93,0xa5,0xa5,0x93,0x46,0x3c,0,0, 0x3c,0x42,0xa5,0x99,0x99,0xa5,0x42,0x3c,0,0, 0x3c,0x42,0xa5,0x99,0x99,0xa5,0x42,0x3c,0,0, 0x3c,0x46,0xa5,0xb1,0xa5,0x85,0x42,0x3c,0,0, 0x3c,0x46,0xa5,0xb1,0xa5,0x85,0x42,0x3c,0,0, 0x3c,0x4a,0xad,0xe9,0xe9,0xad,0x4a,0x3c,0,0, 0x3c,0x4a,0xad,0xe9,0xe9,0xad,0x4a,0x3c,0,0, 0x1c,0x3e,0x7e,0xfc,0x7e,0x3e,0x1c,0x00,0,0, 0x1c,0x3e,0x7e,0xfc,0x7e,0x3e,0x1c,0x00,0,0, ; fd=open(/dev/led/0raw,O_RDWR); if (fd 0) printf(#Led device open fail#n); return (-1); LEDWORD=0xff00; printf(will enter TUBE LED ,please waiting . n); LEDWORD=0xff00; ioctl(fd,0x12,LEDWORD); sleep(1); for (j=0;j2;j+) for (i=0;i10;i+) LEDWORD=(LEDCODEi8)|LEDCODE9-i; ioctl(fd,0x12,LEDWORD); jmdelay(1500); printf(will enter DIG LED ,please waiting . n); sleep(1); for (i=0;i16;i+) write(fd,dd_datai,10);jmdelay(1000); while(1)unsigned char a10; for (i=0;i10;i+)ai = rand() % 255;write(fd,a,10);jmdelay(500); close(fd);return 0;24
展开阅读全文