嵌入式课设报告

时间:2024.5.13

嵌入式操作系统WinCE的移植及应用程序设计

院):        计算机科学学院         

专业班级:       计算机科学与技术学院    

姓    名:        林科                   

学    号:        201003674              

指导教师:         王剑                   

设计时间:     2013.6.11~2013.6.17             

设计地点:         4教机房                

一、课程设计目的.................................. 3

二、设计任务及要求................................ 3

    一)、设计任务

     二)、设计要求

三、需求分析..................................... 3

     一)、Windows CE 操作系统简介

     二)、Platform Builder 开发工具介绍

四、总体设计……………………………………………………………6

    一)、Windows CE 平台的构建与配置

     二)、IO 接口控制实验之七段数码管和LED 显示

     三)、IO 接口控制实验——电机控制

五、详细设计与实现[含代码和实现界面]............... 6

 一)、基于Windows CE平台下嵌入式操作系统定制的集成开发环境建立;

       嵌入式操作系统Windows CE平台的搭建;

       基于Windows CE的应用开发环境的建立和程序设计方法;

  二)、七段数码管和LED显示控制程序设计;

  三)、IO 接口控制——电机控制设计。

六、课程设计小结................................. 33

一、课程设计目的

   1.了解嵌入式系统、嵌入式操作系统,掌握基于嵌入式系统的应用开发基本知识。

  2.了解嵌入式操作系统Windows CE的特点,Windows CE的主要模块及各自的功能。掌握嵌入式操作系统Windows CE的配置、编译、移植方法。

  3.了解Visual Studio.NET开发环境,掌握基于Windows CE平台的应用程序设计方法。

二、设计任务及要求

一、设计内容

  1.嵌入式操作系统系统基础知识,基于Windows CE的应用开发环境的建立和程序设计方法

  介绍嵌入式操作系统Windows CE的特点,了解Windows CE的主要模块及各自的功能。了解微软提供给Windows CE开发人员进行基于Windows CE平台下嵌入式操作系统定制的集成开发环境Platform Builder(PB),掌握通过交互式的环境来设计和定制内核、选择系统特性,然后进行编译和调试的全过程。了解BSP在嵌入式系统中位置及其作用。介绍在嵌入式操作系统Windows CE上搭建嵌入式应用开发环境的方法,在Visual Studio.NET中建立移动设备开发工程、程序调试以及下载运行的方法。

  2.嵌入式操作系统Windows CE平台的搭建

  安装XSBase270实验开发平台的BSP。根据XSBase270实验开发平台的特点和系统需求,利用Platform Builder集成开发环境配置Windows CE操作系统的特性和功能。编译、链接操作系统内核,生成系统映像文件。下载并运行编译好的Windows CE系统。

  3.IO接口控制---七段数码管和LED显示控制程序设计

  了解Windows CE下I/O访问机制和原理。了解LED和七段数码管的显示和控制原理。掌握Windows CE下访问硬件I/O寄存器的方法,以及使用Visual Studio.NET对硬件设备编程的一般方法。

  4. IO 接口控制——电机控制设计

了解WinCE 下IO 访问机制和原理;掌握GPIO 的控制寄存器的控制方法;掌握线程通信的编程方法;熟悉EVC 和VS.Net 的使开发环境。

二、设计要求

        1.功能要求

  安装XSBase270实验开发平台的BSP;在嵌入式操作系统Windows CE平台定制的集成开发环境Platform Builder(PB)上定制内核,编译和调试并生成内核映像文件,下载并运行编译好的Windows CE系统;在VS.NET中编写对 XSBase270目标板上LED和七段数码管的控制程序,下载运行程序。

      2.设计所需设备与工具

        ① 装有Platform Builder、Visual Studio.NET开发环境,有并口、串口和USB接口的PC 机一台。

        ② XSBase270 实验开发平台一套。

三、需求分析

    1、Windows CE 操作系统简介

Microsoft Windows CE 是一个开放的、可裁剪的、32 位的实时嵌入式窗口操作系统。

和其他桌面窗口操作系统(Windows XP/2000)相比,它具有可靠性好、实时性高、内核体

积小等特点,适用于各种嵌入系统和产品。它拥有多线程、多任务、确定性的实时、完全抢

先式优先级的操作系统环境,专门面向只有有限资源的嵌入式硬件系统。同时,开发人员可

以根据特定硬件系统对Windows CE 操作系统进行裁剪、定制,所以目前Windows CE 被广

泛用于各种嵌入式智能设备的开发,是当今应用最多、增长最快的嵌入式操作系统。

Windows CE 被设计成为一种高度模块化的操作系统,每一模块都提供特定的功能,这

些模块中的一部分被划分成组件,系统设计者可以根据设备的性质只选择那些必要的模块或

模块中的组件包含进操作系统映像,从而使Windows CE 变得非常紧凑(只占不到200 KB

的RAM),因此只占用了运行设备所需的最小的ROM、RAM 以及其它硬件资源。

Windows CE 被分成不同的模块,其中最主要的模块有内核模块(Kernel)、对象存储模

块、图形窗口事件子系统(GWES)模块以及通信(Communication)模块。另外Windows CE

还包含一些附加的可选择模块,这些模块可支持的任务有管理可安装设备驱动程序、支持

COM 等。一个最小的Windows CE 系统至少由内核和文件系统模块组成。

     1)、 内核模块

内核模块是Windows CE 操作系统的核心,它为任何基于Windows CE 的设备提供处理

器调度、内存管理、异常处理以及系统内通信等系统功能,并为应用程序使用这些核心功能

提供内核服务。Windows CE 的内核模块通过CoreDLL 模块表示。所有的操作系统定制设

计都必须包含这个模块,但并不是这个模块的所有组件都必需的,有一些内核组件是可选的。

     2)、 对象存储

对象存储是Windows CE 的默认文件系统,它相当于Windows CE 设备上的硬盘。对象

存储是由共享一个内核堆的文件系统、系统数据库和系统注册表组成,即使在没有系统主电

源时,对象存储也能维持应用程序及相关数据不会丢失。对象存储可将用户数据和应用程序

数据存入文件或注册器。在操作系统创建进程(该进程中只包括那些必需选项)的过程中,

对于这些不同的对象存储组件,可以选取,也可以忽略。

     3)、 图形窗口和事件系统模块

图形窗口和事件系统模块(GWES)包含大部分的核心Windows CE 功能,它集成了图

形设备接口(GDI)、窗口管理器和事件管理器。GWES 模块时Windows CE 操作系统高度

组件化的部分,它分别由USER 和GDI 两部分组成,USER 用来处理消息、事件及鼠标和

键盘等用户输入,而GDI 用于处理图形的屏幕和打印输出等。GWES 是用户、应用程序和

操作系统之间的图形用户接口。GWES 通过处理键盘、鼠标动作与用户交互,并选择传送

到应用程序和操作系统的信息。GWES 通过创建并管理在显示设备和打印机上显示的窗口、

图形以及文本来处理输出。

GWES 的中心是窗口。所有应用程序都通过窗口接收来自操作系统的消息,即使那些

为缺少图形显示的设备创建的应用程序也是如此。GWES 提供控制器、菜单、对话框以及

图形显示的设备资源,还提供GDI 以控制文本与图形显示。

      4)、 通信模块

通信模块为基于Windows CE 的设备提供有线或无线通信能力,使Windows CE 设备能

够与其他设备或计算机进行连接与通信,通信组件提供对下列通信硬件和数据协议的支持:

· 串行I/O 支持

· 远程访问服务(RAS)

· 传输控制协议/ Internet 协议(TCP/IP)

· 局域网(LAN)

· 电话技术API (TAPI)

· WinCE 的无线服务

可选组件

除上述主要模块之外,还可使用其它的操作系统模块。这些模块与组件主要有:

· 设备管理器和设备驱动程序

· 多媒体(声音)支持模块

· COM 支持模块

· WinCE 外壳模块

WinCE 提供的每一模块或组件都支持一组可用的相关API 函数。

     2 Platform Builder 开发工具介绍

Platform Builder(PB)是微软提供给Windows CE 开发人员进行基于Windows CE 平台下

嵌入式操作系统定制的集成开发环境。它提供了所有进行设计、创建、编译、测试和调试

Windows CE 操作系统平台的工具。它运行在桌面Windows 下,开发人员可以通过交互式的

环境来设计和定制内核、选择系统特性,然后进行编译和调试。该工具能够根据用户的需求,

选择构建具有不同内核功能的CE 系统。同时,它也是一个集成的编译环境,可以为所有

CE 支持的CPU 目标代码编译C/C++程序。一旦成功地编译了一个CE 系统,就会得到一个

名为nk.bin 的映像文件。将该文件下载到目标板中,就能够运行CE 了。

Platform Builder 提供了开发人员快速建立基于Windows CE 嵌入式系统所需的各种工

具。Platform Builder 的集成开发环境(IDE)允许开发人员配置、建立并调试能够借助Windows

和Web 强大功能为嵌入式系统带来灵活性与可靠性的新一代高度模块化设计方案。

Platform Builder 提供的主要特性包括:

? 平台开发向导(Platform Wizard)和BSP 开发向导:开发向导用于引导开发人员区创建

一个简单的系统平台或BSP(板级支持软件包),然后再根据要求进一步修改。开发向

导提高了平台和BSP 创建效率;

? 特性目录(Catalog):操作系统可选特性均在特性目录(Catalog)中列出,开发人员

可以选择相应的特性来定制操作系统;

? 导出向导(Export Wizard)。可以向其他Platform Builder 用户导出自定义的目录(Catalog)

特性;

? 导出SDK 向导(Export SDK Wizard):使用户可以导出一个自定义的软件开发工具包

(SDK),可以将客户定制的SDK 导出到特定的开发环境中(如EVC)。

3

? 远程工具:可以执行同基于Windows CE 的目标设备有关的各种调试任务和信息收集任

务;

? 仿真器(Emulator):通过硬件仿真加速和简化了系统的开发,使用户可以在开发工作

站上对平台和应用程序进行调试,大大简化了系统的开发流程,缩短了开发时间。

? 应用程序调试器:可以在自定义的操作系统映像上对应用程序进行调试;

? 内核调试器:可以对自定义的操作系统映像进行调试,并且向用户提供有关映像性能的

信息;

? 驱动测试工具包(Windows CE.net Test Kit):系统为驱动程序开发提供了基本的测试

工具集;

? 基础配置:为各种流行的设备类别预置的可操作系统基础平台,为自定义操作系统的创

建提供了一个起点。

四、总体设计

基于Windows CE平台下嵌入式操作系统定制的集成开发环境建立;嵌入式操作系统Windows CE平台的搭建;基于Windows CE的应用开发环境的建立和程序设计方法;七段数码管和LED显示控制程序设计;IO 接口控制——电机控制设计。

   Windows CE 平台的构建与配置

1、掌握Windows CE 内核的配置、编译方法;

2、掌握构建一个适合特定开发平台的Windows CE 系统方法;

3、熟悉Platform Builder 开发工具使用方法。

  IO 接口控制实验之七段数码管和LED 显示

    1、掌握在Windows CE 下访问硬件I/O 寄存器的一般方法;

    2、了解WinCE 下IO 访问机制和原理;

    3、了解数码管(LED)的显示及控制原理;

4、熟悉VS.Net 的使开发环境;

  IO 接口控制实验——电机控制

   1、了解WinCE 下IO 访问机制和原理;

   2、掌握GPIO 的控制寄存器的控制方法;

   3、掌握线程通信的编程方法;

   4、熟悉EVC 和VS.Net 的使开发环境;

五、详细设计与实现【含代码与实现界面】

嵌入式Windows CE的搭建及应用

一、编译XSBase270上的Windows CE 5.0系统

    1 创建新工程

    2 配置XSBase270平台

二、下载内核镜像

    1 Ethernet Bootloader(EBOOT)

    2 下载内核镜像文件

     将并口线(JTAG)、串口线、以太网线分别和微机连接好,连接ARM实验箱电源线,打开ARM电源。

1.Ethernet Bootloader(EBOOT)

(1)打开资源管理器,找到文件夹c:\Windows CE 光盘\Jflash_Pxa270_P30下的文件cmd.bat,双 击执行,在“>”提示后键入jflashmm.exe pxa270 EBOOT.nb0。

(2)按下回车键出现界面

(3)写入并且校对

(4)写Eboot到flash存储器结束

(5)如果校对出错,重新键入jflashmm.exe pxa270 EBOOT.nb0,重复(1)~(3),直到正确写入为止。如果多次写入出错,关闭ARM电源,20秒后打开ARM电源,重新烧录

(6)关闭ARM电源。

(7)右键单击”网上邻居” →”属性”,弹出网络连接对话框,右键单击”本地连接”→”属性”,设置TCP/IP协议。修改IP地址为192.168.0.2

(8)在桌面上找到超级终端图标,双击启动。

(9)打开ARM电源。出现信息后按空格键进行设置。选择0改IP,只要保证ARM的IP和微机的IP在同一网段即可,如192.168.0.5或192.168.0.6选择5,改为,ARM上的WINCE烧录后可自己启动,其他不用设置。

(10)请将微机时间改为2007/10/1,PB才能使用。找到PB工程文件,启动。

(11)选择超级终端的。

(12)在超级终端的菜单进行PB和ARM的连接设置。

(13)继续Kernel Service Map进行设置.

(14)在Download选项点击Setting。

 (15)  在出现的界面中选择XSBASE

(16)按图17菜单连接PB和ARM。出现文件下载对话框,在超级终端中出现WINCE烧录信息。

(17)WINCE烧录结束后ARM上自动启动WINCE。

三、ActiveSync的使用

     ActiveSync用来实现PC上的应用程序和ARM上的应用程序保持同步。

    (1) 打开目标机(ARM)电源,进入“网络和拨号连接”。(2)双击“新建连接”,建立一个新连接。点击“下一步”。(3)选择“直接连接”,点击“下一步”。(4)选择设备“COM2”,点击“配置”,进行配置。(5)“我的连接”已经创建完毕。(6)在ARM机的WINCE系统中选择“控制面板”→“PC连接”。(7)出现对话框后,选择“更改”。(8)选择“我的连接”,确定,ARM中“我的连接”创建完成。(9)插上USB线,微机会自动识别USB设备,并启动ActiveSync:

         1.USB线一定要在第(8)步之后插,否则连接不成功。如果出现此情况,则拔掉USB线,重新建立一个新的连接,再插USB线。

         2.ARM上的“我的连接”在ARM关电后会消失。

(10)选择“下一步”。(11)选择弹出界面中的同步文件夹,选择“确定”,“下一步”,“完成”。

七段数码管和LED显示控制程序设计

第一步:连接好实验系统,打开实验箱电源。

第二步:打开对应的工程文件,我们可以看到硬件地址映射到内存的关键代码

第三步:编译、下载与调试

(1)、IO 接口控制LED工程的调试和发行版的编译配置

(2)、编译该代码,点击运行按钮,这样程序就会下载到XSBase270 目标板板上运行。运

行界面。

(3)、应用程序操作过程:

? Light Control 表示对XSBase270 目标板的8 个发光二极管控制,按“Start”按钮,发光

二极管左移或右移;L1~L8 对应目标板的发光二极管,勾选后按“Set”按钮,对应的

二极管点亮。按“Stop”按钮,二极管的左移或右移停止。

? Led Control 表示对目标板的4 个七段数码管的控制,在文本框中输入4 位(0~9)数

字,按“Set”按钮,七段数码管将显示输入的数字;按“Count”按钮,数码管进行计

数操作,按“Stop”按钮停止计数。

(4)、修改程序,实现其他不同的显示实验效果。

一、执行代码:

// Led.cpp : Defines the class behaviors for the application.

//

#include "stdafx.h"

#include "Led.h"

#include "LedDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CLedApp

BEGIN_MESSAGE_MAP(CLedApp, CWinApp)

END_MESSAGE_MAP()

// CLedApp construction

CLedApp::CLedApp()

    : CWinApp()

{

    // TODO: add construction code here,

    // Place all significant initialization in InitInstance

}

// The one and only CLedApp object

CLedApp theApp;

// CLedApp initialization

BOOL CLedApp::InitInstance()

{

    // Standard initialization

    // If you are not using these features and wish to reduce the size

    // of your final executable, you should remove from the following

    // the specific initialization routines you do not need

    // Change the registry key under which our settings are stored

    // TODO: You should modify this string to be something appropriate

    // such as the name of your company or organization

    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    CLedDlg dlg;

    m_pMainWnd = &dlg;

    INT_PTR nResponse = dlg.DoModal();

    if (nResponse == IDOK)

    {

        // TODO: Place code here to handle when the dialog is

        //  dismissed with OK

    }

    // Since the dialog has been closed, return FALSE so that we exit the

    //  application, rather than start the application's message pump.

    return FALSE;

}

// LedDlg.cpp : implementation file

//

#include "stdafx.h"

#include "Led.h"

#include "LedDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

char* pLightReg = NULL;

USHORT *v_pLEDBaseAddr1=NULL;

USHORT *v_pLEDBaseAddr2=NULL;

USHORT *v_pLEDBaseAddr3=NULL;

#define BIT7  (0x1<<7)

#define BIT15 (0x1<<15)

extern "C" __declspec(dllimport) BOOL VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );

#define LED_BASEADDR1    0x10200000

#define LED_BASEADDR2    0x10300000

#define LED_BASEADDR3    0x10400000

#define pLightIoBaseAddress 0x10500000

BYTE NumData[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

UINT16 READ_PORT_USHORT(UINT16 *pAddr)

{

    UINT32 nAlignedAddr = ((UINT32)pAddr & ~0x3);

    if ((UINT32)pAddr & 0x2)    // Is the address an "odd" word within a longword?

    {

        // Yes - read a longword and data is in the upper word.

        return((UINT16) ((*(volatile unsigned long *)nAlignedAddr) >> 16));

    }

    else

    {

        // No - read single word.

        return(*(volatile unsigned short *)nAlignedAddr);

    }

}

void WRITE_PORT_USHORT(UINT16 *pAddr, UINT16 Data)

{

    UINT32 nAlignedAddr = ((UINT32)pAddr & ~0x3);

    if ((UINT32)pAddr & 0x2)    // Is the address an "odd" word within a longword?

    {

        // Yes - write a longword with data in the upper word.

        *(volatile UINT32 *)nAlignedAddr = (READ_PORT_USHORT(pAddr) | (Data << 16));

    }

    else

    {

        // No - write single word.

        *(volatile UINT16 *)pAddr = Data;

    }

}

// CLedDlg dialog

CLedDlg::CLedDlg(CWnd* pParent /*=NULL*/)

    : CDialog(CLedDlg::IDD, pParent)

    , m_LedValue(1234)

{

    count=0;

    outdata=0x80;

    setLightData=0;

    LedCount=0;

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CLedDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    DDX_Control(pDX, IDC_LED, m_ControlLed);

    DDX_Control(pDX, IDC_LeftShift, m_LeftShift);

    DDX_Control(pDX, IDC_RightShift, m_RightShift);

    DDX_Text(pDX, IDC_LED, m_LedValue);

}

BEGIN_MESSAGE_MAP(CLedDlg, CDialog)

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)

    ON_WM_SIZE()

#endif

    //}}AFX_MSG_MAP

    ON_BN_CLICKED(IDC_LedSet, &CLedDlg::OnBnClickedLedset)

    ON_BN_CLICKED(IDC_CountTime, &CLedDlg::OnBnClickedCounttime)

    ON_BN_CLICKED(IDC_LedStop, &CLedDlg::OnBnClickedLedstop)

    ON_BN_CLICKED(IDC_LightStart, &CLedDlg::OnBnClickedLightstart)

    ON_BN_CLICKED(IDC_LightStop, &CLedDlg::OnBnClickedLightstop)

    ON_BN_CLICKED(IDC_LightSet, &CLedDlg::OnBnClickedLightset)

    ON_WM_TIMER()

    ON_WM_DESTROY()

END_MESSAGE_MAP()

// CLedDlg message handlers

BOOL CLedDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically

    //  when the application's main window is not a dialog

    SetIcon(m_hIcon, TRUE);          // Set big icon

    SetIcon(m_hIcon, FALSE);     // Set small icon

    m_LeftShift.SetCheck(1);

    if(!SetMemoryMap())

        return FALSE;

    *pLightReg=0xff;

    // TODO: Add extra initialization here

   

    return TRUE;  // return TRUE  unless you set the focus to a control

}

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)

void CLedDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)

{

    DRA::RelayoutDialog(

        AfxGetInstanceHandle(),

        this->m_hWnd,

        DRA::GetDisplayMode() != DRA::Portrait ?

            MAKEINTRESOURCE(IDD_LED_DIALOG_WIDE) :

            MAKEINTRESOURCE(IDD_LED_DIALOG));

}

#endif

void CLedDlg::SetLedValue(unsigned int indata)

{

    USHORT Data;

    UINT buf;

    buf=indata;  

    buf=buf%1000000; 

    Data=NumData[buf/100000];

    buf=buf%100000;

    Data|=NumData[buf/10000]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr1,~(Data|BIT7|BIT15));

   

    //*v_pLEDBaseAddr1=~(Data|BIT7|BIT15);

    buf=buf%10000;

    Data=NumData[buf/1000];

    buf=buf%1000;

    Data|=NumData[buf/100]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr2,~(Data|BIT7|BIT15));

    //*v_pLEDBaseAddr2=~(Data|BIT7|BIT15);

    buf=buf%100;

    Data=NumData[buf/10];

    buf=buf%10;

    Data|=NumData[buf]<<8;

    WRITE_PORT_USHORT(v_pLEDBaseAddr3,~(Data|BIT7|BIT15));

    //*v_pLEDBaseAddr3=~(Data|BIT7|BIT15);

}

BOOL CLedDlg::SetMemoryMap(void)

{

    if(!(v_pLEDBaseAddr1=(USHORT*)VirtualAlloc(0,0x400,MEM_RESERVE,PAGE_READWRITE)))

    {

        MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

if(!VirtualCopy((PVOID)v_pLEDBaseAddr1,(PVOID)(LED_BASEADDR1>>8),0x400,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))

    {

        VirtualFree((PVOID)v_pLEDBaseAddr1,0,MEM_RELEASE);

        pLightReg = NULL;

        MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

    if(!(v_pLEDBaseAddr2=(USHORT*)VirtualAlloc(0,0x400,MEM_RESERVE,PAGE_READWRITE)))

    {

        MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

if(!VirtualCopy((PVOID)v_pLEDBaseAddr2,(PVOID)(LED_BASEADDR2>>8),0x400,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))

    {

        VirtualFree((PVOID)v_pLEDBaseAddr2,0,MEM_RELEASE);

        pLightReg = NULL;

        MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

    if(!(v_pLEDBaseAddr3=(USHORT*)VirtualAlloc(0,0x400,MEM_RESERVE,PAGE_READWRITE)))

    {

        MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

if(!VirtualCopy((PVOID)v_pLEDBaseAddr3,(PVOID)(LED_BASEADDR3>>8),0x400,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))

    {

        VirtualFree((PVOID)v_pLEDBaseAddr3,0,MEM_RELEASE);

        pLightReg = NULL;

        MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

    //////////////////

    if(!(pLightReg=(char*)VirtualAlloc(0,0x400,MEM_RESERVE,PAGE_READWRITE)))

    {

        MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

if(!VirtualCopy((PVOID)pLightReg,(PVOID)(pLightIoBaseAddress>>8),0x400,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))

    {

        VirtualFree((PVOID)pLightReg,0,MEM_RELEASE);

        pLightReg = NULL;

        MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

        return FALSE;

    }

    return TRUE;

}

void CLedDlg::OnBnClickedLedset()

{

    UpdateData(TRUE);

    SetLedValue(m_LedValue);

    // TODO: Add your control notification handler code here

}

void CLedDlg::OnBnClickedCounttime()

{

    UpdateData(TRUE);

    SetTimer(2,500,NULL);    // TODO: Add your control notification handler code here

}

void CLedDlg::OnBnClickedLedstop()

{

    KillTimer(2);

}

void CLedDlg::OnBnClickedLightstart()

{

    SetTimer(1,500,NULL);// TODO: Add your control notification handler code here

}

void CLedDlg::OnBnClickedLightstop()

{

    KillTimer(1);

    // TODO: Add your control notification handler code here

}

void CLedDlg::OnBnClickedLightset()

{

        KillTimer(1);

    setLightData=0;

    for(int Index=0;Index<8;Index++){

        if(IsDlgButtonChecked(IDC_L1+Index))

            setLightData|=0x1<<Index;

    }

    *pLightReg=~setLightData;

    // TODO: Add your control notification handler code here

}

void CLedDlg::OnTimer(UINT_PTR nIDEvent)

{

    switch(nIDEvent)

    {

    case 1:

        count++;

        if(count<8)

        {

            if(m_LeftShift.GetCheck())

                outdata=outdata>>1;

            else

                outdata=outdata<<1;

        }

        else

        {

            count=0;

            if(m_LeftShift.GetCheck())

                outdata=0x80;

            else

                outdata=0x01;

        }

        *pLightReg=~outdata;

        break;

    case 2:

        //LedCount++;

        m_LedValue++;

        SetLedValue(m_LedValue);

        UpdateData(FALSE);

        break;

    }   // TODO: Add your message handler code here and/or call default

    CDialog::OnTimer(nIDEvent);

}

void CLedDlg::OnDestroy()

{

   

    if(pLightReg)

        VirtualFree((PVOID)pLightReg,0,MEM_RELEASE);

    if(v_pLEDBaseAddr1)

        VirtualFree((PVOID)v_pLEDBaseAddr1,0,MEM_RELEASE);

    if(v_pLEDBaseAddr2)

        VirtualFree((PVOID)v_pLEDBaseAddr2,0,MEM_RELEASE);

    if(v_pLEDBaseAddr3)

        VirtualFree((PVOID)v_pLEDBaseAddr3,0,MEM_RELEASE);

    // TODO: Add your message handler code here

    CDialog::OnDestroy();

}

二、代码分析:

(1)、虚拟内存函数介绍

IO 接口属于XScale 处理器的外部设备,类似于通常所使用的PC 的串口、并口或者PC

喇叭。对于一般单片机,可以直接操作硬件,即通过直接读写IO 端口来访问硬件。而对于

Windows CE 操作系统,不允许直接访问硬件,尽管知道物理地址,我们仍不能直接访问它,

因此必须使用特殊的方法来访问硬件。

Windows CE 操作系统出于稳定性和安全的要求,屏蔽了用户应用程序对硬件访问的权

限,只有内核应用程序才可以访问硬件资源。如果要直接访问某一个地址的物理内存,可以

采用内存映射的方法,将该硬件寄存器映射到普通的内存空间,像操作内存地址一样操作硬

件寄存器。Windows CE 提供了VirtualAlloc()和VirtualCopy()函数,VirtualAlloc 负责在虚拟

内存空间内保留一段虚拟内存,而VirtualCopy 负责把一段物理内存和虚拟内存绑定,这样,

最终对物理内存的访问还是通过虚拟地址进行。下面简单介绍这些函数的作用和使用方法。

VirtualAlloc()函数用于分配一块内存空间。如果要映射一个硬件寄存器,必然要将其映

射到一块确定的内存空间。在这里我们分配一个内存空间。这个内存空间并不占用实际内存

空间,而是留待后面进行分配。

VirtualAlloc()函数原型为:

LPVOID VirtualAlloc(

LPVOID lpAddress, // 希望的虚拟内存起始地址

DWORD dwSize, // 以字节为单位的大小

DWORD flAllocationType, // 申请类型,分为Reserve 和Commit

DWORD flProtect // 访问权限

);

其参数lpAddress 包含一个内存地址,用于定义待分配区域的首地址。通常可将此参数

设置为NULL,由系统通过搜索地址空间来决定满足条件未保留的地址空间。这时系统可从

地址空间的任意位置处开始保留一个区域。如果存在一个足够大的空闲区域,那么系统将会

保留此区域并返回此保留区域的虚拟地址,否则将导致分配的失败而返回NULL。这里需要

特别指出的是,在指定lpAddress 的内存地址时,必须确保从分配粒度的边界处开始。

VirtualCopy()负责将硬件设备寄存器的物理地址与VirtualAlloc()分配的虚拟地址做一个

映射关系,这样驱动程序访问虚拟地址即是访问对应的物理地址处的第一个寄存器。

VirtualCopy()函数原型为:

BOOLVirtualCopy(

LPVOID lpvDest, // 虚拟内存的目标地址

LPVOID lpvSrc, // 物理内存地址

DWORD cbSize, // 要绑定的大小

DWORD fdwProtect // 访问权限

);

由于VS.net 里没有提供没有VirtualCopy()的头文件和库文件(这些是由Platform Builder

提供的),因此需要将它们作为外部函数调用导入。如下:extern "C" __declspec(dllimport) BOOL VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc,DWORD cbSize, DWORD fdwProtect );如此调用VirtualCopy 函数后,物理地址和虚拟内存空间就对应起来了。对于分配的内存空间,虽然没有占用实际的内存空间,但是还是占用了系统的存储器地址,因此在退出程序时需要将其释放掉。使用的函数是VirtualFree()。其函数原型为:

BOOLVirtualFree(

LPVOID lpAddress, // 虚拟内存的地址

DWORD dwSize, // 释放的地址空间区域的大小

DWORD dwFreeType // 释放内存类型

);

其中,参数lpAddress 为指向待释放页面区域的指针。参数dwSize 指定了要释放的地址空间

区域的大小,如果参数dwFreeType 指定了MEM_RELEASE 标志,则将dwSize 设置为0,

由系统计算在特定内存地址上的待释放区域的大小。参数dwFreeType 为所执行的释放操作

的类型。

(2)虚拟内存函数使用方法

首先使用VirtualAlloc 分配出一个虚拟的地址空间,代码如下:

VirtualAlloc(0,0x1000,MEM_RESERVE,PAGE_READWRITE)

这样就分配出一个MEM_RESERVE 类型的存储器空间,它并没有占用实际内存空间,

而是虚拟的地址空间。接着将实际的硬件地址(例如LED 的片选控制信号地址)映射到前面分配的虚拟地址空间,使用VirtualCopy 函数建立起两个地址间的映射关系。具体代码如下:VirtualCopy((PVOID)pLightReg,(PVOID)(pLightIoBaseAddress>>8),0x1000,PAGE_READ

WRITE|PAGE_NOCACHE|PAGE_PHYSICAL)这里的pLightReg 即前面分配的虚拟地址空间,而pLightIoBaseAddress 为实际的硬件地址,需要将它右移8 位,因为在函数中存储器分配是以256 位为单位的。而后面的选项则指定了映射地址的属性——可读写、不缓冲以及硬件物理地址。现在就可以使用虚拟地址访问原本不能直接访问的硬件地址了。在程序退出的时候,出于安全与妥善考虑,还应使用VirtualFree 将已经分配的空间释放掉。实际的代码如下:

VirtualFree((PVOID) pLightReg,,0,MEM_RELEASE);

三、执行界面:

IO 接口控制——电机控制设计

第一步:连接好实验系统,打开实验箱电源。

第二步:打开电机控制的工程文件Motor.vcw,进行编译:

第三步:编译该代码,点击运行按钮,这样程序就会下载到XSBase270 目标板板上运行。

运行界面。

第三步:电机控制程序操作过程:

? Step Motor Controll 表示对XSBase270 目标板的步进电机进行控制操作,按“Start Run”

按钮,启动步进电机,当“Postive”表正转,“Reverse”表示反转,当“Continue”被

勾选后,步进电机将连续运转,直到按下“Stop Run”按钮。“Count”表示步进电机的

8运行脉冲数,在“Continue”没有被选中时,步进电机运行到设定的脉冲数后停止运行;

“Ratio”表示PWM 的占空比。

? DC Motor Control 表示对目标板的直流电机运行进行控制,按“Start Run”按钮,启动

步进电机,当“Postive”表正转,“Reverse”表示反转,当“Continue”被勾选后,电

机将连续运转,直到按下“Stop Run”按钮。“Time”表示直流电机的运行时间,在

“Continue”没有被选中时,直流电机运行到设定时间后停止运行;

第四步:修改应用程序,使电机正转运行到设定时间后自动进入反转运行。

一、执行代码

// Motor.cpp : Defines the class behaviors for the application.

#include "stdafx.h"

#include "Motor.h"

#include "MotorDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CMotorApp

BEGIN_MESSAGE_MAP(CMotorApp, CWinApp)

END_MESSAGE_MAP()

// CMotorApp construction

CMotorApp::CMotorApp()

    : CWinApp()

{

    // TODO: add construction code here,

    // Place all significant initialization in InitInstance

}

// The one and only CMotorApp object

CMotorApp theApp;

// CMotorApp initialization

BOOL CMotorApp::InitInstance()

{

    // Standard initialization

    // If you are not using these features and wish to reduce the size

    // of your final executable, you should remove from the following

    // the specific initialization routines you do not need

    // Change the registry key under which our settings are stored

    // TODO: You should modify this string to be something appropriate

    // such as the name of your company or organization

    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    CMotorDlg dlg;

    m_pMainWnd = &dlg;

    INT_PTR nResponse = dlg.DoModal();

    if (nResponse == IDOK)

    {

        // TODO: Place code here to handle when the dialog is

        //  dismissed with OK

    }

    // Since the dialog has been closed, return FALSE so that we exit the

    //  application, rather than start the application's message pump.

    return FALSE;

}

// MotorDlg.cpp : implementation file

//

#include "stdafx.h"

#include "Motor.h"

#include "MotorDlg.h"

#include "Motordef.h"

#include "wait.h"

#include <pkfuncs.h>

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

volatile GPIO_REGS  *v_pGPIOReg = NULL;

#define StepBaseTime 2500

#define GPIO_81_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_81 //用于直流电机

#define GPIO_81_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_81

#define GPIO_82_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_82 //用于直流电机

#define GPIO_82_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_82

#define GPIO_83_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_83 //用于产生步进电机脉冲

#define GPIO_83_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_83

#define GPIO_84_PullHigh()  v_pGPIOReg->GPSR_z|=GPIO_84 //用于控制步进电机方向

#define GPIO_84_PullLow()   v_pGPIOReg->GPCR_z|=GPIO_84

#define GPIO_53_PullHigh()  v_pGPIOReg->GPSR_y|=GPIO_53//用于步进电机输出使能

#define GPIO_53_PullLow()   v_pGPIOReg->GPCR_y|=GPIO_53

// CMotorDlg dialog

UINT StepMotorThread(LPVOID lpParam)   //步进电机运行线程

{

    CMotorDlg *pDlg=(CMotorDlg*)lpParam;

    CWait waitTime;

    WaitForSingleObject(pDlg->StepThreadBegin.m_hObject,INFINITE);

    GPIO_53_PullLow();

    while(1)

    {          

        if(pDlg->m_StepMotorPositive.GetCheck())

            GPIO_84_PullLow();

        else  

            GPIO_84_PullHigh();

        if(!pDlg->m_StepContinue.GetCheck())

        {

            pDlg->m_StepRunTime--;

            if(pDlg->m_StepRunTime <=0)

                break;

        }

        int result=::WaitForSingleObject(pDlg->StepThreadEnd.m_hObject,0);

        if(result==WAIT_OBJECT_0)

            break;

        GPIO_83_PullHigh(); 

        waitTime.usWait(pDlg->g_HighTimeA);

        GPIO_83_PullLow();

        waitTime.usWait(pDlg->g_LowTimeA);

    }

    GPIO_53_PullHigh();

    return 0;

}

UINT DCMotorThread(LPVOID param)//直流电机运行线程

{

    CMotorDlg *pDlg=(CMotorDlg*)param;

    ::WaitForSingleObject(pDlg->DCThreadBegin.m_hObject ,INFINITE);

    while(1)

    {

        int result=::WaitForSingleObject(pDlg->DCThreadEnd.m_hObject ,0);

        if(result==WAIT_OBJECT_0)

        {

            GPIO_82_PullHigh();

            GPIO_81_PullHigh();

            break;

        }

        if(pDlg->m_DCMotorPositive.GetCheck())

        {

            GPIO_82_PullLow();

            GPIO_81_PullHigh();

        }

        else

        {

            GPIO_81_PullLow();

            GPIO_82_PullHigh();

        }

        if(!pDlg->m_DCContinue.GetCheck())

        {

            Sleep(pDlg->m_DCRunTime);

            GPIO_82_PullHigh();

            GPIO_81_PullHigh();

            break;

        }

    }

    return 0;

}

CMotorDlg::CMotorDlg(CWnd* pParent /*=NULL*/)

    : CDialog(CMotorDlg::IDD, pParent)

    , m_DCRunTime(1000)

    , m_StepRunTime(1000)

    , m_RatioH(1)

    , m_RatioL(1)

{

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CMotorDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    DDX_Text(pDX, IDC_DCTime, m_DCRunTime);

    DDX_Text(pDX, IDC_StepTime, m_StepRunTime);

    DDX_Text(pDX, IDC_StepRatioH, m_RatioH);

    DDX_Text(pDX, IDC_StepRatioL, m_RatioL);

    DDX_Control(pDX, IDC_DcMotorContinue, m_DCContinue);

    DDX_Control(pDX, IDC_StepContinue, m_StepContinue);

    DDX_Control(pDX, IDC_DCMotorPositive,m_DCMotorPositive);

    DDX_Control(pDX, IDC_StepMotorPositive,m_StepMotorPositive);

}

BEGIN_MESSAGE_MAP(CMotorDlg, CDialog)

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)

    ON_WM_SIZE()

#endif

    //}}AFX_MSG_MAP

    ON_BN_CLICKED(IDC_StepMotorStart, &CMotorDlg::OnBnClickedStepmotorstart)

    ON_BN_CLICKED(IDC_StepMotorStop, &CMotorDlg::OnBnClickedStepmotorstop)

    ON_BN_CLICKED(IDC_DCMotorStart, &CMotorDlg::OnBnClickedDcmotorstart)

    ON_BN_CLICKED(IDC_DCMotorStop, &CMotorDlg::OnBnClickedDcmotorstop)

END_MESSAGE_MAP()

// CMotorDlg message handlers

BOOL CMotorDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically

    //  when the application's main window is not a dialog

    SetIcon(m_hIcon, TRUE);          // Set big icon

    SetIcon(m_hIcon, FALSE);     // Set small icon

    m_DCMotorPositive.SetCheck(1);

    m_StepMotorPositive.SetCheck(1);

    InitGPIO();

    // TODO: Add extra initialization here

   

    return TRUE;  // return TRUE  unless you set the focus to a control

}

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)

void CMotorDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)

{

    DRA::RelayoutDialog(

        AfxGetInstanceHandle(),

        this->m_hWnd,

        DRA::GetDisplayMode() != DRA::Portrait ?

            MAKEINTRESOURCE(IDD_MOTOR_DIALOG_WIDE) :

            MAKEINTRESOURCE(IDD_MOTOR_DIALOG));

}

#endif

BOOL CMotorDlg::InitGPIO(void)

{

    int retvalue;

//  DWORD threadID;

    retvalue=0;

    if(!v_pGPIOReg) //

    {

        if(!(v_pGPIOReg=(volatile GPIO_REGS *)VirtualAlloc(0,0x1000,MEM_RESERVE,PAGE_NOACCESS)))

        {          

            MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

             return FALSE;

        }

        else

        retvalue=VirtualCopy((PVOID)v_pGPIOReg,(PVOID)(GPIO_BASE_U_VIRTUAL>>8),0x1000,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);

        if(!retvalue)

        {

            VirtualFree((PVOID)v_pGPIOReg, 0, MEM_RELEASE);

            v_pGPIOReg = NULL;

            MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

            return FALSE;

        }

        else

        {

            //set GPIO pin direction

            v_pGPIOReg->GPDR_z |= GPIO_81;

            v_pGPIOReg->GPDR_z |= GPIO_82;

            v_pGPIOReg->GPDR_z |= GPIO_83;

            v_pGPIOReg->GPDR_z |= GPIO_84;

            v_pGPIOReg->GPDR_y |=GPIO_53;

            GPIO_84_PullLow();

            GPIO_83_PullLow();

           

            GPIO_81_PullHigh();

            GPIO_82_PullHigh(); 

            GPIO_53_PullHigh(); 

           

            return TRUE;

        }

    }

    return TRUE;

}

void CMotorDlg::OnBnClickedStepmotorstart()

{

    UpdateData(TRUE);

    g_HighTimeA=m_RatioH*StepBaseTime/(m_RatioH+m_RatioL);

    g_LowTimeA=m_RatioL*StepBaseTime/(m_RatioH+m_RatioL);

    AfxBeginThread(StepMotorThread,this);

    StepThreadBegin.SetEvent();

}

void CMotorDlg::OnBnClickedStepmotorstop()

{

    StepThreadEnd.SetEvent();

}

void CMotorDlg::OnBnClickedDcmotorstart()

{

    UpdateData(TRUE);

    AfxBeginThread(DCMotorThread,this);

    DCThreadBegin.SetEvent();

}

void CMotorDlg::OnBnClickedDcmotorstop()

{

    DCThreadEnd.SetEvent();

}

// Wait.cpp: implementation of the CWait class.

#include "stdafx.h"

#include "Motor.h"

#include "Wait.h"

#include "Motordef.h"

#include <pkfuncs.h>

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

#define PAGE_SIZE 0x1000

#define ALIGNMENT_MASK (PAGE_SIZE-1)

static volatile OST_REGS *ost;

CWait::CWait()

{

}

CWait::~CWait()

{

}

PVOID CWait::VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress)

{

    PVOID ptr;

    unsigned offset;

    offset = (unsigned)pVirtualAddress & ALIGNMENT_MASK;

    size +=offset ? PAGE_SIZE : 0;

    ptr = VirtualAlloc(0,size,MEM_RESERVE,PAGE_NOACCESS);

    if (ptr == NULL)

    {

        ERRORMSG(1,(TEXT("VirtualAlloc failed! %s : size=0x%x, (0x%x)\r\n"),str,size,GetLastError()));

        return(0);

    }

    if (!VirtualCopy((PVOID)ptr,(PVOID)((unsigned)pVirtualAddress - offset),size,PAGE_READWRITE|PAGE_NOCACHE))

    {

        ERRORMSG(1,(TEXT("VirtualCopy failed! %s : addr=0x%x, offset=0x%x(0x%x)\r\n"),str,(unsigned)pVirtualAddress,offset,GetLastError()));

        return(0);

    }

    return((PVOID)((PBYTE)ptr+offset));

}

PVOID CWait::VirtualAllocCopyPhysical(unsigned size, char *str, PVOID pPhysicalAddress)

{

    PVOID ptr;

    unsigned offset;

    offset = (unsigned)pPhysicalAddress & ALIGNMENT_MASK;

    size +=offset ? PAGE_SIZE : 0;

    ptr = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);

    if (ptr == NULL)

    {

        ERRORMSG(1,(TEXT("VirtualAllocCopyPhysical failed! %s : size=0x%x, (0x%x)\r\n"),str,size,GetLastError()));

        return(0);

    }

    if (!VirtualCopy((PVOID)ptr, (PVOID)(((unsigned)pPhysicalAddress - offset) >> 8), size, PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))

    {

        ERRORMSG(1,(TEXT("VirtualCopyCopyPhysical failed! %s : addr=0x%x, offset=0x%x(0x%x)\r\n"),str,(unsigned)pPhysicalAddress,offset,GetLastError()));

        return(0);

    }

    return((PVOID)((PBYTE)ptr+offset));

}

void CWait::usWait(unsigned int usVal)

{

    unsigned Start;

    static unsigned firstCall=1;

    if (firstCall)

    {

        ost = (volatile OST_REGS*)VirtualAllocCopyPhysical(0x80,"Wait OST",(PVOID)(OST_BASE_PHYSICAL));

        if (!ost)

        {

            RETAILMSG(TRUE, (TEXT("usWait: Map OST register failed\r\n")));

            return;

        }

        firstCall=0;

    }

    if (usVal != 0)

    {

        Start = ost->oscr;

        while ((ost->oscr - Start) < usVal * TIMERTICK)

        {

            // do nothing

        }

    }

}

void CWait::msWait(unsigned msVal)

{

    usWait(msVal*1000);

}

void CWait::sWait(unsigned sVal)

{

    msWait(sVal*1000);

}

二、代码分析

、程序实现分析

(1)、寄存器结构体定义

#define GPIO_81 ( 1u << 17 )

#define GPIO_82 ( 1u << 18 )

#define GPIO_83 ( 1u << 19 ) //0x00080000

#define GPIO_84 ( 1u << 20 ) //0x00100000

#define GPIO_53 ( 1u << 21 )

#define GPIO_BASE_U_VIRTUAL 0x40E00000 // GPIO Virtual Base address

// GPIO definition start

typedef struct {

unsigned int GPLR_x; // 0x40E00000 Pin Level Registers

unsigned int GPLR_y; // 0x40E00004

unsigned int GPLR_z; // 0x40E00008

unsigned int GPDR_x; // 0x40E0000C Pin Direction Registers

unsigned int GPDR_y; // 0x40E00010

unsigned int GPDR_z; // 0x40E00014

unsigned int GPSR_x; // 0x40E00018 Pin Output Set Registers

unsigned int GPSR_y; // 0x40E0001C

unsigned int GPSR_z; // 0x40E00020

unsigned int GPCR_x; // 0x40E00024 Pin Output Clear Registers

unsigned int GPCR_y; // 0x40E00028

unsigned int GPCR_z; // 0x40E0002C

unsigned int GRER_x; // 0x40E00030 Rising Edge Detect Enable Registers

unsigned int GRER_y; // 0x40E00034

unsigned int GRER_z; // 0x40E00038

unsigned int GFER_x; // 0x40E0003C Falling Edge Detect Enable Registers

unsigned int GFER_y; // 0x40E00040

unsigned int GFER_z; // 0x40E00044

unsigned int GEDR_x; // 0x40E00048 Edge Detect Status Registers

unsigned int GEDR_y; // 0x40E0004C

unsigned int GEDR_z; // 0x40E00050

unsigned int GAFR0_x; // 0x40E00054 Alternate Function Registers

unsigned int GAFR1_x; // 0x40E00058

unsigned int GAFR0_y; // 0x40E0005C

unsigned int GAFR1_y; // 0x40E00060

unsigned int GAFR0_z; // 0x40E00064

unsigned int GAFR1_z; // 0x40E00068

} GPIO_REGS, *PGPIO_REGS

(2)、GPIO 控制的宏定义

#define GPIO_81_PullHigh() v_pGPIOReg->GPSR_z|=GPIO_81 //用于直流电机

#define GPIO_81_PullLow() v_pGPIOReg->GPCR_z|=GPIO_81

#define GPIO_82_PullHigh() v_pGPIOReg->GPSR_z|=GPIO_82 //用于直流电机

#define GPIO_82_PullLow() v_pGPIOReg->GPCR_z|=GPIO_82

#define GPIO_83_PullHigh() v_pGPIOReg->GPSR_z|=GPIO_83 //用于产生步进电机脉冲

#define GPIO_83_PullLow() v_pGPIOReg->GPCR_z|=GPIO_83

#define GPIO_84_PullHigh() v_pGPIOReg->GPSR_z|=GPIO_84 //用于控制步进电机方向

#define GPIO_84_PullLow() v_pGPIOReg->GPCR_z|=GPIO_84

#define GPIO_53_PullHigh() v_pGPIOReg->GPSR_y|=GPIO_53 //用于步进电机输出使能

#define GPIO_53_PullLow() v_pGPIOReg->GPCR_y|=GPIO_53

(3)、GPIO 初始化函数

BOOL CMotorDlg::InitGPIO()

{

int retvalue;

retvalue=0;

if(!v_pGPIOReg){

if(!(v_pGPIOReg=(volatile GPIO_REGS

*)VirtualAlloc(0,0x1000,MEM_RESERVE,PAGE_NOACCESS)))

{

MessageBox(TEXT("VirtualAlloc() failed!\r\n"),NULL,MB_OK);

return FALSE;

}

else

retvalue=VirtualCopy((PVOID)v_pGPIOReg,(PVOID)(GPIO_BASE_U_VIRTUAL>>8),0x

1000,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);

if(!retvalue) {

VirtualFree((PVOID)v_pGPIOReg, 0, MEM_RELEASE);

v_pGPIOReg = NULL;

MessageBox(TEXT("VirtualCopy() failed!\r\n"),NULL,MB_OK);

return FALSE;

}

else

{

//set GPIO pin direction

v_pGPIOReg->GPDR_z |= GPIO_81;

v_pGPIOReg->GPDR_z |= GPIO_82;

v_pGPIOReg->GPDR_z |= GPIO_83;

v_pGPIOReg->GPDR_z |= GPIO_84;

v_pGPIOReg->GPDR_y |=GPIO_53;

g_uPWMRunTimes=0xFFFFFFFF;

g_DCERunTime=1000;

g_Positive=0xFFFFFFFF;

GPIO_84_PullLow();

GPIO_83_PullLow();

GPIO_81_PullHigh();

GPIO_82_PullHigh();

GPIO_53_PullHigh();

return TRUE;

}

}

return TRUE;

}

(4)、控制步进电机运转线程

6

DWORD WINAPI CMotorDlg::StepMotorThread(LPVOID lpParam) //步进电机驱动

{ CMotorDlg *pDlg=(CMotorDlg*)lpParam;

CWait waitTime;

while(1) {

if(WaitForSingleObject(pDlg->g_hPWMOpenEvent, INFINITE) ==WAIT_OBJECT_0)

{

GPIO_53_PullLow();// Step Motor Power on

if(pDlg->g_ZLDJPositive)

GPIO_84_PullLow();

else

GPIO_84_PullHigh();

while(pDlg->g_uPWMRunTimes)

{

if(pDlg->g_uPWMRunTimes!=0xFFFFFFFF)

pDlg->g_uPWMRunTimes--;

GPIO_83_PullHigh();

waitTime.usWait(pDlg->g_HighTimeA);

GPIO_83_PullLow();

waitTime.usWait(pDlg->g_LowTimeA);

}

GPIO_84_PullLow();

}

GPIO_53_PullHigh();

}

return 0;

}

(5)、直流电机控制函数

void CMotorDlg::OnDCMotorStart()

{

CWait wait;

//SetEvent(g_hDCEOpenEvent);

UpdateData(TRUE);

if(m_DCMotorDir) //Positive Run

{

GPIO_81_PullLow();

GPIO_82_PullHigh();

if(!m_DCContinue.GetCheck()){ //定时运行

Sleep(m_DCRunTime);//

//wait.msWait(m_DCRunTime);

GPIO_81_PullHigh();

GPIO_82_PullHigh();

}

}

else

{

GPIO_81_PullHigh();

GPIO_82_PullLow();

if(!m_DCContinue.GetCheck())//定时运行

{ Sleep(m_DCRunTime);

//wait.msWait(m_DCRunTime);

GPIO_81_PullHigh();

GPIO_82_PullHigh();

}

}

三、执行界面

六、课程设计小结

  嵌入式系统在很多产业中得到了广泛的应用并逐步改变着这些产业,包括工业自动化、国防、运输和航天领域。例如神州飞船和长征火箭中肯定有很多嵌入式系统,导弹的制导系统也是嵌入式系统,高档汽车中也有多达几十个嵌入式系统。在日常生活中,人们使用各种嵌入式系统,但未必知道它们。事实上,几乎所有带有一点“智能”的家电都是嵌入式系统。嵌入式系统广泛的适应能力和多样性,使得视听、工作场所甚至健身设备中到处都有嵌入式系统。Windows CE是微软开发的一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作,它是精简的Windows 95。Windows CE的图形用户界面相当出色。Win CE具有模块化、结构化和基于Win32应用程序接口以及与处理器无关等特点。Win CE不仅继承了传统的Windows图形界面,并且在Win CE平台上可以使用Windows 95/98上的编程工具,使绝大多数的应用软件只需简单的修改和移植就可以在Windows CE平台上继续使用。两周的时间,基本完成了嵌入式操作系统WinCE的移植及应用个程序设计相对于以前我们编写的程序,这个程序似乎稍微大了一些,做的的结果也不是十分的理想,程序的执行方面也不是如意,还需要改进,在老师的指导及同学的互相商讨下,经过我一次一次的尝试,最终基本达到了预期的效果,但还有不足的的地方。第一次这种规模的程序设计,由于时间短,有许多程序没有弄懂,还不是十分完善,希望能通过以后的学习是的程序更加的健壮、完善。通过这次实习让我对嵌入式有了进一步的了解,以前只停留在写十几行小程序的基础上,做一点简单功能的程序,对它的一些嵌入式只是略知皮毛,经过这学期学习也只是停留在理论上,此次实习让我受益匪浅,这次提高了我们的动动脑能力,大学生缺乏动手实践的能力,对于大学生来说书本知识固然重要但是实践绝对是其大学生活、学习中不可或缺的一部分。

更多相关推荐:
嵌入式课程设计报告

福建工程学院嵌入式系统课程设计报告书题目基于S3C2440设备驱动及其界面设计班级姓名学号指导老师陈靖张平均李光炀2目录一设计课题4二设计目的4三设计任务及要求4四设计内容5五操作界面的生成7六操作界面调试9七...

嵌入式课程设计报告

福州大学课程设计任务书课程嵌入式课程设计题目姓名李仁煌学号011000610系别电机电器专业电气工程与自动化年级20xx起讫日期20xx61020xx74指导教师王武目录1课程设计目的22课程设计题目和实现目标...

嵌入式系统课程设计报告

嵌入式系统课程设计报告基于ARM的楼宇对讲系统设计摘要采用模块化设计方法设计出一款基于ARM微控制芯片和Linux操作系统的楼宇对讲系统,该对讲系统通过以太网与楼宇间的各室内机相连,实现了安装在楼道门口的终端机…

嵌入式课程设计报告

嵌入式系统开发课程设计专周报告题目:具有日历功能的电子时钟系别及专业:计算机工程系计算机应用技术班级:10511学生姓名:XXX指导老师:XX完成时间:20XX-12-24/20XX-12-28目录前言....…

嵌入式课程设计报告

课程设计综合实验报告20xx20xx年度第1学期名称题目院系班级学号学生姓名指导教师设计周数成绩日期年月日一课程设计的目的与要求11目的掌握嵌入式系统的基本原理及其基于COSII操作系统的实现方法本次设计使用A...

嵌入式系统课程设计实验报告

7嵌入式系统课程设计必做部分学院电控学院专业通信工程设计名称IIC同步串行通讯1设计的目的1掌握S3C44B0IIC控制器的编程方法2编程实现串行EEPROM存储器24C16的数据存储和访问2设计的内容1学习S...

嵌入式课程设计报告

中南大学嵌入式课程设计基于ARM平台的打地鼠游戏姓名董嘉伟学号0909103303班级物联网1002时间20xx913目录课程设计内容课程设计实验环境课程设计原理分析课程设计开发计划课程设计系统设计图课程设计关...

嵌入式课程设计报告

嵌入式课程设计报告班级自动化学号姓名分工程序编写程序调试程序流程设计及报告20xx年8月目录摘要3关键字3一课程设计目的4二课题设计功能4LED数码管驱动程序4三模块介绍与使用手册51开发工具介绍52开发语言5...

嵌入式系统课程设计报告

课程设计报告电子点菜器设计报告班学姓级号名20xx061420xx061411刘群峰20xx年9月1题目电子点菜器2系统简介本次课程设计的系统是电子点菜器它运行的环境是博创UPNETARM3000实验台主要使用...

嵌入式系统课程设计报告

昆明理工大学嵌入式系统设计报告指导老师设计者专业班级20xx学号20xx704126时间20xx许江淳肖智斌级计算机技术年7月1LED灯显示一设计目的1熟悉arm开发板基本组成电路并熟悉arm芯片特性了解ADS...

嵌入式课程设计报告

通信与信息工程学院嵌入式开发技术课程设计报告班级姓名学号指导教师设计时间成绩评20xx年1月11日20xx年1月14日通信与信息工程学院二一六年嵌入式开发技术课程设计报告目录嵌入式课程设计11设计要求111基本...

嵌入式课程设计报告

嵌入式课程设计报告基于WINCE下黑白棋的设计嵌入式系统课程设计报告课程设计目的1通过前期的嵌入式系统的学习和实验对S3C2440嵌入式系统的开发通过寄存器的设置操作硬件模块以及操作系统的移植有了初步的了解通过...

嵌入式课程设计报告(44篇)