热门搜索 :
考研考公
您的当前位置:首页正文

嵌入式系统课程设计报告

来源:东饰资讯网


中南大学

嵌入式系统

实验设计报告

指导老师 吴志虎、李志民 设计者 连金涛 专业班级 测控0801班 学 号 0909081012 时 间 2011年6月

1

实验一 LED灯显示实验

一. 实验目的

1. 熟悉arm开发板基本组成电路,并通过配套教材熟悉arm芯片特性。了

解ADS1.2软件使用,并会用该软件编译调试开发板。

2. 了解H—JTAG软件原理,利用教材中提供的LED测试程序,完成实验。 二. 实验器材

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。

2

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) {

3

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);

4

*/ */ */ */

}

IO0DIR = LED4; /* LED4熄灭 、延时、点亮、延时 */ IO0SET = LED4; DelayNS(50); IO0CLR = LED4; DelayNS(50); }

return 0;

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

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

5

实验二 中断实验

一. 实验目的

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: 无

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

6

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中断处理结束*/ }

7

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灯亮灭的功能。

8

实验三 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 值越大,延时时间越长 ** 出口参数: 无

9

实验源程序及运行结果

** 返回值: 无

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

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){ /* 判断数据是否接收完

10

毕 */

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 要发送的数据

11

** 出口参数: 无 ** 返回值: 无

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

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) {

12

PINSEL0 = PINSEL0 & (~0x0F);

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

uiGRcvNew = 0;

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

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

IRQEnable ();

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

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

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

*/

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

*/

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

while (1){

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

*/

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

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

return 0; }

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

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

13

14

提高部分:

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

硬件连接图:

15

源程序代码:

#include

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) { }

void timer0_ISR (void) {

16

//

// //

uint32 i,j;

for(i=0;itimes++ ; 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中断

17

}

void display_led(uint8 x,uint8 y) { uint32 data; }

int main(void) { uint8 miao_low; uint8 miao_high;

while(1) {

miao_low = miao%10; miao_high = miao/10; fen_low = fen%10;

18

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);

uint8 fen_low; uint8 fen_high; uint8 shi_low; uint8 shi_high;

PINSEL1 &= 0x00000000; IO0DIR |= 0xffff0000; IO0PIN |= 0xffff0000; timer0Init();

//p16-p31 as gpio //p16-p31 as out //初始化IO口

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);

}

}

19

因篇幅问题不能全部显示,请点此查看更多更全内容

Top