ARM9控制LED流水灯程序设计
存档资料成绩:
华东交通大学理工学院
课程设计报告书
课程名称嵌入式系统原理及应用题目 ARM9 I/O口控制LED流水灯程序设计分院电信分院专业班级通信工程 2008-2 学号 20080210420224 学生姓名骆玉春指导教师徐涢基
2012年 12月 30 日
华东交通大学理工学院课程设计报告
华东交通大学理工学院
课程设计任务书
专业通信工程班级 2008级2班姓名骆玉春
一、课程设计题目 ARM9 I/O口控制LED流水灯想设计二、课程设计工作:自2011 年 12 月 28 日起至 2012
月 2 日止。年 1
三、课程设计的内容要求:
1.了解ARM9的I/O口的工作原理;
2.基于arm920T的内核,在开发板或者实验箱上,实现LED的流水控制;
3.了解I/O口怎么控制LED的输出;
4.掌握设置I/O口的状态需要设置的寄存器GPBCON、GPBDAT、GPBUP;
5.掌握在ADS环境下建立工程,用H-JTAG来调试程序,生成.HEX文件;
6.总结本次课程设计的知识点。
学生签名:
201 年月日
- 1 -
华东交通大学理工学院课程设计报告
课程设计评阅意见
等级
序号项目优秀良好中等及格不及格
1 课程设计态度评价
2 出勤情况评价
3 任务难度评价
4 工作量饱满评价
5 任务难度评价
6 设计中创新性评价
7 论文书写规范化评
价
8 综合应用能力评价
综合评定等级
评阅人职称
20 年月日
- 2 -
华东交通大学理工学院课程设计报告
目录
课程设计任务书...................................................................... ..2 第1章课程设计目
的..............................................................4 第2章S3C2440的I/O口配置. (5)
第3章 S3C2440的I/O口寄存器 (6)
第4章课程设计过程 (9)
4.1 设计步骤...................................................................... (9)
4.2 部分原理图 (9)
4.3 源程序...................................................................... (10)
4.4 编译调试结果................................................................17 第
8章课程设计心得...........................................................19 参考文献...................................................................... . (20)
- 3 -
华东交通大学理工学院课程设计报告
第1章课程设计目的
这学期开了嵌入式这门课程,之前就了解到嵌入式系统是当前最热门最有发展前途的IT 应用领域之一。嵌入式系统用在一些特定专用设备上,通常这些设备的硬件资源(如处理器、存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高等。特别是随着消费家电的智能化,嵌入式更显重要。像我们平常常见到的手机、可视电话、PDA、电子字典、VCD/DVD/MP3 Player、机顶盒(Set Top Box)、数字相机(DC)、数字摄像机(DV)、高清电视(HDTV)、游戏机、智能玩具、交换机、路由器、数控设备或仪表、汽车电子、家电控制系统、医疗仪器、航天航空设备等等都是典型的嵌入式系统。
随着社会的发展,嵌入式在未来的应用会越来越广泛。随着物联网的时代的到来,电器将会与互联网,移动电话成为一体,通过无线通信技术以及互联网技术将可以使人们在任何时候控制电器等的工作。
通过这次课程设计使我们了解基本的嵌入式编程方法以及培养我们对嵌入式编程的兴趣,与此同时,我们还能巩固一下C编程和汇编编程基础,为将来的嵌入式学习和工作做好充足的准备~
- 4 -
华东交通大学理工学院课程设计报告
第2章 S3C2440的I/O口配置
在S3C2440 的CPU中有130多个多功能的输入输出引脚,分为8个端口,如下所示:
- Port A(GPA): 25-output port
- Port B(GPB): 11-input/out port
- Port C(GPC): 16-input/output port
- Port D(GPD): 16-input/output port
- Port E(GPE): 16-input/output port
- Port F(GPF): 8-input/output port
- Port G(GPG): 16-input/output port
- Port H(GPH): 9-input/output port
- Port J(GPJ): 13-input/output port
每个端口可以很容易地通过软件配置,以满足不同的系统配置和设计要求。如果引脚不用于复用功能,则引脚可配置为普通的I/O口。它们的寄存器是相似的:GPxCON用于选择引脚功能,GPxDAT用于都/写引脚数据,GPxUP用于确定是否使用内部上拉电阻(x为A、B、..........、H、J,注意没有GPAUP)。
1.GPxCON中每两位控制一根引脚:
00表示输入、01表示输出、10表示特殊功能、11保持不用。其中GPBCON中共有22位来管理GPB的功能设置,每两位来管理一个口的功能设置,两位共有四种状态,当GPB中的两位值为00时,配置为输入功能;配置为01时,是输出功能;10为复用功能;11为保留状态。
/写引脚: 2.GPxDAT用于读
当引脚设为输入时,读此寄存器可知相应引脚的状态是高是低。
当引脚设为输出时,写此寄存器相应位可令此引脚输出低电平或高电平。
3. GpxUP
GPBUP宫11位,每一位代表一个管脚的上拉功能,某位为0时,相应引脚上拉功能被使能,为1时,相应引脚被禁止使用上拉功能。
- 5 -
华东交通大学理工学院课程设计报告
第3章 S3C2440的I/O口寄存器
LED灯是接在某一个I/O上的,点亮或者熄灭LED灯其实就是对I/O寄存器的操作。ARM的I/O口寄存器主要包括端口配置寄存器GPXCON、端口数据寄存器
GPXDAT、端口上拉电阻使能寄存器GPXUP、MISCELLANEOUS控制寄存器和外部中断寄存器五种(其中X为芯片的I/O口字母)。在这个课程设计我们只用前三个寄存器,下面就对着三个寄存器进行简单的介绍。
对于ARM芯片来说,它的寄存器很多,为了区分不同的寄存器,系统给每个寄存器都分配了一个固定的地址,地址就像每个人的身份证一样,是唯一的。那么当你使用这个地址的时候ARM就知道你要使用哪个寄存器了,所以在编程的时候,首先要声明待操作的寄存器地址。下表就是本次课程设计要用到的寄存器的地址和位定义:
Register Address R/W Description Reset Value GPBCON 0x56000010 R/W Configures the pins of port B 0x0 GPBDAT 0x56000014 R/W The data register for port B Undefined
GPBUP 0x56000018 R/W Pull-up disable register for 0x0
port B
Reserved 0x5600001c — Reserved Undefined. ARM芯片找到相应寄存器后,也先要设置端口配置寄存器GPBCON,也就是告诉寄存器做好接收数据或者输出数据或者响应外部中断的准备,下表为它的功能描述:
GPBCON Bit Description
GPB10 [21:20] 00 = Input 01 = Output
10 = nXDREQ0 11 = reserved
GPB9 [19:18] 00 = Input 01 = Output
10 = nXDACK0 11 = reserved
GPB8 [17:16] 00 = Input 01 = Output
10 = nXDREQ1 11 = Reserved
- 6 -
华东交通大学理工学院课程设计报告
GPB7 [15:14] 00 = Input 01 = Output
10 = nXDACK1 11 = Reserved GPB6 [13:12] 00 = Input 01 = Output 10 = nXBREQ 11 = reserved GPB5 [11:10] 00 = Input 01 = Output 10 = nXBACK 11 = reserved GPB4 [9:8] 00 = Input 01 = Output
10 = TCLK[0] 11 = reserved GPB3 [7:6] 00 = Input 01 = Output 10 = TOUT3 11 = reserved GPB2 [5:4] 00 = Input 01 = Output
10 = TOUT2 11 = reserved GPB1 [3:2] 00 = Input 01 = Output
10 = TOUT1 11 = reserved GPB0 [1:0] 00 = Input 01 = Output
10 = TOUT0 11 = reserved
ARM设置完I/O口状态后,就准备读/写数据了。这个功能可以通过设置数据寄存器GPBDAT来实现。下表即为它的功能描述:
GPBDAT Bit Description
GPB[10:0] [10:0] When the port is configur- ed as
input port, the corre- sponding bit
is the pins-state.When the port is
configured as output port, the pin
state is the sameas the corresponding
bit.
When the port is config-gu red as
functional pin, theundefined value
will be read.
ARM设置完I/O口状态后,就准备读/写数据了。这个功能可以通过设置数- 7 -
华东交通大学理工学院课程设计报告
据寄存器GPBDAT来实现。下表即为它的功能描述:
设置完前两个寄存器后,还要设置上拉电阻使能寄存器GPBUP,顾名思义,它的作用就是告诉ARM这个端口要不要配置上拉电阻。上拉电阻、下拉电阻的作用在于,当IO引脚处于第三态(即不是高电平,也不是低电平,而是高阻态,相当于没接芯片)时,它的电平状态由上拉电阻、下拉电阻确定。下表为它的功能描述:当为0时,上拉电阻是允许的;反之,则上拉电阻是被禁止的。
GPBUP Bit Description
0:The pull-up function GPB[10:0] [10:0]
attached to the corrrespond
-ing port pin is enabled.
1:The pull-up function is
disabled.
到此,需要的寄存器就配置完成了,那么接下来介绍下LED在开发板上的电路原理图。
- 8 -
华东交通大学理工学院课程设计报告
第4章课程设计过程
4.1 设计步骤
1.连接好实验环境,将仿真器的一端通过并口连接到PC机,将仿真器的另一端通过JTAG先连接到开发板JTAG接口。
2.将串口线一端接到PC机,另一端接到S3C2440的UART0接口;打开串口超级终端,设置串口属性为COM1,串口波特率(Baudrout)为115200,校验位无,数据
位为8,停止位为1,检查连接是否可靠,可靠后,接入电源线,给系统上电,同时按住空格键,进入VIVI状态。
3.打开ADS codeWarrior,在ADS codeWarrior中创建工程编写代码,并对工程进行编译。
4.使用H-JTAG进行调试。
5.打开ARM的开发环境AXD Debugger,在AXD Debugger中加载可执行映像文件LED_TEXT.axf。
6.在ADS调试环境处下,全速运行映像文件,观察LED灯LED1、LED2、LED3、LED4的闪亮情况—轮流闪烁。
4.2部分原理图
图a
- 9 -
华东交通大学理工学院课程设计报告
图b
上图a、b是实验的部分原理图,可以看出我们通过GPB5、GPB6、GPB7、
GPB8来分别控制LED1、LED2、LED3、LED4。
4.3源程序:
1.main.c
#define rGPBCON (*(volatile unsigned *))0x56000010) //prot B contorl #define rGPBDAT (*(volatile unsigned *))0x56000010) //prot B data #define rGPBUP (*(volatile unsigned *))0x56000010) //pull-up control B
void xmain(void)
{
ChangeClockDivider(3,1); //设置时钟分频比1:3:6
ChangeMPllValue(127,2,1); //设置主时钟频405MHZ
Port_Init(); //端口初始化
Isr_Init(); //中断初始化
Uart_Init(0, 115200); //串口初始化
Uart_Select(0);
Uart_Printf("the main is running\n");//向超级终端打印"the main is running"
rGPBCON = rGPBCON & (~(0xf<<10)) |( 1<< 10) |(1 << 12);
//将GPB5[11:10] 两位设置为01---即output状态,GPB6[13:12] 两位设置为01---即output状态
- 10 -
华东交通大学理工学院课程设计报告
rGPBCON = rGPBCON & (~(0xf<<14)) |( 1<< 14) |(1 << 16);
//将GPB7[15:14] 两位设置为01---即output状态,GPB8[17:16] 两位设置为01---即output状态
rGPBUP = rGPBUP&(~(0xF<<5))|(0xF<<5);
//将GPB5、GPB6、GPB7、GPB8上拉电阻设置为disabled
while(1)
{
rGPBDAT = (rGPBDAT|(0xF<<5))&(~(0x1<<5)); //点亮LED1
Delay(10000000);//延时
rGPBDAT =( rGPBDAT|(0xF<<5))&(~(0x2<<5)); //点亮LED2
Delay(10000000);// 延时
rGPBDAT = (rGPBDAT|(0xF<<5))&(~(0x4<<5)); //点亮LED3
Delay(10000000);// 延时
rGPBDAT =(rGPBDAT|(0xF<<5))&(~(0x8<<5)); //点亮LED4
Delay(10000000);// 延时
rGPBDAT = (rGPBDAT|(0xF<<5))&(~(0x4<<5)); //点亮LED3
Delay(10000000);// 延时
rGPBDAT =( rGPBDAT|(0xF<<5))&(~(0x2<<5)); //点亮LED2
Delay(10000000);// 延时
rGPBDAT = (rGPBDAT|(0xF<<5))&(~(0x1<<5)); //点亮LED1
Delay(10000000);// 延时
}
}
2.2440lib.c
//============================================================
=======
// File Name : 2440lib.c
// Function : S3C2440 PLL,Uart, LED, Port Init
// Date :2011/22/28
- 11 -
华东交通大学理工学院课程设计报告
// Version : 0.1
//============================================================
=======
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include
#include
#include
#include
#include
extern char Image$$RW$$Limit[]; void *mallocPt=Image$$RW$$Limit; static int delayLoopCount; void Delay(int time) //延时函数
{
int i, adjust=0;
if(time==0)
{
time = 200;
adjust = 1;
delayLoopCount = 800;
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3);
rWTDAT = 0xffff;
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer
start
- 12 -
华东交通大学理工学院课程设计报告
}
for(;time>0;time--)
for(i=0;i if(adjust==1) { rWTCON = ((PCLK/1000000-1)<<8)|(2<<3); //Watch-dog timer stop i = 0xffff - rWTCNT; //1count->64us, 200*800 cycle runtime = 64*i us delayLoopCount = 16000000/(i*64); //200*800:64*i=1*x:100 -> x=160000*100/(64*i) } } void Port_Init(void)//I/O口初始化 { rGPACON = 0x7fffff; rGPBCON = 0x155555; rGPBUP = 0x7ff; // The pull up function is disabled GPB[10:0] rGPCCON = 0xaaaaaaaa; rGPCUP = 0xffff; // The pull up function is disabled GPC[15:0] rGPDCON = 0xaaaaaaaa; rGPDUP = 0xffff; // The pull up function is disabled GPD[15:0] rGPECON = 0xaaaaaaaa; rGPEUP = 0xffff; // The pull up function is disabled GPE[15:0] rGPFCON = 0x55aa; rGPFUP = 0xff; // The pull up function is disabled GPF[7:0] rGPGCON = 0xff95ffba; rGPGUP = 0xffff; // The pull up function is disabled GPG[15:0] rGPHCON = 0x2afaaa; rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0] rGPJDAT = (1<<12)|(0<<11); - 13 - 华东交通大学理工学院课程设计报告 rGPJCON = 0x016aaaa; rGPJUP = ~((0<<12)|(1<<11)); rGPJDAT = (0<<12)|(0<<11); rGPJCON = 0x016aaaa; rGPJUP = 0x1fff;//~((1<<12)|(1<<11)); rEXTINT0 = 0x22222222; // EINT[7:0] rEXTINT1 = 0x22222222; // EINT[15:8] rEXTINT2 = 0x22222222; // EINT[23:16] } static int whichUart=1; void Uart_Init(int pclk,int baud)//串口初始化,设置时钟,波特率 { if(pclk == 0) pclk = PCLK; rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable rUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disable rUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable rUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable //UART0 rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bit rUCON0 = 0x245; // Control register rUBRDIV0 = 0x34; //UART1 rULCON1 = 0x3; rUCON1 = 0x245; rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 ); //UART2 rULCON2 = 0x3; rUCON2 = 0x245; - 14 - 华东交通大学理工学院课程设计报告 rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 ); Uart_TxEmpty(whichUart); } void Uart_Select(int ch) { whichUart = ch; } void Uart_TxEmpty(int ch) { if(ch==0) while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty. else if(ch==1) while(!(rUTRSTAT1 & 0x4)); //Wait until tx shifter is empty. else if(ch==2) while(!(rUTRSTAT2 & 0x4)); //Wait until tx shifter is empty. } void Uart_SendString(char *pt) { while(*pt) Uart_SendByte(*pt++); } void Led_Display(int data) //LED显示 { rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4); } void Timer_Start(int divider) //0:16us,1:32us 2:64us 3:128us { - 15 - 华东交通大学理工学院课程设计报告 rWTCON = ((PCLK/1000000-1)<<8)|(divider<<3); //Watch-dog timer control register rWTDAT = 0xffff; //Watch-dog timer data register rWTCNT = 0xffff; //Watch-dog count register rWTCON = (rWTCON & ~(1<<5) & ~(1<<2)) |(1<<5); } int Timer_Stop(void) { rWTCON = ((PCLK/1000000-1)<<8); return (0xffff - rWTCNT); } void ChangeMPllValue(int mdiv,int pdiv,int sdiv) { rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; } void ChangeUPllValue(int mdiv,int pdiv,int sdiv) { rUPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; } void Isr_Init(void)//中断初始化 { pISR_UNDEF = (unsigned)HaltUndef; pISR_SWI = (unsigned)HaltSwi; pISR_PABORT = (unsigned)HaltPabort; pISR_DABORT = (unsigned)HaltDabort; rINTMOD = 0x0; //All=IRQ mode rINTMSK = BIT_ALLMSK; //All interrupt is masked. rINTSUBMSK = BIT_SUB_ALLMSK; } - 16 - 华东交通大学理工学院课程设计报告 4.4 编译调试结果 - 17 - 华东交通大学理工学院课程设计报告 - 18 - 华东交通大学理工学院课程设计报告 第5章课程设计心得 通过本次课程设计,使我对S3C2440体系结构理解更加深刻,以及对相应的寄存器操作更熟悉。