嵌入式实训报告

嵌入式系统设计实训报告

实训报告目录

一、任务名称内容……………………1

二、题目分析…………………1

三、系统平台搭建…………………………6

四、系统设计与实现………………………7

五、心得体会…………………14

六、参考文献及资料………………15

1.实训任务的名称、内容:

在这学期期末的实训中,我们的任务是“视频采集图像并实时显示在LCD上”。具体内容是,通过在USB接口上外接一个带USB口的摄像头,将采集到的视频图像数据放入输入缓冲区中。然后保存成文件的形式,或者运行移植到平台上的图像处理程序,对缓冲的图像数据直接进行相关处理,最后通过网络接口将图像发送到LCD上显示。

而对于我来说,分配到的任务是“摄像头的驱动”。

2.题目分析:

要实现视频采集,先要在系统平台上运行的是linux。启动LINUX后,启用了MMU,系统进入保护模式,所以应用程序就不能直接读写外设的I/O区域。(包括I/O端口和I/O内存),这时一般就要借助于该外设的驱动来进入内核完成这个工作。本系统中的视频采集分两步实现:一是为USB口数码摄像头在内
核中写入驱动,二是要再写入上层应用程序获取视频数据。我分配到的任务就是摄像头驱动的编写。于是先上网查找了资料。

   查得资料:

摄像头在Linux中是如何支持的;

在 Linux中,硬件的驱动程序,都是由内核支持的;目前比较新内核版本也集成了一些的摄像头驱动。就是Fedora、SuSE最新版本所支持的内核也是来自由 kernel.org 。所以支持也是极为正常的。内核对硬件的支持分为内置于和外挂模块两种方便。对于摄像头来说,大多是模块支持的;

  关于开发平台:

我们用的系统的硬件平台采用Samsung公司的处理器S3C2410x。该处理器内部集成了ARM公司ARM920T处理器核的32位微控制器,资源丰富:带独立的16 kB指令Cache和16 kB数据Cache,还有LCD控制器、RAM控制器、NAND闪存控制器、3路UART、4路DMA、4路带PWM的Timer、并行I/O口、8路 10位ADC、TouchScreen接口、I2C接口、I2S接口、2个USB接口控制器、2路SPI,主频最高可达203 MHz。在处理器丰富资源的基础上,还进行了相关的配置和扩展,平台配置了16 MB,16位的FLASH和64 MB,32位的SDRAM。通过以太网控制器芯片DM9000扩展了一个网口,另外引出了一个HOST、USB接口,通过在USB接口上外接一个带USB 接口的摄像头。

2410平台硬件如图所示:

http://tech.ccidnet.com/col/attachment/2007/1/1002581.jpg

实验箱图片:

2410经典

摄像头驱动

  在Linux 环境下,所有的外设都被看成一类称为“设备文件”的特殊文件,系统中所有硬件都可以用一个特殊的设备文件来表示。在本系统中,USB 摄像头被作为一种字符设备来对待,用/dev/video0 来表示。相对于应用程序来讲,硬件是不透明的,设备驱动程序屏蔽了硬件在实现上的细节,应用程序必须依靠相应驱动程序中定义的通信接口实现对硬件的操作。

  Video4Linux(简称V4L)是Linux 系统关于视频设备的内核驱动程序,它为针对视频设备的应用程序编程提供一系列接口函数。对于USB 接口摄像头,驱动程序中提供了基本的I/O操作接口函数open、read、write、close 的实现,对中断的处理实现,内存映射功能以及对I/O 通道的控制接口函数ioctl 的实现等,并在struct file_operations 数据结构中定义了这些函数,当应用程序对设备文件进行例如read、write 等操作时,嵌入式Linux 内核通过strcutfile_operations 数据结构访问驱动程序提供的函数。

摄像头驱动程序基本结构如下:

  1)驱动的注册与注销

  通过在驱动程序的初始化过程中调用 register_chrdev()或register_blkdev()函数来添加驱动程序并分配主设备号;通过调用unregister_chrdev()或unregister_blkdev()函数从内核中注销设备,同时释放其占用的主设备号。

  2)设备文件的打开与释放

  调用 file_operations 结构体中的open()函数打开设备;调用file_operations 结构中的函数release()关闭设备。

  3)设备的读/写操作

  使用函数 read()和write()完成对设备的读和写。

  4)设备的控制操作

  通过设备驱动程序中的函数ioctl()来完成。ioctl()的用法与具体设备密切关联,因此需要根据设备的情况进行具体分析。

  5)设备的中断和轮流查询处理

  由于有些硬件设备不支持中断,那么在对其读写时需要轮流查询设备状态,以便决定是否继续进行数据传输。如果硬件设备支持中断,则可以按中断方式进行操作。

以上这写就是查到的资料

三、系统平台搭建

 嵌入式系统的硬件资源少,不宜直接把Linux作为操作系统,要针对具体的应用对嵌入式linux进行裁剪,使整个系统能够存放到容量较小的FLASH中。Linux的动态模块加载,使 Linux的裁减极为方便,高度模块化的部件使添加非常容易。

嵌入式系统软件开发采用交叉编译调试的方式。交叉编译调试环境建立在宿主机上,对应的开发板叫做目标板。

通常宿主机和目标板上的处理器不同,所以程序需要使用针对处理器特点的编译器才能生成在相应平台上可运行的代码。GNU编译器提供这样的功能,在编译时,可以选择开发所需的宿主机和目标机,从而建立开发环境。在进行嵌入式开发前的第一步工作就是把一台PC机作为宿主机开发机;然后在宿主机上建立交叉编译调试的开发环境。

这里我们用的是GNU编译器,开发环境配置参考嵌入式实验指导书,由其他同学完成,这里不再赘述。

4.系统设计与实现

要设计摄像头的驱动,首先要搞清楚摄像头的具体型号。经查资料,可以用一个叫做ISHAL的工具获得。

使用情况如下图:

[root@localhost ~]# lshal |grep WebCam
  info.product = 'ZC0303 WebCam'  (string)
  usb_device.product = 'ZC0303 WebCam'  (string)

  其中,“usb_device.product=”后面的ZC0303说明这个摄像头是ZC303芯片组的。

  上面这个命令是列出系统硬件设备,然后从输出中,提取WebCam字样的信息。

  如果要看更详细的情况,就用以下命令:

[root@localhost ~]# lshal |grep usb

然后就找 ZC0303字样的设备,查看相应信息:

usb_device_ac8_303b_noserial

usb_device_ac8_303b_noserial_if0

usb_device_ac8_303b_noserial_usbraw

usb_device_ac8_303b_noserial_video4linux

接下来到驱动网站:http://mxhaard.free.fr/spca5xx.html

将驱动网址摄像头芯片所对应地址对号入座。

下载内核;

测试摄像头所用的内的内核版本是 2.6.16.19;

linux-2.6.16.19.tar.bz2

下载内核配置文件:

从Slackware的FTP上,找到了2.6.16.19的配置文件。请到这里下载;kernel261619.txt


编译内核;

第一步:解压内核软件包;

[root@localhost ~]#  tar jxvf linux-2.6.16.19.tar.bz2
[root@localhost ~]#  mv linux-2.6.16.19 /usr/src

把下载下来的内核配置文件改名复制到 /usr/src/linux-2.6.16.19

[root@localhost ~]# cp  kernel261619.txt  /usr/src/linux-2.6.16.19/.config

第二步:编译内核;

[root@localhost ~]# cd /usr/src/linux-2.6.16.19/
[root@localhost linux-2.6.16.19]# make
[root@localhost linux-2.6.16.19]# make modules_install
[root@localhost linux-2.6.16.19]# make install

第三步:查看/boot/grub/menu.lst文件;

一般的情况下,make install 安装内核后,系统会把启动写入GRUB的配置文件。/boot/grub/menu.lst。您可以看到有类似如下的一段;

title Fedora Core (2.6.16.19)
        root (hd0,6)
        kernel /boot/vmlinuz-2.6.16.19 ro root=LABEL=/1  rhgb quiet
        initrd /boot/initrd-2.6.16.19.img

编译摄像头驱动程序;

在编译摄像头驱动的前题是,我们要用2.6.16.19这个内核来启动系统,然后在 2.6.16.19内核系统环境下编译摄像头驱动;


 
下载摄像头驱动;

http://mxhaard.free.fr

spca5xx-20060501.tar.gz


解压编译;

在编译的过程中需要各种开发库和或开发工具之类的,比如gcc、make、automake等

[root@localhost ~]# tar zxvf spca5xx-20060501.tar.gz
[root@localhost ~]# cd spca5xx-20060501
[root@localhost spca5xx-20060501]# make
[root@localhost spca5xx-20060501]# make install
[root@localhost spca5xx-20060501]# depmod -a
[root@localhost spca5xx-20060501]# modprobe spca5xx

看看驱动模块挂载好了没有:

[root@localhost spca5xx-20060501]# lsmod |grep spca5xx

spca5xx               659920  0
videodev                7040  1 spca5xx

我们再查看一下设备/dev/video0是否存在:

[root@localhost spca5xx-20060501]# ls -lh /dev/video0
crw------- 1 beinan root 81, 0 06-08 09:33 /dev/video0


要使摄像头显示出影像,摄像头应用程序 SpcaView


 SpcaView
软件包,包括一组工具;

spcaview工具是用来纪录数据流,也能用来播放数据;
spcaserv 是流媒体服务器;
spcacat 简单图片的抓取工具;

SpcaView 下载和安装;

下载地址:

http://mxhaard.free.fr/spca50x/Download ,我下载的是目前这个版本:spcaview-20051212.tar.gz

依赖关系;

此软件依赖 libsdl,要先安装它才行,下载地址:http://www.libsdl.org ,我下载的是:SDL-1.2.10.tar.gz

http://www.libsdl.org/download-1.2.php

[root@localhost ~]# tar zxvf SDL-1.2.10.tar.gz
[root@localhost ~]#  cd SDL-1.2.10
[root@localhost SDL-1.2.10]# ./configure ; make ;make install

安装SpcaView

[root@localhost ~]# tar zxvf spcaview-20051212.tar.gz
[root@localhost ~]# cd spcaview-20051212
[root@localhost spcaview-20051212]# make ; make install

配置可执行程序的路径:

可执行的工具被安装到 /usr/local/bin目录中,所以我们还要配置一下用户的环境变量PATH 。配置命令执行路径,在当前用户家目录下的.bashrc文件中加入下面的一行;

export PATH=".:/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/X11R6/bin"

然后运行如下命令;

[root@localhost ~]# source .bashrc

spcaview来测试摄像头;

[root@localhost ~]# spcaview -d /dev/video0 -f jpg -s 320x240

 -s后面的参数是图像分辨率

如果抓取数据流,尝试用下面的命令,比如我们把抓取的数据流存在一个linuxsir.org.avi文件中;如果要播放,就用mplayer就行,xine也可以。

[root@localhost ~]#  spcaview -f yuv -o linuxsir.org.avi

最终效果如图:

五、心得体会

通过为期4周的实训,对于嵌入式软件设计我有了更深刻的体会,进一步熟悉了嵌入式LINUX的各种操作和应用。

这次实训是以小组为单位合作设计一个完整的项目,这在以前是没有遇上过的。让我们体会到现代工业设计模块化设计的过程,感受到团队合作的重要性。

在设计中,我认识到只完成好自己的任务是不够的,自己的设计必须和其他同学的相匹配,必须为其他同学提供服务,这就要求我们交流与协作。

同时,我还认识到在设计中要善于利用计算机查找资料,利用论坛解决问题,借鉴他人思想的长处。

七、       参考文献

电子发烧友:http://www.elecfans.com/emb/app/20110615202156.html

嵌入式视频采集:

http://www.elecfans.com/emb/app/20110615202156.html

《经典2410实验指导书》北京博创兴业有限责任公司经典2410试验箱指导书

 

第二篇:嵌入式实训报告

 嵌入式实训报告

    题    目: 串口通信步进电机控制系统

    系    部:    计算机科学与工程系   

    专    业:         计算机应用      

    班    级:           350920        

    姓    名:          孙    中       

    学    号:          35092018       

    同 组 人:       王    良    遇    

    指导教师:       刘    长    荣    

                                  

实训题目:步进电机控制系统

一、功能描述:

二、总体设计框架:

调用发送数据(void Uart_SendByte())、接受数据(int Uart_GetKey())、步进电机正转(void moto_run0())、步进电机反转(void moto_run1())、加速(void jia())、减速(void jian())、开始(void start())、暂停(void end())等函数。

步进电机系统电路原理图

触摸屏原理图

三、详细设计:

1、正转:

让电机绕组通电时序为A、AB、B、BC、C、CD、D、DA,就能够实现电机正转,并且设置标志flag为0。

            2、反转

让电机绕组通电时序为DA、D、DC、C、CB、B、BA、A,就能够实现电机正转,并且设置标志flag为1。

3、加速

根据正反转标志,让电机延时变小,就能够实现电机正转、反转的加速。

4、减速

根据正反转标志,让电机延时变大,就能够实现电机正转、反转的减速。

5、开始:

    调用正转函数。  

6、暂停

给电机送入同一个通电时序,就能让它实现电机的停止(保留在某一个状态)。

四、主要源程序代码:

int t,time=0;

int flag; //标志位,0表示正转,1表示反转

int pluse_table[]={0x01,0x09,0x08,0x0a,0x02,0x06,0x04,0x05,};

void moto_run0(void)   //正转

{

    flag=0;

    for(t=0;t<8;t++)

    {

       pluse_value=pluse_table[t];

       Delay(500);

    }

}

void moto_run1(void)   //反转

{

    flag=1;

    for(t=7;t>=0;t--)

    {

       pluse_value=pluse_table[t];

       Delay(500);

    }

}

void jiasu(void)//加速

{

    time=time-50;

    if((500+time)>=50)

    {

       if(flag==0)

       {

           for(t=0;t<8;t++)

           {

              pluse_value=pluse_table[t];

              Delay(500+time);

           }

       }

       else{

           for(t=7;t>=0;t--)

           {

              pluse_value=pluse_table[t];

              Delay(500+time);

}

    else{

       if(flag==0)

       {

           for(t=0;t<8;t++)

           {

              pluse_value=pluse_table[t];

              Delay(50);

           }

       }

       else{

           for(t=7;t>=0;t--)

           {

              pluse_value=pluse_table[t];

              Delay(50);

           }

}

void jiansu(void)//减速

{

    time=time+50;

    if((500+time)<=1000)

    {

       if(flag==0)

       {

           for(t=0;t<8;t++)

           {

              pluse_value=pluse_table[t];

              Delay(500+time);

           }

       }

       else{

           for(t=7;t>=0;t--)

           {

              pluse_value=pluse_table[t];

              Delay(500+time);

    }

    else{

       if(flag==0)

       {

           for(t=0;t<8;t++)

           {

              pluse_value=pluse_table[t];

              Delay(1000);

           }

       }

       else{

           for(t=7;t>=0;t--)

           {

              pluse_value=pluse_table[t];

              Delay(1000);

}

void start(void)//开始

{

    moto_run0();

}

void end(void)//暂停

{

    pluse_value=pluse_table[0];

}

void Main(void)                           

{  

     int i;

     Target_Init();

     LcdTest();                  // ARMII实验系统的初始化,包括CPU板

     GUI_Init();

     Test();

     GUI_SetColor(GUI_WHITE);

     GUI_FillRect(150,150,250,200);

     GUI_FillRect(400,150,500,200);

     GUI_FillRect(150,250,250,300);

     GUI_FillRect(400,250,500,300);

     GUI_FillRect(150,350,250,400);

     GUI_FillRect(400,350,500,400);

     GUI_SetFont(&GUI_FontHZ_Song_16);

     GUI_SetColor(GUI_BLUE);

     GUI_SetBkColor(GUI_WHITE);

     GUI_DispStringAt("正转",180,170);

     GUI_DispStringAt("反转",430,170);

     GUI_DispStringAt("加速",180,270);

     GUI_DispStringAt("减速",430,270);

     GUI_DispStringAt("开始",180,370);

     GUI_DispStringAt("暂停",430,370);

     while(1)

     {

        if((TOUCH_X>=150 && TOUCH_X<=250)&&(TOUCH_Y>=150 && TOUCH_Y<=200)) i=1;

        if((TOUCH_X>=400 && TOUCH_X<=500)&&(TOUCH_Y>=150 && TOUCH_Y<=200)) i=2;

        if((TOUCH_X>=150 && TOUCH_X<=250)&&(TOUCH_Y>=250 && TOUCH_Y<=300)) i=3;

        if((TOUCH_X>=400 && TOUCH_X<=500)&&(TOUCH_Y>=250 && TOUCH_Y<=300)) i=4;

        if((TOUCH_X>=150 && TOUCH_X<=250)&&(TOUCH_Y>=350 && TOUCH_Y<=400)) i=5;

        if((TOUCH_X>=400 && TOUCH_X<=500)&&(TOUCH_Y>=350 && TOUCH_Y<=400)) i=6;

        Uart_SendByte(i+'0');//发送

        switch(i)

        {

            case 1:moto_run0();break;

            case 2:moto_run1();break;

            case 3:jiasu();break;

            case 4:jiansu();break;

            case 5:start();break;

            case 6:end();break;

        }

     }

}

  五、总结:

通过这次实训,我学到了很多东西。对于项目的具体实施有了大概的了解,对于以后有着很大的帮助。并且理论知识得到了系统的学习,与实践相结合。当然还有许多不足之处仍需改进。

相关推荐