嵌入式系统课程设计报告

             昆明理工大学

嵌入式系统设计报告

                                                             

指导老师          许江淳           

设计者      肖智斌    

专业班级      2013级计算机技术    

学   号         2013704126        

时  间          2014年7月         

      

   LED灯显示

一.     设计目的

1.  熟悉arm开发板基本组成电路并熟悉arm芯片特性。了解ADS1.2软件使用,并会用该软件编译调试开发板。

2.  了解H—JTAG软件原理。

二.     器材

PC机一台,周立功开发板一块。

注意:对LPC2103管脚的寄存器进行配置时,应该对照芯片说明手册,按照索引,找到相关寄存器,对其进行配置。

三.设计原理

    EasyARM2103开发板提供了4个绿色发光二极管用作显示,电路如图1.1所示。显示电路采用了灌电流的方式来驱动发光二极管,由于微控制器LPC2103 I/O口提供的灌电流大于其拉电流,采用此驱动方式可以保证二极管发光的亮度。

图1.1  LED电路原理

四.     设计内容及步骤

1.  下面以GPIO的测试程序为例,熟悉EasyJTAG-H软件的使用方法,程序功能设计为控制单路LED闪烁,硬件电路如图1.1所示。

2.  打开示例工程。示例工程路径:配套光盘内容->光盘内容v1.00->3.EasyARM2103安装手册->GPIO Test,将此文件夹复制到其它目录下打开,要求存放目录必须无中文路径。打开文件夹后,建议用户先删掉“GPIO_Test_Data”文件夹,然后双击打开“GPIO Test.mcp”文件,即打开示例工程。

3.  点击“user”文件夹,打开main.c文件,见到示例代码。

4.  选择低速GPIO,控制LED灯闪烁,示例程序如程序清单所示。此示例操作需要短接JP4的P0.17,输出控制LED1。

5.  编译连接工程。项目目标栏处选择DebugInFlash模式,然后编译连接工程。

6.  仿真调试 。将计算机并口与Easy JTAG-H仿真器相连,然后再将Easy JTAG-H仿真器的JTAG接口连接到Easy ARM2103目标板上,打开H-JTAG,检测到芯片内核信息后,选择Auto Download选项,此时会自动启动H-Flasher软件,选择目标芯片的型号,将当前的配置信息保存起来,建议将配置信息保存到安装路径下的Hconfig文件夹内。

7.  设置完成后,关闭H-JTAG Server和H-Flasher(注意:不能使用Exit项关闭)。启动AXD,打开【Options】->【Configure Target...】,弹出Choose Target窗口,点击“ADD”添加仿真器的驱动程序,在添加文件窗口选择如D:\Program Files\H-JTAG 目录下的H-JTAG .dll,点击“打开”即可。

8.  在AXD环境点击运行,即可看到led亮。

附加:编写程序实现四个LED灯循环闪烁的功能。

五.  程序及结果

1. 一个led灯亮的源代码如下:

#include "config.h"

# define    LED1    1 << 17    /*  P0.17控制LED1    */

/************************************************************

** Function name:             DelayNS

** Descriptions:          延时函数

** input parameters:    uiDly   值越大,延时时间越长

** output parameters:   无

** Returned value:      无

************************************************************/

void DelayNS (uint32 uiDly)

{   uint32 i;

    for (; uiDly > 0; uiDly--){

        for(i = 0; i < 50000; i++);

    }

}

/************************************************************

** Function name:             main

** Descriptions:          跳线JP4短接,LED1闪烁

** input parameters:    无

** output parameters:   无

** Returned value:      无

************************************************************/

int main (void)

{ PINSEL1 = PINSEL1 & (~(0x03 << 2));    /*  将P0.17设置为GPIO   */

    IO0DIR  = LED1;                /* 设置LED控制口为输出  */

    IO0SET  = LED1;             /*  LED1熄灭  */

    while (1) {

        IO0SET = LED1;          /*  LED1熄灭   */

        DelayNS(50);            /*  延时       */

        IO0CLR = LED1;          /*  LED1点亮   */

        DelayNS(50);           /*  延时       */

    }

    return 0;

}

/********************     End Of File      *********************/

运行程序后,可以看到第一个LED灯亮。

2. 四个LED灯循环闪烁的源代码如下:

#include "config.h"

# define    LED1    1 << 17       /*  P0.17控制LED1   */

# define       LED2      1 << 18       /*  P0.18控制LED2   */

# define       LED3      1 << 19       /*  P0.19控制LED3   */

# define     LED4     1 << 20       /*  P0.20控制LED4   */

void DelayNS (uint32 uiDly)

{   uint32 i;

    for (; uiDly > 0; uiDly--){ for(i = 0; i < 50000; i++);  }

}

int main (void)

{   PINSEL1 = PINSEL1 & (~(0x03 << 2));    /*  将P0.17设置为GPIO     */

     PINSEL1 = PINSEL1 & 0x0FFFFFFE7;    /*  将P0.18设置为GPIO     */

     PINSEL1 = PINSEL1 & 0x0FFFFFF9F;    /*  将P0.19设置为GPIO     */

     PINSEL1 = PINSEL1 & 0x0FFFFFE7F;    /*  将P0.20设置为GPIO     */

    while (1) {

    IO0DIR  = LED1;                                                       

IO0SET = LED1;           /*  LED1熄灭                    */

    DelayNS(50);         /*  延时                        */

    IO0CLR = LED1;      /*  LED1点亮                    */

    DelayNS(50);

IO0DIR  = LED2;      /*  LED2熄灭 、延时、点亮、延时     */  

IO0SET = LED2;                                                  

DelayNS(50);                                                   

IO0CLR = LED2;                                                

DelayNS(50);

       

IO0DIR  = LED3;    /*  LED3熄灭 、延时、点亮、延时     */       

IO0SET = LED3;                                                  

DelayNS(50);                                                   

IO0CLR = LED3;                                                

DelayNS(50);

       

IO0DIR  = LED4;   /*  LED4熄灭 、延时、点亮、延时     */        

IO0SET = LED4;                                                 

DelayNS(50);                                                   

IO0CLR = LED4;                                                

DelayNS(50);                                                   

 }

      return 0;

}

/**************        End Of File        ***************/

运行程序后,可看到四个LED一个接一个的亮,实现了跑马灯的功能。

 中断

一.     设计目的

1.  熟悉arm开发板中断原理。并产生中断。

2.  了解快速中断和普通中断。编写嵌套中断实验。

二.     器材

PC机一台,周立功开发板一块

三.设计原理

同设计一

四.     设计内容及步骤

参照设计一中步骤1-8。

附加:1. 编写程序实现三个按钮分别控制三个LED灯亮灭的功能。

2. 自行编写一段实现中断嵌套的程序,阐明嵌套过程。

五. 程序及结果

1.一个按钮控制一个LED灯亮灭的源代码

#include "config.h"

#define   LED    1 << 17

/***************************************************************

** Function name:       Eint0IRQ

** Descriptions:        外部中断0服务程序

** input parameters:    无

** ouput parameters:    无

** Returned value:      无

***************************************************************/

void __irq Eint0IRQ(void)                     /*  进入中断取反LED   */

{   if ((IO0PIN & (1 << 17)) == 0) {                                       

        IO0SET = 1 << 17;         /*  熄灭发光二极管   */

      }

   else {

        IO0CLR = 1 << 17;         /*  点亮发光二极管    */

       }

   while((IO0PIN & (1 << 16)) == 0);   /*  等待按键松开   */

   EXTINT = 0x01;                /*  清中断标志    */

   VICVectAddr = 0x00;         /*  通知VIC中断处理结束*/

}

/***************************************************************

** Function name:       main

** Descriptions:        P0.16低电平触发外部中断主函数

** input parameters:    无

** ouput parameters:    无

** Returned value:      无

**************************************************************/

int main (void)

{

    PINSEL1 = PINSEL1 & (~0x03);

    PINSEL1 = PINSEL1 | 0x01;     /*  设置P0.16为外部中断0管脚    */

    INSEL1 = PINSEL1 & (~(0x03 << 2));  /*  设置P0.17为GPIO功能    */

    IO0DIR  = LED;             /*  设置P0.17为输出     */

    IO0SET  = LED;           /*  设置输出为高电平   */

    IRQEnable();             /*  IRQ中断使能       */

    EXTMODE  = 0x00;      /*  设置外部中断为低电平触发    */

    EXTPOLAR = 0x00;

    VICIntSelect = 0 << 14;   /*  选择EINT0为IRQ中断          */

    VICVectCntl0 = 0x20 | 14; /*  将外部中断0分配给向量中断0  */

    VICVectAddr0 = (uint32)Eint0IRQ; /*  设置中断服务程序地址   */

    VICIntEnable = 1 << 14;        /*  使能EINT0中断     */

    EXTINT = 0x01;              /*  清除EINT0中断标志     */

    while(1);

    return 0;

}

运行程序后,按下按钮,LED灯亮;再按一次,灯灭;再按一次,灯亮;再按一次,灯灭;如此循环。

2. 三个按钮分别控制三个LED灯亮灭的源代码

#include "config.h"

#define   LED1    1 << 17

#define   LED2    1 << 18

#define   LED3    1 << 19

void __irq Eint0IRQ(void)                                         /*进入中断取反LED */

{   if ((IO0PIN & (1 << 17)) == 0) { IO0SET = 1 << 17;  } /* 熄灭发光二极管*/

    else {   IO0CLR = 1 << 17;    }                     /*  点亮发光二极管  */

    while((EXTINT & 0x01)!= 0){ EXTINT = 0x01; } /* 按键松开清中断标志*/

    VICVectAddr = 0x00;                                         /*通知VIC中断处理结束*/

}

void __irq Eint1IRQ(void)                                         /*进入中断取反LED */

{ if ((IO0PIN & (1 << 18)) == 0) { IO0SET = 1 << 18; }  /* 熄灭发光二极管 */

    else { IO0CLR = 1 << 18;    }                          /*  点亮发光二极管  */

   while((EXTINT & 0x02)!= 0){  EXTINT = 0x02;} /* 按键松开清中断标志*/

   VICVectAddr = 0x00;                                           /*通知VIC中断处理结束*/

}

void __irq Eint2IRQ(void)                                          /*进入中断取反LED */

{  if ((IO0PIN & (1 << 19)) == 0) { IO0SET = 1 << 19; }  /*熄灭发光二极管 */

    else { IO0CLR = 1 << 19;    }                           /* 点亮发光二极管 */

   while((EXTINT & 0x04)!= 0){  EXTINT = 0x04;}  /*按键松开清中断标志*/

   VICVectAddr = 0x00;                                           /*通知VIC中断处理结束*/

}

int main (void)

{   PINSEL1 = PINSEL1 & (~0x03);

    PINSEL1 = PINSEL1 | 0x01;                  /* 设置P0.16为外部中断0管脚 */

    PINSEL0 = PINSEL0 & (~(0x03 << 30));

    PINSEL0 = PINSEL0 | ( 0x01 << 30);  /* 设置P0.15为外部中断2管脚 */

    PINSEL0 = PINSEL0 & (~(0x03<<28));

    PINSEL0 = PINSEL0 | (0x01<<28);    /* 设置P0.14为外部中断1管脚 */

    PINSEL1 = PINSEL1 & (~(0x03 << 2));   /*  设置P0.17为GPIO功能  */

    PINSEL1 = PINSEL1 & (~(0x03 << 4));  /*  设置P0.18为GPIO功能  */

    PINSEL1 = PINSEL1 & (~(0x03 << 6));  /*  设置P0.19为GPIO功能  */

IO0DIR  = LED1|LED2|LED3;

    IO0SET  = LED1|LED2|LED3;

    IRQEnable();                           /*  IRQ中断使能  */

    EXTMODE  = 0x00;              /*  设置外部中断为低电平触发  */

    EXTPOLAR = 0x00;

    VICIntSelect = 0x00;        /* 选择EINT0,EINT1,EINT2为IRQ中断  */

    VICVectCntl0 = 0x20 | 14;   /*  将外部中断0分配给向量中断0  */

      VICVectCntl1 = 0x20 | 15   /*  将外部中断1分配给向量中断1  */

    VICVectCntl2 = 0x20 | 16;   /*  将外部中断2分配给向量中断2  */

   

    VICVectAddr0 = (uint32)Eint0IRQ;  /* 设置中断服务程序地址 */

    VICVectAddr0 = (uint32)Eint1IRQ;

    VICVectAddr2 = (uint32)Eint2IRQ;

   

 VICIntEnable = (1 << 14) | (1<<15)| (1<<16); /*使能EINT0,EINT1,EINT2中断 */

 EXTINT = 0x07;                                          /*  清除EINT0中断标志 */

 while(1);

 return 0;

}

/**********************     END FILE    ***********************/

运行程序,可以实现三个按钮分别控制三个LED灯亮灭的功能。

UART接口设计

一.    设计目的

掌握UARTO各控制器的设置,并能使用URTO接收PC机发过来的数据,并将数据送回PC进行显示。

二.    器材

PC机一台,周立功开发板一块

三.    设计内容

1.采用中断方式,通过UART0接收上位机发送的字符串,如“Hello EasyARM2103!”,然后送回上位机终端EasyARM-C.exe的数据接收窗口进行显示。

2.UART0设置为通讯波特率115200,8位数据位,1位停止位,无奇偶校验。

3.UART0的通信实验需要短接JP6的P0.0和P0.1引脚

四.    实施步骤

软件设置与调试同设计一和二基本一致,但硬件连线方面需注意:

1.将EasyARM2103教学实验开发平台上的JP6跳线短接

2. 使用串口延长线把EasyARM2103教学实验开发平台的UART0接口与PC机的COM1连接。PC机运行EasyARM软件,设置串口为COM1,波特率为115200,然后选择【设置】->【发送数据】,在弹出的发送数据窗口中点击“高级”即可打开接收窗口。

五.    源程序及运行结果

/******************************************************************************

#include "config.h"

# define    UART_BPS    115200                      /*  串口通信波特率              */

volatile    uint8 uiGRcvNew;                           /*  串口接收新数据的标志        */

uint8       uiGRcvBuf[30] = {0};                       /*  串口接收数据缓冲区          */

uint32      uiGNum;                                  /*  串口接收数据的个数          */

/******************************************************************************

** 函数名称:            DelayNS

** 函数功能:            延时函数

** 入口参数:       uiDly   值越大,延时时间越长

** 出口参数:       无

** 返回值:         无

*****************************************************************************************/

void DelayNS (uint32 uiDly)

{

    uint32 i;

   

    for (; uiDly > 0; uiDly--){

        for(i = 0; i < 50000; i++);

    }

}

/*****************************************************************************************

** 函数名称:         UART0_IRQ

** 函数功能:           串口中断服务函数

** 入口参数:       无

** 出口参数:       无

** 返回值:         无

*****************************************************************************************/

void __irq UART0_IRQ (void)

{

    uiGNum = 0;

      

    while ((U0IIR & 0x01) == 0){                             /*  判断是否有中断挂起     */

        switch (U0IIR & 0x0E){                              /*  判断中断标志           */

       

            case 0x04:                                     /*  接收数据中断           */

                uiGRcvNew = 1;                            /*  置接收新数据标志       */

                for (uiGNum = 0; uiGNum < 8; uiGNum++){     /*  连续接收8个字节        */

                uiGRcvBuf[uiGNum] = U0RBR;

                }

                break;

           

            case 0x0C:                                    /*  字符超时中断            */

                uiGRcvNew = 1;

                while ((U0LSR & 0x01) == 0x01){            /*  判断数据是否接收完毕    */

                    uiGRcvBuf[uiGNum] = U0RBR;

                    uiGNum++;

                }

                break;

               

            default:

                break;

        }

    }

  

   VICVectAddr = 0x00;

  

}

/*****************************************************************************************

** 函数名称:            UARTInit

** 函数功能:            串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为115200

** 入口参数:       uiDly   值越大,延时时间越长

** 出口参数:       无

** 返回值:         无

*****************************************************************************************/

void UARTInit (void)

{

    uint16 uiFdiv;

   

    U0LCR  = 0x83;                                  /*  允许设置波特率              */

    uiFdiv = (Fpclk / 16) / UART_BPS;                    /*  设置波特率                  */

    U0DLM  = uiFdiv / 256;

    U0DLL  = uiFdiv % 256;

    U0LCR  = 0x03;                                  /*  锁定波特率                  */

}

/*****************************************************************************************

** 函数名称:         UART0SendByte

** 函数功能:            向串口发送子节数据,并等待数据发送完成,使用查询方式

** 入口参数:       uiDat   要发送的数据

** 出口参数:       无

** 返回值:         无

*****************************************************************************************/

void UART0SendByte (uint8 uiDat)

{

    U0THR = uiDat;                                   /*  写入数据                    */

    while ((U0LSR & 0x20) == 0);                       /*  等待数据发送完毕            */

}

/*****************************************************************************************

** 函数名称:         UART0SendStr

** 函数功能:         向串口发送字符串

** 入口参数:       uiStr   要发送的字符串指针

**                  uiNum   要发送的数据个数

** 出口参数:       无

** 返回值:         无

*****************************************************************************************/

void UART0SendStr(uint8 const *uiStr, uint32 uiNum)

{

    uint32 i;

   

    for (i = 0; i < uiNum; i++){                               /*  发送指定个字节数据      */

        UART0SendByte (*uiStr++);

    }

}

/*****************************************************************************************

** 函数名称:           main

** 函数功能:            跳线JP6短接,打开串口调试软件,串口0中断方式通信

** 入口参数:       无

** 出口参数:       无

** 返回值:         无

*********************************************************************************************************/

int main (void)

{

   

    PINSEL0 = PINSEL0 & (~0x0F);                                       

    PINSEL0 = PINSEL0 | 0x05;                        /*  设置I/O连接到UART           */

   

    uiGRcvNew = 0;

    UARTInit ();                                    /*  串口初始化                    */

    U0FCR = 0x81;                                  /*  使能FIFO,设置8个字节触发点  */

    U0IER = 0x01;                                  /*  使能接收中断                  */

   

    IRQEnable ();

   

    VICIntSelect = 0x00000000;                       /*  设置所有中断为向量中断        */

    VICVectCntl0 = 0x20 | 0x06;                      /*  设置串口中断为最高优先级      */

    VICVectAddr0 = (uint32)UART0_IRQ;              /*  设置向量地址                  */

    VICIntEnable = 1 << 0x06;                        /*  使能串口中断                  */

   

    while (1){

        if (uiGRcvNew == 1){                        /*  判断是否有新数据              */

            uiGRcvNew = 0;                         /*  清除标志                     */

            UART0SendStr (uiGRcvBuf, uiGNum);       /*  向串口发送数据               */

        }

    }

    return 0;

}

/******************************************************************************

运行程序后可用PC机上的软件观测数据的收发情况

数字时钟的设计

设计目的

利用protues的模拟数字时钟的运行,主要使用芯片有:LPC2103、74HC573、led灯

硬件连接图:

源程序代码:

#include <LPC2103.H>

typedef            void    (*CPU_FNCT_VOID)(void);

#define Fosc            11059200

#define Fcclk           (Fosc * 4)

#define Fcco            (Fcclk * 4)

#define Fpclk           (Fcclk / 4) * 1

typedef unsigned char  uint8;

typedef unsigned short uint16;

typedef unsigned int   uint32;

uint8  Select[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};    //led灯选通信号

uint8  LED_CODES[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};    //0-f

uint8  miao   = 0;        //

uint8  fen = 0;                    //

uint8  shi = 0;                     //

uint8  times=0;

void delay(uint32 x)

{

       uint32 i,j;

       for(i=0;i<x;i++)

              for(j=0;j<1000;j++);

}

void timer0_ISR (void)

{    

       times++   ;

       if(times==10)

       {

       times=0;

       miao++;

       if(miao==60)

       {

              fen++;

              miao=0;

              if(fen==60)

              {

                     shi++;

                     fen=0;

              }

       }

       }

    T0IR = 1;                            //清除定时器0中断

      VICVectAddr = 0;                    //清除向量中断地址寄存器 

}

void IRQ_Exception(void)

{

       CPU_FNCT_VOID  pfnct;

       pfnct = (CPU_FNCT_VOID)VICVectAddr;        //返回最高优先级向量地址

       if (pfnct != (CPU_FNCT_VOID)0)                   //   确保不是错误的指针   

       {                                 

            (*pfnct)();                    //这句能关联到中断

       }   

}

void timer0Init (void)

{

       T0TC  = 0;

       T0PR  = 0;

    T0MR0 = 119999;                        //匹配寄存器,120000-1,12000000为1秒

    T0MCR = 3;                             //产生中断,重置TC

    T0TCR = 3;

       T0TCR = 1;                             //使能定时计数器

       VICIntSelect=0;                                               //初始为IRQ中断

    VICVectAddr0 = (uint32)timer0_ISR;       

    VICVectCntl0 = 0x20 | 4;               //定时器计数器0为4号中断,设为最高优先级

    VICIntEnable = 0x00000010;              //开定时计数器0中断

}

void display_led(uint8 x,uint8 y)

{

                     uint32 data;

                     IO0CLR |= (1<<25);

                     data = Select[x];     //片选

                     IO0PIN = (IO0PIN & 0x0000ffff) | (data << 16);

                     IO0SET |= (1<<25);

                     IO0CLR |= (1<<25);

                     IO0CLR |= (1<<24);

                     data = LED_CODES[y];       //显示

                     IO0PIN = (IO0PIN & 0x0000ffff) | (data << 16);

                     IO0SET |= (1<<24);

                     IO0CLR |= (1<<24);

}

int  main(void)

{

       uint8 miao_low;

       uint8 miao_high;

       uint8 fen_low;

       uint8 fen_high;

       uint8 shi_low;

       uint8 shi_high;

      

       PINSEL1 &= 0x00000000;                       //p16-p31 as gpio

       IO0DIR  |= 0xffff0000;                            //p16-p31 as out

       IO0PIN  |= 0xffff0000;                                   //初始化IO口

       timer0Init();

       while(1)

       {       

                     miao_low = miao%10;

                     miao_high = miao/10;

                     fen_low = fen%10;

                     fen_high = fen/10;

                     shi_low = shi%10;

                     shi_high = shi/10;

                  display_led(0,miao_low);

                     delay(30);

                  display_led(1,miao_high);

                     delay(30);

                  display_led(2,fen_low);

                     delay(30);

                  display_led(3,fen_high);

                     delay(30);

                  display_led(4,shi_low);

                     delay(30);

                  display_led(5,shi_high);

                     delay(30);

       }

}

相关推荐