嵌入式系统原理与设计实验报告_第1页
嵌入式系统原理与设计实验报告_第2页
嵌入式系统原理与设计实验报告_第3页
嵌入式系统原理与设计实验报告_第4页
嵌入式系统原理与设计实验报告_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌 入 式 系 统 实 验 报 告指导教师: 学科专业: 班 级: 学 号: 姓 名: 2014年6月前 言从20世纪七十年代单片机的出现到各式各样的嵌入式微处理器,微控制器的大规模应用,嵌入式系统已经有了近30年的发展历史,并在全世界各行业得到广泛应用。嵌入式系统产品的研制和应用已经成为我国信息化带动工业化、工业化促进信息化发展的新的国民经济增长点。经过几十年的发展,嵌入式系统已经在很大程度改变了人们的生活、工作和娱乐方式,而且这些改变还在加速。嵌入式系统具有无数的种类,每类都具有自己独特的个性。例如,MP3、数码相机与打印机就有很大的不同。汽车中更是具有多个嵌入式系统,使汽车更轻快、更干净、更容易驾驶,机顶盒、高清电视、游戏机、智能玩具、交换机、路由器、数控设备或仪表、汽车电子、家电控制系统、医疗仪器、航天航空设备等等,都是典型的嵌入式系统。事实上,几乎所有带有一点“智能”的家电(全自动洗衣机、电脑电饭煲)都是嵌入式系统。嵌入式系统广泛的适应能力和多样性,使得视听、工作场所甚至健身设备中到处都有嵌入式系统。高端的嵌入式系统和工业软件的发展, 实际上与我们对该行业最先进的科学技术前沿的掌握有关,换言之,与我国该行业的科学技术水平有关。学习和研究嵌入式系统,具有重大意义。这学期的嵌入式系统的学习过程中我们在2410RP这一实验开发平台上进行了诸多嵌入式的基础实验。在本报告中,将把其中两个具有代表性的实验的原理、内容、结果以及驱动和测试程序写出来。目 录实验一 数码管显示11.1 实验目的11.2 实验内容11.3 实验原理11.3.1 LED的发光原理11.3.2 八段LED显示器11.3.3 芯片zlg7289A的介绍21.3.4 数码管的连接电路31.4 实验步骤31.5 实验源代码解释与说明41.6 总结11实验二 LED点阵驱动实验122.1 实验目的122.2 实验内容122.3 实验原理122.3.1 8X8点阵数码管发光原理122.3.2 数码管的连接电路122.3.3 I/O接口132.4 实验步骤132.5 实验源代码解释与说明142.6 实验结果192.7 总结19实验一 数码管显示1.1 实验目的学习串并转换的相关知识,并编写驱动程序。1.2 实验内容1) 了解数码管显示的工作原理;2) 掌握数码管驱动的编写及测试过程;3) 对zlg7289A的驱动程序进行编写;4) 驱动数码管并显示个人学号。1.3 实验原理1.3.1 LED的发光原理LED(Light Emitting Diode),即发光二极管。是一种半导体固体发光器件。它是利用固体半导体置于一个有引线的架子上,然后四周用环氧树脂密封,起到保护内部芯线的作用,所以LED的抗震性能好。发光二极管的核心部分是由p型半导体和n 型半导体组成的晶片,如图所示,在p型半导体和n型半导体之间有一个过渡层,称为p-n结。在某些半导体材料的PN结中,注入的少数载流子与多数载流子复合时会把多余的能量以光的形式释放出来,从而把电能直接转换为光能。PN结加反向电压,少数载流子难以注入,故不发光。这种利用注入式电致发光原理制作的二极管叫发光二极管,通称LED。当它处于正向工作状态时(即两端加上正向电压),电流从LED阳极流向阴极时,半导体晶体就发出从紫外到红外不同颜色的光线,光的强弱与电流有关。图1-1 LED发光原理图1.3.2 八段LED显示器八段LED显示器由8个发光二极管组成,如图1-2、图1-3所示。基中7个长条形的发光管排列成“日”字形,另一个贺点形的发光管在显示器的右下角作为显示小数点用,它能显示各种数字及部份英文字母。LED显示器有两种不同的形式:一种是8个发光二极管的阳极都连在一起的,称之为共阳极LED显示器;另一种是8个发光二极管的阴极都连在一起的,称之为共阴极LED 显示器。共阴和共阳结构的LED显示器各笔划段名和安排位置是相同的。当二极管导通时,相应的笔划段发亮,由发亮的笔划段组合而显示的各种字符。8个笔划段hgfedcba 对应于一个字节(8位)的D7 D6 D5 D4 D3 D2 D1 D0,于是用8位二进制码就可以表示欲显示字符的字形代码。例如,对于共阴LED显示器,当共阴极接地(为零电平),而阳极hgfedcba各段为0111011时,显示器显示P字符,即对于共阴极LED 显示器,“P”字符的字形码是73H。如果是共阳LED显示器,共阳极接高电平,显示“P”字符的字形代码应为10001100(8CH)。这里必须注意的是:很多产品为方便接线,常不按规则的方法去对应字段与位的关系,这时字形码就必须根据接线来自行设计了。图1-2 LED数码管组成图图1-3 LED数码管原理图1.3.3 芯片zlg7289A的介绍zlg7289A是一片具有串行接口的可同时驱动8位共阴式数码管或64只独立LED的智能显示驱动芯片该芯片同时还可连接多达64 键的键盘矩阵单片即可完成LED显示键盘接口的全部功能。zlg7289A内部含有译码器可直接接受BCD码或16进制码并同时具有2 种译码方式参看后文此外还具有多种控制指令如消隐闪烁左移右移段寻址等zlg7289A具有片选信号可方便地实现多于8位的显示或多于64键的键盘接口。芯片zlg7289A的典型应用:仪器仪表、工业控制器、条形显示器、控制面板。芯片zlg7289A的特点:1)串行接口无需外围元件可直接驱动LED; 2)各位独立控制译码/不译码及消隐和闪烁属性;3))循环左移/ 循环右移指令;4)具有段寻址指令方便控制独立LED; 5)64键键盘控制器内含去抖动电路。1.3.4 数码管的连接电路图1-4 数码管连接电路1.4 实验步骤1) 连接号宿主PC机与一台S3C2410-RP目标板;2) 编写数码管驱动程序spi_led.c文件;3) 启动系统终端设置S3C2410-RP目标板的地址;4) 将宿主PC机的根目录挂载到S3C2410-RP目标板的mnt目录下;5) 加载驱动程序;6) 执行并测试程序。1.5 实验源代码解释与说明A. 头文件keypad.h#ifndef _KEYPAD_H_#define _KEYPAD_H_/Keypad 扫描码#define KEYPADNUMLK 0x33#define KEYPADDIV 0x34#define KEYPADMUL 0x35#define KEYPADSUB 0x3d#define KEYPADADD 0x2e#define KEYPADENTER 0x1e#define KEYPADDOT 0x15/DEL#define KEYPAD0 0x14/INS#define KEYPAD1 0x1b/END#define KEYPAD2 0x1c/DOWN#define KEYPAD3 0x1d/PDN#define KEYPAD4 0x23/LEFT#define KEYPAD5 0x24#define KEYPAD6 0x25/RIGHT#define KEYPAD7 0x2b/HOME#define KEYPAD8 0x2c/UP#define KEYPAD9 0x2d/PUP#endif 头文件定义了嵌入式开发板上输入键盘各个按键的逻辑地址。B. 驱动程序源文件spi_led.c#include /config.h内核配置头文件#include /kernel.h定义了经常用到的函数原型及宏定义#include /module.h定义了内核模块相关的函数、变量及宏#include /sched.h为调度程序头文件,定义了任务结构#include /interrupt.h中包含了与操作系统中断相关的大部分宏及struct结构的定义#include #include /init.h中定义了驱动的初始化和退出相关的函数#include #include #include /version.h里定义了Linux内核的版本,用于版本检查#include /I/O头文件,定义对I/O端口操作的函数#include #include /访问系统硬件的头文件/-#include #include /自旋锁,防止多处理器并发#include #include #include #include #include #include #include #include /miscdevice结构体成员变量设备#include #include #include #include #include #include #include #include /包含copy_to_user、copy_from_user等内核访问用户进程内存地址的函数定义#include /系统头文件,定义了设置或修改描述符/中断门等的嵌入式汇编宏/-#define HR_DEBUG 1/-#define IRQ_spi_led_INT IRQ_EINT4#define GPIO_SimpleINT_EINT4 (GPIO_MODE_ALT0 | GPIO_PULLUP_EN | GPIO_F4)#define ONEBIT 0x1#define KEYPADCSDIS (GPGDAT |=(ONEBIT 3)#define KEYPADCSEN (GPGDAT &=(ONEBIT 3)#define KEYPADDIRMO (GPBDAT &=(ONEBIT 0)#define KEYPADDIRMI (GPBDAT |=(ONEBIT 0)#define spi_led_MAJOR 104 /定义led_ary_MAJOR设备的主设备号devfs_handle_t spi_led_handle; /系统支持devfs的数据结构int spi_led_temp_count=0; /定义的系统全局变量,防止文件被多重打开static int DELAY_TIME=100; /时间延迟为100int putcToKBCTL(u8 c) u32 i; KEYPADCSEN; KEYPADDIRMO; udelay(60); while(SPSTA1 & ONEBIT)=0); / wait while busy SPTDAT1 = c; / write left justified data while(SPSTA1 & ONEBIT)=0); / wait while busy KEYPADCSDIS; i = SPRDAT1; return(i); /功能概要:将所给数据写入指定的寄存器中int spi_ledInit() int t; char dummy = (char)0xff; printk(GPGCON=%xn,GPGCON); GPGCON &= (0x36)|(0x310)|(0x312)|(0x314); GPGCON |= (0x16)|(0x310)|(0x312)|(0x37289 GPBCON &= (0x3 0); / 清除GPB0端口数据 GPBCON |= (ONEBIT 0); /设置端口GPB0用于_PWR_OK信号输出 / rGPDDAT &=(ONEBIT 0); / 将 _PWR_OK t置 0 KEYPADDIRMO; /设置SPI(串行外设接口)寄存器 / 中断模式,可用分频,主模式,高电平时钟,形式B,正常模式 /rSPCON1=(ONEBIT5)|(ONEBIT4)|(ONEBIT3)|(0x02)|(ONEBIT1);/ 查询模式,可用分频,主模式,高电平时钟,形式A,正常模式 SPCON1 = (05)|(ONEBIT4)|(ONEBIT3)|(0x02)|(01);/* 开发者必须根据PCLK时钟的变化正确地调节分频器的值*/SPPRE1 = 255; /* 99.121K = 203M/4/2/(255+1) PCLK=50.75Mhz FCLK=203Mhz SPICLK=99.121Khz*/ putcToKBCTL(0xbf); /传送初始化指令 printk(Key Pad Init complete:n); /显示键盘初始化成功putcToKBCTL(0xc8); /第一个数码管的地址为0xc8putcToKBCTL(0x01); /设置第一个数码管显示的数值为1 KEYPADCSDIS;putcToKBCTL(0xc9); /第二个数码管的地址为0xc9putcToKBCTL(0x02); /设置第二个数码管显示的数值为2 KEYPADCSDIS;putcToKBCTL(0xca); /第三个数码管的地址为0xcaputcToKBCTL(0x09); /设置第三个数码管显示的数值为9 KEYPADCSDIS;putcToKBCTL(0xcb); /第三个数码管的地址为0xcbputcToKBCTL(0x00); /设置第三个数码管显示的数值为0KEYPADCSDIS; return(1); /函数实现LED数码管的初始化,返回值为1时,则完成系统初始化u8 readKBValue(void) unsigned char i; KEYPADCSEN; KEYPADDIRMO; udelay(60); while(SPSTA1 & ONEBIT)=0); / wait while busy SPTDAT1 = 0x15; / 传送读取键值的命令 while(SPSTA1 & ONEBIT)=0); / wait while busy udelay(30);/delay 30us KEYPADDIRMI; SPTDAT1 = 0xff; / 传送读取键值的命令 while(SPSTA1 & ONEBIT)=0); / wait while busy i = SPRDAT1; /printk(%xn,i); KEYPADCSDIS; KEYPADDIRMO; return(i); /函数实现的主要功能为读取键盘输入的值。ssize_t spi_led_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)return count;/函数返回:读取数据的长度count。/功能概要:对字符性设备进行读操作/*= SimpleD Write =*/ssize_t spi_led_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)printk(s3c2410: device file-write operation!n);return count;/函数返回:写入数据的长度count。/功能概要:对字符性设备进行写入操作/*= SimpleD Ioctl =*/ssize_t spi_led_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data)printk(s3c2410: device ioctl operation!n); /函数可重新定义用来I/O口的其他控制操作/*= SimpleD device open =*/ ssize_t spi_led_open (struct inode * inode ,struct file * file)return 0; /当用户态调用函数时,对应内核态次函数被调用/*= SimpleD device close =*/ssize_t spi_led_release (struct inode * inode ,struct file * file)return 0;/定义内核态release函数,当用户态调用close函数时,release函数被调用struct file_operations spi_led_ops =open:spi_led_open,read:spi_led_read,write:spi_led_write,ioctl:spi_led_ioctl,release:spi_led_release,;/结构体file_operations在头文件 linux/fs.h中定义,用来存储驱动内核模块提供的对设备进行各种操作的函数的指针static void IRQ_spi_led_interrupt(int nr, void *devid, struct pt_regs *regs) u8 ui8ScanCode; ui8ScanCode=readKBValue();/HR_del_pre_scancode(ui8ScanCode); /定义静态函数IRQ_spi_led_interrupt,请求中断static int _init HW_spi_led_init(void) int ret = -ENODEV; int delay ; set_external_irq(IRQ_spi_led_INT,EXT_FALLING_EDGE, GPIO_PULLUP_EN); set_gpio_ctrl(GPIO_SimpleINT_EINT4);ret = request_irq(IRQ_spi_led_INT, IRQ_spi_led_interrupt, SA_INTERRUPT, spi_led, NULL);if (ret) printk(KERN_INFO request SimpleINT IRQ failed (%d)n, IRQ_spi_led_INT); return ret; ret = devfs_register_chrdev(spi_led_MAJOR, spi_led, &spi_led_ops); if( ret 0 )printk ( s3c2410: init_module failed with %dn, ret);return ret;elseprintk(KERN_INFO S3c2410 spi_led register success!n);spi_led_handle = devfs_register( NULL, spi_led, DEVFS_FL_DEFAULT, spi_led_MAJOR, 0, S_IFCHR, &spi_led_ops, NULL);/-spi_ledInit();/- return ret; /用于驱动程序进行硬件设备初始化int _init s3c2410_spi_led_init(void) int ret = -ENODEV; ret = HW_spi_led_init(); if (ret) return ret; return 0; /模块初始化,程序由此开始执行,此函数被module_init()调用int init_module()s3c2410_spi_led_init(); /此函数在insmod加载此模块驱动的时候自动调用。负责进行设备驱动程序初始化工作.init_module 返回0以表示初始化成功。返回负数表示失败。void cleanup_module() devfs_unregister_chrdev( spi_led_MAJOR, spi_led ); devfs_unregister( spi_led_handle ); free_irq(IRQ_spi_led_INT, NULL); / 此函数在卸载此模块驱动时调用。负责进行设备驱动程序的清除工作1.6 总结 通过本次实验,我学习到一些Linux系统常用的操作命令,了解了LED数码管工作的原理。同时,对嵌入式系统有了更明确的了解与认识。通过实验中的实际操作,也体验了基于嵌入式开发的基本流程。在老师的指导下,完成了对LED数码管的显示控制,显示得到了自己学号的后四位1290。实验二 LED点阵驱动实验2.1 实验目的编写一个针对总线操作的硬件驱动程序。2.2 实验内容1) 了解LED点阵显数码管示的工作原理;2) 掌握LED点阵驱动的编写及测试;3) 编写一个针对硬件LED点阵的驱动程序并测试;4) 驱动LED点阵并显示个人姓名。2.3 实验原理2.3.1 8X8点阵数码管发光原理从图2-1中可以看出来,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一列置1电平,某一行置0电平,则相应的二极管就亮;因此要实现一根柱形的亮法,如图2-1所示,对应的一列为一根竖柱,或者对应的一列为一根横柱,因此实现柱形的亮法如下所述:图2-1 LED点阵等效电路图2.3.2 数码管的连接电路 系统电路如图2-2所示。显示部分用的是一个8X8发光二极管点阵,我们常见的用于发布消息、显示汉字的点阵式LED显示屏通常由若干块LED点阵显示模块组成,8X8显示点阵模块,每块有64个独立的发光二极管,为了减少引脚且便于封装,各种LED显示点阵模块都采用阵列形式排布,即在行列线的交点处接有显示LED。(因此,LED 点阵显示模块的显示驱动只能采用动态驱动方式,每次最多只能点亮一行LED(共阳形式LED显示点阵模块)或一列 LED(共阴形式LED显示点阵模块)。如图2-2所示的显示驱动原理图中,点阵为共阴,由总线锁存芯片74573为点阵显示模块提供列驱动电流,8个行信号则由集电极开路门驱动器7407控制,行线和列线都挂在总线上,微处理器可以通过总线操作来完成对每一个LED点阵显示模块内每个LED显示点的亮、暗控制。图2-2 LED点阵硬件连接电路2.3.3 I/O接口在本开发板上,整个LED显示模块是作为一个I/O进行控制的。如电路原理图2-2所示,DATA0.7、DATA8.15分别对应系统数据线的低16位,LED_LOCK信号是由系统总线的写信号和地址信号经简单的逻辑组合而得,在板载的CPLD内完成,控制该显示模块的I/O地址为0x08000000。2.4 实验步骤1) 连接号宿主PC机与一台S3C2410-RP目标板;2) 编写LED点阵驱动程序;3) 编写LED点阵显示测试程序test.c,并编译;4) 启动Linux系统终端并设置S3C2410-RP目标板的地址;5) 将宿主PC机的根目录挂载到S3C2410-RP目标板的mnt目录下;6) 加载LED点阵驱动程序;7) 执行并测试程序。2.5 实验源代码解释与说明A.驱动程序源文件led_ary.c#include /config.h为内核配置头文件,文件里面指向另一个由make menuconfig自动生成的文件autoconf.h#include /kernel.h定义了经常用到的函数原型及宏定义#include /module.h模块驱动程序的头文件,定义了内核模块相关的函数、变量及宏#include /sched.h为调度程序头文件,定义了任务结构#include /interrupt.h中包含了与操作系统中断相关的大部分宏及struct结构的定义#include #include /init.h中定义了驱动的初始化和退出相关的函数#include /* for udelay */#include #include /定义了Linux 内核的版本,用于版本检查#include /I/O头文件,定义对I/O端口操作的函数#include #include /访问系统硬件用的头文件#include #define led_ary_MAJOR102 /定义了led_ary_MAJOR设备的主设备号为102#define VERSION 2410RP-led_ary-V1.00-070820unsigned long ioremap_addr;void showversion(void)printk(*n); printk(t %s tn, VERSION); printk(*nn); /函数用于显示该设备的版本型号devfs_handle_t dev_handle; /系统支持devfs的数据结构,注册handle到存储设备上。int led_ary_temp_count=0; /定义的系统变量,防止文件被多重打开。ssize_t led_ary_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)char tmp1;printk(s3c2410: device file-read operation!n);tmp0=inb(ioremap_addr);copy_to_user(buf,tmp,1);return count; /函数实现对字符型设备进行读取操作ssize_t led_ary_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)outw(count,ioremap_addr);printk(s3c2410: device write operation!n);return count;/函数实现对字符性设备进行写操作/上述两个函数实现了用户空间和内核空间的数据交换,而且还可以检查用户空间指针的有效性/ioctl()函数,可实现读写之外的控制。ssize_t led_ary_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data)printk(s3c2410: device ioctl operation!n); /函数可重新定义用于实现I/O口的其他控制操作ssize_t led_ary_open (struct inode * inode ,struct file * file)return 0;/当用户态调用open函数时,对应内核态次函数被调用ssize_t led_ary_release (struct inode * inode ,struct file * file)return 0; /当用户态调用close函数时,此release函数被调用。struct file_operations led_ary_ops =open:led_ary_open,read:led_ary_read,write:led_ary_write,ioctl:led_ary_ioctl,release:led_ary_release,; /结构体file_operations在头文件 linux/fs.h中定义,用来存储驱动内核模块提供的对设备进行各种操作的函数的指针,指出设备驱动程序所提供的入口点位置static int _init HW_led_ary_init(void) int ret = -ENODEV;showversion();ret = devfs_register_chrdev(led_ary_MAJOR, led_ary, &led_ary_ops); /*字符设备led_ary进行注册*/if( ret 0 )printk ( s3c2410: init_module failed with %dn, ret);return ret;elseprintk(KERN_INFO S3c2410 led_ary register success!n);dev_handle = devfs_register( NULL, led_ary, DEVFS_FL_DEFAULT, led_ary_MAJOR, 0, S_IFCHR, &led_ary_ops, NULL);/* 注册devfs 设备*/printk(GPACON=%xn,GPACON); printk(BWSCON=%xn,BWSCON);ioremap_addr=ioremap(0x18000002,0x0f);/* 将一个IO地址空间映射到内核的虚拟地址空间上去*/outw(0x00ff,ioremap_addr);/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论