嵌入式系统原理与应用实验报告_第1页
嵌入式系统原理与应用实验报告_第2页
嵌入式系统原理与应用实验报告_第3页
嵌入式系统原理与应用实验报告_第4页
嵌入式系统原理与应用实验报告_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式系统原理与应用实验报告实验报告-20-目录软件仿真实验实验一ARM汇编指令1--简单数据搬移实验 3实验二ARM汇编指令2--字符串拷贝实验 5实验三ARM汇编指令3--ARM处理器工作模式实验 9实验四ARM汇编与C混合编程实验--ARM启动过程控制实验 16硬件接口实验实验五ARM硬件接口实验1--基本IO实验 23实验六ARM硬件接口实验2--外部中断实验 35实验总结 45实验一ARM汇编指令1--简单数据搬移实验实验目的熟悉实验开发环境,掌握简单ARM汇编指令的使用方法实验环境硬件:PC机。软件:ADS1.2集成开发环境实验内容熟悉开发环境并使用LDR/STR,MOV等指令访问寄存器或存储单元;使用ADD/SUB/LSL/LSR/AND/ORR等指令,完成基本数学/逻辑运算。实验要求(1)按照2.3节介绍的方法,在ADS下创建一个工程asmlab1,定义两个变量x,y和堆栈地址0x1000,将变量x的内容存到堆栈顶,然后计算x+y,并将和存到堆栈的下一个单元。通过AXD查看寄存器和memory和寄存器中数据变化。(2)在指令后面加上适当注释,说明指令功能。(3)指出程序执行完成后各相关寄存器及存储器单元的具体内容。参考程序:AREAInit,CODE,READONLY;AREA用于声明一个只读或读写的代码或数据段ENTRY;ENTRY声明程序入口,CODE32用于申明以下代码为32位ARM指令CODE32 xEQU45 ;x=45 yEQU64 ;y=64stack_topEQU0x1000;definethetopaddressforstacks栈顶为0x1000startMOVSP,#stack_top;SP=0x1000MOVR0,#x;R0=45STRR0,[SP];[1000]存放45MOVR0,#y;R0=64LDRR1,[SP];LDR加载指令,STR存储指令.ADDR0,R0,R1;将R0与R1相加赋值给R0;STRR0,[SP,#4];STRR0,[SP,#4];先执行SP+4,再将寄存器R0B.;无限循环跳转到当前地址END;程序结束。单步调试过程:通过观察,本实验中内存采用大端模式初始寄存器及各内存运行情况:运行MOVR0,#x后运行STRR0,[SP]后运行MOVR0,#y后运行LDRR1,[SP]后运行ADDR0,R0,R1后运行STRR0,[SP,#4]后练习题编写程序实现对一段数据的最大值最小值搜索,最大值存于max变量之中,最小值存于min变量之中。提示:数据的定义采用伪指令:DCD来实现,如:DataBufDCD11,-2,35,47,96,63,128,-23搜索最大值和最小值可以利用两个寄存器R1,R2来存放。用到的比较指令为CMP,用到的条件标识符小于为LT,大于为GT。基本思路为:利用R0做基地址,将R1,R2分别存入第一个单元的内容,利用R3做循环计数器,利用R4遍历读取第2至最后一个数据,如果R1的数据小于新读入的R4数据则将R4的内容存入R1,如果R2的内容大于R4的内容则将R4的内容存入R2。遍历完成之后,R1将存放最大数据,R2将存放最小数据。练习题实验源程序:AREAInit,CODE,READONLYENTRYCODE32startLDRr0,=DataBuf;r0取数据段的首地址MOVr3,#0x08;用r3存循环次数LDRr1,[r0];用r1存最大值LDRr2,[r0];用r2存最小值LDRr4,[r0]loopSUBr3,r3,#1CMPr3,#0;结束条件BLEQCONTINUEADDr0,r0,#0x04;分支语句LDRr4,[r0]CMPr4,r1BGTbigCMPr4,r2BLTsmallBloopbigMOVr1,r4BloopsmallMOVr2,r4BloopAREAArray,DATA,READWRITEDataBufDCD11,-2,35,47,96,63,128,-23CONTINUEEND实验截图:相关解释:最后成功搜索到最大值,放到了R1中,搜索到的最小值放到了R2中。实验二ARM汇编指令2--字符串拷贝实验实验目的通过实验掌握使用LDB/STB,b等指令完成较为复杂的存储区访问和程序分支,学习使用条件码。实验环境硬件:PC机。软件:ADS1.2集成开发环境。实验内容熟悉开发环境的使用并完成一块存储区的拷贝。完成分支程序设计,要求判断参数,根据不同参数,调用不同的子程序。实验要求(1)按照2.3节介绍的方法,在ADS下创建一个工程asmlab2,定义两个数据存储区Src和Dst,Src用于存放原字符串,Dst用于存放目的字符串。堆栈地址0x400,将变量原字符串的内容拷贝到目的字符串中,要能判断原字符串的结束符(0),并统计字符串中字符的个数。通过AXD查看寄存器和memory和寄存器中数据变化。(2)在指令后面加上适当注释,说明指令功能。(3)指出程序执行完成后各相关寄存器及存储器单元的具体内容。参考程序:AREAInit,CODE,READONLY;AREA用于声明一个只读或读写的代码或数据段,这里是只读代码段ENTRY ;ENTRY声明程序入口CODE32 ;CODE32用于申明以下代码为32位ARM指令START ;标号“start”MOVSP,#0x400 ;SP=0x400LDRR0,=Src ;LDR伪指令将源字符串的地址值读取到R0寄存器中LDRR1,=Dst ;LDR伪指令将目的字符串的地址值读取到R1寄存器中MOVR3,#0 ;R3=0进行初始化,用来统计字符串中字符的个数strcopy ;标号“strcopy”LDRBR2,[R0],#1 ;将源地址起始位置的一个字节数据装入R2中,且R0=R0+1CMPR2,#0 ;比较R2和结束符0的大小BEQendcopy ;若R2==0表示跳转到endcopy处STRBR2,[R1],#1 ;若R2!=0,把寄存器R2中的字数据(32位)保存到目的地址的内存地址中,且R1=R1+1ADDR3,R3,#1 ;R3=R3+1用来统计字符串中字符的个数Bstrcopy ;跳转回标号“strcopy”处endcopy ;标号“endstrcopy”LDRR0,=ByteNum ;LDR伪指令将ByteNum的地址值读取到R0寄存器中STRR3,[R0] ;将统计得到的字符个数存储到ByteNum内存单元中B. ;无限循环跳转到当前地址AREADatapool,DATA,READWRITE;AREA用于声明一个只读或读写的代码或数据段,这里是读写数据段SrcDCB"string",0 ;源字符串数据存储地址DstDCB0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;目的字符串存储地址ByteNumDCD0 ;字符个数统计单元存储地址END ;程序结束参考程序实验截图运行前内存情况:运行至复制前,得知源地址在0x8040,目标地址在0x8047单步调试运行中

ByteNum的地址:最终结果:练习题编写程序循环对R4~R11进行累加8次赋值,R4~R11起始值为1~8,每次加操作后把R4~R11的内容放入SP栈中,SP初始设置为0x800。最后把R4~R11清空赋值为0。提示:多字的加载与存储使用多寄存器寻址,使用的指令为LDM和STM。如:LDMIAR0!,{R4-R11}STMIAR1!,{R4-R11}练习题程序:AREAInit,CODE,READONLYENTRYCODE32Start;设置起始值MOVSP,#0X800LDRR0,=srcMOVR1,#8MOVR4,#1MOVR5,#2MOVR6,#3MOVR7,#4MOVR8,#5MOVR9,#6MOVR10,#7MOVR11,#8loopADDR4,R4,#1ADDR5,R5,#1ADDR6,R6,#1ADDR7,R7,#1ADDR8,R8,#1ADDR9,R9,#1ADDR10,R10,#1ADDR11,R11,#1STMFDSP!,{R4-R11}SUBSR1,R1,#1;循环判别条件BNEloopLDMIAR0!,{R4-R11}HALTBHALTsrcDCD0,0,0,0,0,0,0,0END练习题实验截图:实验三ARM汇编指令3--ARM处理器工作模式实验实验目的(1)通过实验掌握学会使用msr/mrs指令实现ARM处理器工作模式的切换,观察不同模式下的寄存器,加深对CPU结构的理解;(2)通过实验掌握ld中如何使用命令行指定代码段起始地址。实验设备硬件:PC机。软件:ADS1.2集成开发环境实验内容通过ARM汇编指令,在各种处理器模式下切换并观察各种模式下寄存器的区别;掌握ARM不同模式的进入与退出。实验要求(1)按照2.3节介绍的方法,在ADS下创建一个工程asmmodelab,完成各个模式下的堆栈初始化工作,并将R1-R12的内容存入当前模式下堆栈。通过AXD运用单步执行方式调试程序,验证工作模式的切换,注意观察CPSR寄存器中的变化。随着程序调试过程中在模式间的切换,使用寄存器观察器切换到不同的工作模式下观察SP(R13)的变化情况。(2)实验过程中请记录并思考以下内容:1)程序复位之后系统处于什么模式?2)记录每种模式下的初始堆栈指针,以及执行R1-R12内容压栈后本模式堆栈相关内存单元的数值。并分析快速中断FIQ模式与其他模式存入的R1-R12有什么不同。3)切换成用户模式之后还能否从用户模式切换到其他模式(如系统模式)?4)用户模式下能否执行堆栈压栈操作?如果能得话,观察用户模式下压栈之前和压栈之后其堆栈区域的变化情况。5)观察本程序模式切换过程中SPSR有无变化,并解释其原因。参考程序:;定义堆栈大小usr_stack_legthequ64 ;用户模式svc_stack_legthequ32 ;管理模式fiq_stack_legthequ16 ;快速中断模式irq_stack_legthequ64 ;中断模式abt_stack_legthequ16 ;中止模式und_stack_legthequ16 ;未定义模式 areareset,code,readonly ;

声明只读代码段reset entry ;ENTRY声明程序入口 code32 ;CODE32用于申明以下代码为32位ARM指令startmovr0,#0 movr1,#1 movr2,#2 movr3,#3 movr4,#4 movr5,#5 movr6,#6 movr7,#7 movr8,#8 movr9,#9 movr10,#10 movr11,#11 movr12,#12 blinitstack ;初始化各模式下的堆栈指针BL(BranchwithLink跳转将PC拷入LR,用于子程序返回) ;打开irq中断(将cpsr寄存器的i位清0) mrsr0,cpsr ;r0<--cpsr bicr0,r0,#0x80 ;开IRQ中断 msrcpsr_cxsf,r0 ;cpsr<--r0;切换到用户模式(CPSR[4:0]=10000,同时CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]=11010000=0xd0) msrcpsr_c,#0xd0;保存一下当前CPSR,将CPSR传入R0 mrsr0,cpsr;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;观察由用户模式能否切换到其他模式 ;切换到管理模式 msrcpsr_c,#0xdf;保存一下当前CPSR,将CPSR传入R0 mrsr0,cpsr;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12}haltbhalt ;留在此处Initstack ;初始化各模式下的堆栈子程序;子程序内容r0<--lr,因为各种模式下r0是相同的而各个模式movr0,lr ;R0<-LR,各模式下的R0是相同的 ;设置管理模式堆栈,先切换到管理模式下再设置该模式下的SP

msrcpsr_c,#0xd3 ;11010011cpsr[4:0] ldrsp,stacksvc ;将StackSvc代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;设置中断模式堆栈,先切换到中断模式下再设置该模式下的SP,;中断模式CPSR[7:0]=110,10010 msrcpsr_c,#0xd2 ;11010010 ldrsp,stackirq ;将stackirq代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;设置快速中断模式堆栈 msrcpsr_c,#0xd1 ;11010001 ldrsp,stackfiq ;将stackfiq代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;设置中止模式堆栈,先切换到中断模式下再设置SP msrcpsr_c,#0xd7 ;11010111 ldrsp,stackabt ;将stackabt代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;设置未定义模式堆栈 msrcpsr_c,#0xdb ;11011011 ldrsp,stackund ;将stackund代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;设置系统模式堆栈 msrcpsr_c,#0xdf ;11011111 ldrsp,stackusr ;将stackusr代表的地址装入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} movpc,r0 ;返回;定义堆栈首地址,即最高地址处stackusrdcdusrstackspace+(usr_stack_legth-1)*4stacksvcdcdsvcstackspace+(svc_stack_legth-1)*4stackirqdcdirqstackspace+(irq_stack_legth-1)*4stackfiqdcdfiqstackspace+(fiq_stack_legth-1)*4stackabtdcdabtstackspace+(abt_stack_legth-1)*4stackunddcdundstackspace+(und_stack_legth-1)*4 areareset,data,noinit,align=2 ;分配栈堆空间usrstackspacespaceusr_stack_legth*4 ;分配USR_STACK_LENGTH*4个字节svcstackspacespacesvc_stack_legth*4 ;同上irqstackspacespaceirq_stack_legth*4fiqstackspacespacefiq_stack_legth*4abtstackspacespaceabt_stack_legth*4undstackspacespaceund_stack_legth*4 end ;END程序结束实验截图:运行前,用户模式各寄存器状态如图,其他模式R13寄存器值均为0:1、usr_stack_legthequ64 ;用户模式之后用户模式各寄存器赋初值:2、svc_stack_legthequ32 ;管理模式3、fiq_stack_legthequ16 ;快速中断模式4、irq_stack_legthequ64 ;中断模式5、abt_stack_legthequ16 ;中止模式6、und_stack_legthequ16 ;未定义模式实验练习题答案1)程序复位之后系统处于什么模式?程序复位后CPSR的值是SVC,故系统处于管理模式。2)记录每种模式下的初始堆栈指针,以及执行R1-R12内容压栈后本模式堆栈相关内存单元的数值。并分析快速中断FIQ模式与其他模式存入的R1-R12有什么不同。这是管理模式中断模式,初始化堆栈指针式0x8340 快速中断模式,初始化堆栈指针式0x8380 只到r7就停了,快速中断模式有自己的分组寄存器R8_fiqR14_fiq中止模式,初始化堆栈指针式0x8c0 未定义模式,初始化堆栈指针式8400系统模式,初始化堆栈指针式81c03)切换成用户模式之后还能否从用户模式切换到其他模式(如系统模式)?切换成用户模式之后还能从用户模式进入其他模式,例如中断模式。4)用户模式下能否执行堆栈压栈操作?如果能得话,观察用户模式下压栈之前和压栈之后其堆栈区域的变化情况。用户模式下能执行压栈操作。堆栈的变化情况如图所示(红色部分之前是00)。5)观察本程序模式切换过程中SPSR有无变化,并解释其原因。SPSR无变化,因为程序运行没有发生异常,无异常状态。实验四ARM汇编与C混合编程实验--ARM启动过程控制实验实验目的(1)掌握建立基本完整的ARM工程,包含启动代码,C语言程序等;(2)了解ARM启动过程,学会编写简单的C语言程序和汇编启动代码并进行调试;(3)掌握如何指定代码入口地址与入口点;(4)掌握通过memory/register/watch/variable窗口分析判断结果。实验设备硬件:PC机。软件:ADS1.2集成开发环境实验内容使用汇编语言编写初始化程序,并引导至C语言main函数,用汇编语言编写延时函数实现毫秒级的延时,在C语言中调用延时函数,实现1s钟定时。实验要求(1)按照2.3节介绍的方法,在ADS下创建一个工程armasmc,编写3个文件,如下图3-1所示:图3-1实验工程文件管理其中一个初始化汇编语言文件Init.s,该文件中主要完成异常矢量表的建立,模式堆栈初始化,并将程序引导至C语言的main函数。C语言程序保存为armasmc.c。C语言中调用汇编语言文件delay.s中的毫秒延时程序delayxms,C语言将延时的毫秒数通过参数传递到汇编语言,汇编语言完成延时,然后返回C语言函数。通过AXD运用单步执行方式调试程序。观察程序执行过程中的寄存器及存储器的变化情况。(2)实验过程中请记录并思考以下内容:1)如何建立异常矢量入口表?

2)如何在汇编语言中切换至C语言的main函数?。

3)如何在C语言中调用汇编语言函数,并完成参数传递?

4)汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的

R11?

5)将delay.s中的R11改成R4,并将两条R11的保护与恢复语句stmfdsp!,{r12}

和ldmfdsp!,{r11}删掉,在C语言程序中的语句i--处设置端点,观察运行

过程中变量i的变化情况,并解释其中的原因。参考程序:;***************************************************************;NAME:entry.s;Author:lihua;History:2014-4-10;***************************************************************IMPORTmain ;用IMPORT伪操作来声明即将调用的C程序。areaInit,code,readonly ;AREA用于声明一个只读或读写的代码或数据段,这里是只读代码段entry ;ENTRY声明程序入口code32 ;CODE32用于申明以下代码为32位ARM指令;***********Setupinterrupt/exceptionvectors*************************;建立异常矢量入口表start bReset_Handler ;Reset入口,即为整个程序的实际入口点Undefined_Handler bUndefined_HandlerSWI_Handler bSWI_HandlerPrefetch_handler bPrefetch_handlerAbort_Handler bAbort_Handlernop;ReservedvectoIRQ_Handler bIRQ_HandlerFIQ_Handler bFIQ_HandlerReset_Handlerblinitstack ;通过BL指令来调用initstack子程序,将PC拷入LR,用于子程序返回,初始化各模式下的堆栈指针;切换至用户模式堆msrcpsr_c,#0xd0;11010000blmain ;通过BL指令来调用main.chalt bhalt ;无限循环跳转到当前地址initstack movr0,lr;r0<--lr,因为各种模式下r0是相同的而各个模式?;设置管理模式堆栈,先切换到管理模式下再设置该模式下的SP

msrcpsr_c,#0xd3;11010011ldrsp,stacksvc ;将StackSvc代表的地址装入SP;设置中断模式堆栈msrcpsr_c,#0xd2;11010010ldrsp,stackirq ;将stackirq代表的地址装入SP

;设置快速中断模式堆栈msrcpsr_c,#0xd1;11010001ldrsp,stackfiq ;将stackfiq代表的地址装入SP;设置中止模式堆栈 msrcpsr_c,#0xd7;11010111ldrsp,stackabt ;将stackabt代表的地址装入SP;设置未定义模式堆栈msrcpsr_c,#0xdb;11011011ldrsp,stackund ;将stackund代表的地址装入SP;设置系统模式堆栈msrcpsr_c,#0xdf;11011111ldrsp,stackusr ;将stackusr代表的地址装入SPmovpc,r0;返回LTORG ;LTORG用于声明一个文字池,在使用LDR伪指令的时候,要在适当的地址加入LTORG声明文字池,这样就会把要加载的数据保存在文字池内,再用ARM的加载指令读出数据;定义堆栈首地址,即最高地址处stackusr dcdusrstackspace+128Stacksvc dcdsvcstackspace+128stackirq dcdirqstackspace+128stackfiq dcdfiqstackspace+128stackabt dcdabtstackspace+128stackund dcdundstackspace+128areaInterrupt,data,READWRITE ;分配栈堆空间usrstackspacespace128 ;分配128个字节svcstackspacespace128 ;同上irqstackspacespace128fiqstackspacespace128abtstackspacespace128undstackspacespace128end/********************************************************************File:armasmc.c*Author:lihua2014.4.10*History:********************************************************************/#include<stdio.h>intmain(){externvoiddelayxms(intxms);//使用extern关键词来声明即将调用的汇编程序inti=100;while(1){delayxms(1000);//延时1si--;if(i==0)i=100;}return0;};***************************************************************;NAME:delay.s;Author:lihua;History:2014-4-10;***************************************************************EXPORTdelayxms ;使用EXPORT伪操作来声明,使得本程序可以被其它程序调用areadelay,code,readonly ;AREA用于声明一个只读或读写的代码或数据段,这里是只读代码段code32 ;CODE32用于申明以下代码为32位ARM指令;下面是延时若干ms的子程序delayxms ;调用时参数传递给R0寄存器stmfdsp!,{r11}; ;STM指令把寄存器列表中索引最小的寄存器存在最低地址,R1、LR依次入栈,完成后SP指向保存R1的地址。subr0,r0,#1 ;r0=r0-1ldrr11,=1000 ;r11=1000loop2subr11,r11,#1 ;r11=r11-1cmpr11,#0x0 ;比较R11和0,设置标志位bneloop2 ;R11不等于0,调转到Loop2标号cmpr0,#0x0 ;r11==0,继续将r0与0比较bnedelayxms ;比较的结果不为0,则继续调用delayxmsldmfdsp!,{r11}; ;r0==0,lr、r1依次出栈movpc,lr ;返回程序调用入口处end截图程序运行初始状态:初始化各模式堆栈:初始化完毕,调用main函数:局部变量i的值传递给R4寄存器:恢复r11的值:由main.c调用delay.asm:返回main.c:实验练习题如何建立异常矢量入口表?我们在编写代码的时候,一般地,我们使用下面的代码,这样建立异常矢量表:startbReset_HandlerUndefined_HandlerbUndefined_HandlerSWI_HandlerbSWI_HandlerPrefetch_handlerbPrefetch_handlerAbort_HandlerbAbort_Handlernop;ReservedvectoIRQ_HandlerbIRQ_HandlerFIQ_HandlerbFIQ_Handler2)如何在汇编语言中切换至C语言的main函数?在asm文件中用IMPORT伪操作来声明即将调用的C程序,通过BL指令来调用main.c。如何在C语言中调用汇编语言函数,并完成参数传递?在C文件中使用extern关键词来声明即将调用的汇编程序,在ASM文件中使用EXPORT伪操作来声明,使得本程序可以被其它程序调用。4)汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的R11?通过命令stmfdsp!,{r11}保护 ;STM指令把寄存器列表中索引最小的寄存器存在最低地址,R1、LR依次入栈,完成后SP指向保存R1的地址。通过命令ldmfdsp!,{r11}恢复 ;r0==0,lr、r1依次出栈因为R11=1000在程序调用过程中被用到,这样做是为了保存程序被调用前的数值。5)将delay.s中的R11改成R4,并将两条R11的保护与恢复语句stmfdsp!,{r12}和ldmfdsp!,{r11}删掉,在C语言程序中的语句i--处设置端点,观察运行过程中变量i的变化情况,并解释其中的原因。因为在程序调用过程中局部变量i的值传给了R4,经过这一步,更改的效果是,运行到i--时候,i从100变到0。硬件接口实验实验五ARM硬件接口实验1--基本IO实验实验目的(1)GPIO的功能配置方法;(2)通过寄存器访问引脚的方法;(3)实现GPIO输入输出功能的基本编程方法。实验设备硬件:北京博创UP-TECH三合一实验箱,J-Link仿真器套件,PC机软件:ADS1.2集成开发环境实验内容编写S3C2440X处理器的端口控制程序,实现利用按键控制的跑马灯程序。GPC5,GPC6,GPC7三个引脚连接发光二极管,按钮开关连接在GPF5引脚,如下图4-13所示:图4-13上电之后,GPC5、GPC6、GPC7按照如下图所示的方向,轮流显示,当按钮开关按下去,方向反向,如下图所示:实验过程中要注意按键去抖动和每个发光二极管显示一定的时间(至少100ms)。实验原理1、S3C2440的GPIO功能简介S3C2440有130个多功能输入输出接口(GPIO),它们被分成9组,分别是:—PortA(GPA):25-outputport—PortB(GPB):11-input/outport—PortC(GPC):16-input/outputport—PortD(GPD):16-input/outputport—PortE(GPE):16-input/outputport—PortF(GPF):8-input/outputport—PortG(GPG):16-input/outputport—PortH(GPH):9-input/outputport—PortJ(GPJ):13-input/outputport每个端口的功能可由软件进行配置。GPIO特殊功能寄存器对GPIO进行配置和控制的特殊功能寄存器,主要有3类,分别是:端口控制寄存器GPxCON寄存器,端口数据寄存器GPxDAT寄存器和端口上拉寄存器GPxUP。2、(1)GPxCON寄存器GPxCON寄存器是为了配置引脚功能的,每一个引脚都可以配置成为输入、输出、外部中断组、特殊功能引脚中的至少三种情况。(2)GPxDAT寄存器GPxDAT是用来读/写引脚状态的:当引脚设置为输出时,向该寄存器的对应位写“1”可输出高电平,写“0”可输出低电平;当引脚设置为输入时,读此寄存器便可得知相应引脚的电平状态;引脚被设置成为特殊功能时,读写此寄存器无效。(3)GPxUP寄存器GPxPUD寄存器是用来设置引脚的内部上/下拉电阻的,寄存器每两位控制一个引脚的上下拉电阻。当引脚对应的两位为“00”时,禁止上/下拉,为“01”时,下拉使能,为“10”时上拉使能。上拉电阻和下拉电阻的作用是:当GPIO引脚处于第三态(高阻态,相当于没接芯片)时,它的电平状态由上拉电阻或下拉电阻确定。本实验中将用到的GPC和GPF两组端口,因此我们将这两个组的端口进行详细介绍。3、端口配置(1)GPC5,GPC6和GPC7三个管脚定义为输出口,输出低电平时相应的LED灯点亮。#definerGPCCON(*(volatileunsigned*)(0x56000020))#definerGPCDAT(*(volatileunsigned*)(0x56000024))#definerGPCUP(*(volatileunsigned*)(0x56000028))#defineGPC5_ONrGPCDAT&~(1<<5)#defineGPC5_OFFrGPCDAT|(1<<5)#defineGPC6_ONrGPCDAT&~(1<<6)#defineGPC6_OFFrGPCDAT|(1<<6)#defineGPC7_ONrGPCDAT&~(1<<7)#defineGPC7_OFFrGPCDAT|(1<<7)rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口设置为输出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引脚上拉(2)GPF5定义为输入,用于实现按键识别#definerGPFCON(*(volatileunsigned*)(0x56000050))#definerGPFDAT(*(volatileunsigned*)(0x56000054))#definerGPFUP(*(volatileunsigned*)(0x56000058))rGPFCON=rGPFCON&~(0x3<<10);//将GPF的5端口设置为输入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引脚上拉charKey_Scan()//按键扫描程序{if(!(rGPFDAT&(1<<5)))//如果GPF5被按下,读取到低电平{delay(20);//延时去抖动,由于ARM11为流水线结构,这里只//是一个大概的延时值if(!(rGPFDAT&(1<<5)))//再次判断return1;//返回“1”elsereturn0;}elsereturn0;}voiddelay(inttime)//延时函数,用于扫描按键时去软件抖动{U8i,j,k;for(i=0;i<time;i++)for(j=0;j<255;j++)}参考程序:(1)初始化程序;********************************************************************;Description:Thisisainitprogramdesignedbycompilelanguage;NAME:entry.s;History:2014-5-4;********************************************************************IMPORTmainareaInit,code,readonlyentrycode32;*****Setupinterrupt/exceptionvectors***********************startbReset_HandlerUndefined_HandlerbUndefined_HandlerSWI_HandlerbSWI_HandlerPrefetch_handlerbPrefetch_handlerAbort_HandlerbAbort_Handlernop;ReservedvectoIRQ_HandlerbIRQ_HandlerFIQ_HandlerbFIQ_HandlerReset_Handlerblinitstack;初始化各模式下的堆栈指针;切换至用户模式堆msrcpsr_c,#0xd0;11010000blmainhaltbhaltinitstackmovr0,lr;r0<--lr,因为各种模式下r0是相同的而各个模式?;设置管理模式堆栈msrcpsr_c,#0xd3;11010011ldrsp,stacksvc;设置中断模式堆栈msrcpsr_c,#0xd2;11010010ldrsp,stackirq;设置快速中断模式堆栈msrcpsr_c,#0xd1;11010001ldrsp,stackfiq;设置中止模式堆栈msrcpsr_c,#0xd7;11010111ldrsp,stackabt;设置未定义模式堆栈msrcpsr_c,#0xdb;11011011ldrsp,stackund;设置系统模式堆栈msrcpsr_c,#0xdf;11011111ldrsp,stackusrmovpc,r0;返回LTORGstackusrdcdusrstackspace+128stacksvcdcdsvcstackspace+128stackirqdcdirqstackspace+128stackfiqdcdfiqstackspace+128stackabtdcdabtstackspace+128stackunddcdundstackspace+128areaInterrupt,data,READWRITEusrstackspacespace128svcstackspacespace128irqstackspacespace128fiqstackspacespace128abtstackspacespace128undstackspacespace128end(2)C语言控制程序为:/******************************************************************Description:ThisisaGPIOcontrolprogram*File:GPIO.c*Author:lihua2014.5.4*History:*******************************************************************/#definerGPCCON(*(volatileunsigned*)(0x56000020))#definerGPCDAT(*(volatileunsigned*)(0x56000024))#definerGPCUP(*(volatileunsigned*)(0x56000028))#definerGPFCON(*(volatileunsigned*)(0x56000050))#definerGPFDAT(*(volatileunsigned*)(0x56000054))#definerGPFUP(*(volatileunsigned*)(0x56000058))#defineGPC5_ON~(1<<5)#defineGPC5_OFF(1<<5)#defineGPC6_ON~(1<<6)#defineGPC6_OFF(1<<6)#defineGPC7_ON~(1<<7)#defineGPC7_OFF(1<<7)voiddelay(inttime)//延时函数,用于扫描按键时去软件抖动{inti,j;for(i=0;i<time;i++)for(j=0;j<255;j++);}voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口设置为输出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引脚上拉rGPFCON=rGPFCON&~(0x3<<10);//将GPF的5端口设置为输入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引脚上拉delay(10);rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口灭掉}charKey_Scan()//按键扫描程序{charkey=rGPFDAT&(1<<5);if(!key)//如果GPF5被按下,读取到低电平{delay(100);//延时去抖动,这里只是一个大概的延时值if(!key)//再次判断return1;//返回"1"elsereturn0;}elsereturn0;}intmain(){intcount=0;chardirection=0;//charolddir=0;port_init();while(1){if(Key_Scan())direction=1;elsedirection=0;switch(count){case0:rGPCDAT=rGPCDAT&GPC5_ON;rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;delay(1000);break;case1:rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;delay(1000);break;case2:rGPCDAT=rGPCDAT&GPC7_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC6_OFF;delay(1000);break;default:break;}if(!direction){if(count==2)count=-1;count++;}else{if(count==0)count=3;count--;};}}实验要求(1)按照前面介绍的方法,在ADS下创建一个工程GPIO,并将前面示例程序加入工程。(注意将实验箱中的JP1402设置为2-3短接,即选择ARMICE模式)。运行AXD加载生成的image文件,点击按钮,运用程序。观察程序执行的效果。并观察按键按下和松开跑马灯轮换的方向。(2)实验过程中请记录并思考以下内容:1)如何访问寄存器并修改其中的1位或多位数据?2)如何配置S3C2440的PIO端口?3)在C语言中如何实现按键处理程序?4)如何初始化DRAM,从而实现程序下载并在线调试?5)尝试实现利用按键切换控制跑马灯的顺序轮换(不是控制其轮换方向,而是在有按键按下并松开后实现一次跑马灯切换)。实验截图:实验练习题如何访问寄存器并修改其中的1位或多位数据?rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;如代码所示用与,非,或操作寄存器的1位或多位数据。如何配置S3C2440的PIO端口?配置IO如下所示voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口设置为输出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引脚上拉rGPFCON=rGPFCON&~(0x3<<10);//将GPF的5端口设置为输入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引脚上拉//delay(10);rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口灭掉}在C语言中如何实现按键处理程序?C语言按键程序如下所示voidKey_Scan()//按键扫描程序{charkey=rGPFDAT&(1<<5);if(!key)//如果GPF5被按下,读取到低电平{delay(100);//延时去抖动,这里只是一个大概的延时值if(!key)//再次判断flag=1;//返回"1"elseflag=0;}elseflag=0;}4)如何初始化DRAM,从而实现程序下载并在线调试?配置SDRAM的代码如下所示setmem0x53000000,0x00000000,32setmem0x4a000008,0xffffffff,32setmem0x4a00001c,0x00007fff,32setmem0x48000000,0x2212d110,32setmem0x48000004,0x00000f40,32setmem0x48000008,0x00002e50,32setmem0x4800000c,0x00002e50,32setmem0x48000010,0x00002e50,32setmem0x48000014,0x00002e50,32setmem0x48000018,0x00002e50,32setmem0x4800001c,0x00018005,32setmem0x48000020,0x00018005,32setmem0x48000024,0x00960542,32setmem0x48000028,0x00000032,32setmem0x4800002c,0x00000030,32setmem0x48000030,0x00000030,325)尝试实现利用按键切换控制跑马灯的顺序轮换(不是控制其轮换方向,而是在有按键按下并松开后实现一次跑马灯切换)。代码如下:intmain(){intcount=0;charkey=rGPFDAT&(1<<5);//charolddir=0;port_init();while(1){key=rGPFDAT&(1<<5);//只有当按过以后flag才=1if(!key) flag=1; if(flag==1)//如果按过了下去 { switch(count){case0:rGPCDAT=rGPCDAT&GPC5_ON;rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;delay(400);break;case1:rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;delay(400);break;case2:rGPCDAT=rGPCDAT&GPC7_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC6_OFF;delay(400);break;default:break;}}if(count==2){count=-1; flag=0;//标志位清零灯就不亮了 } count++;}}实验六ARM硬件接口实验2外部中断实验实验目的(1)通过实验掌握ARM处理器的中断方式和中断处理。(2)熟悉S3C2440X的中断控制寄存器的使用;(3)理解S3C2440X的中断处理机制(4)熟练掌握如何进行ARM处理器中断处理的软件编程方法。(5)掌握生成离线运行(Release模式)程序的开发环境设置方法。(6)掌握通过J-link向Norflash烧些程序的方法。实验设备硬件:北京博创UP-TECH三合一实验箱,J-Link仿真器套件,PC机软件:ADS1.2集成开发环境实验内容硬件电路和前面的实验五完全相同。这里将按钮开关所连接的GPF5引脚设定为外部中断EINT5,中断模式位IRQ,在中断服务程序中完成LED灯的切换,即正常状态时LED5灯亮,按下按钮开关时LED6灯亮。参考程序:(1)初始化汇编程序;**************************************************************;File:head.S;功能:初始化,设置中断模式、系统模式的栈,设置好中断处理函数;****************************************************************IMPORTMain;声明外部函数IMPORTport_initIMPORTeint_initIMPORTEINT_HandleIMPORTdisable_watch_dogAREAhead,CODE,READONLYENTRYCODE32start;程序入口点;****************************************************************;中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用;****************************************************************;0x00:复位中断向量地址bReset;0x04:未定义指令中止模式的向量地址HandleUndefbHandleUndef;0x08:管理模式的向量地址,通过SWI指令进入此模式HandleSWIbHandleSWI;0x0c:指令预取终止导致的异常的向量地址HandlePrefetchAbortbHandlePrefetchAbort;0x10:数据访问终止导致的异常的向量地址HandleDataAbortbHandleDataAbort;0x14:保留HandleNotUsedbHandleNotUsed;0x18:中断模式的向量地址bHandleIRQ;0x1c:快中断模式的向量地址HandleFIQbHandleFIQResetldrsp,=4096;设置栈指针,以下都是C函数,调用前需要设好栈bldisable_watch_dog;关闭WATCHDOG,否则CPU会不断重启;切换至用户模式;msrcpsr_c,#0xd0;11010000msrcpsr_c,#0xd2;进入中断模式ldrsp,=3072;设置中断模式栈指针msrcpsr_c,#0xd3;进入管理模式ldrsp,=4096;设置管理模式栈指针,;其实复位之后,CPU就处于管理模式,;前面的“ldrsp,=4096”完成同样的功能,此句可省略blport_init;初始化LED的GPIO管脚,在main.c中bleint_init;调用中断初始化函数,在main.c中msrcpsr_c,#0x5f;设置I-bit=0,开IRQ中断ldrlr,=halt_loop;设置返回地址ldrpc,=Main;调用main函数halt_loopbhalt_loopHandleIRQsublr,lr,#4;计算返回地址stmdbsp!,{r0-r12,lr};保存使用到的寄存器;注意,此时的sp是中断模式的sp;初始值是上面设置的3072ldrlr,=int_return;设置调用ISR即EINT_Handle函数后的返回地址ldrpc,=EINT_Handle;调用中断服务函数,在interrupt.c中int_returnldmiasp!,{r0-r12,pc}^;中断返回,^表示将spsr的值复制到cpsrEND(2)C语言处理程序/***************************************************************File:main.c*功能:主函数,端口初始化,中断初始化、中断处理等函数****************************************************************/#include"s2440addr.h"#defineGPC5_ON~(1<<5)#defineGPC5_OFF(1<<5)#defineGPC6_ON~(1<<6)#defineGPC6_OFF(1<<6)#defineGPC7_ON~(1<<7)#defineGPC7_OFF(1<<7)/**********KEY对应GPF5************/#defineGPF5_eint(0x2<<(5*2))#defineGPF5_mask(3<<(5*2))/*************端口初始化***************/voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口设置为输出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引脚上拉rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口灭掉}/********关闭WATCHDOG,否则CPU会不断重启******************/voiddisable_watch_dog(){rWTCON=0;//关闭WATCHDOG很简单,往这个寄存器写0即可}/********************中断初始化***************************/voideint_init(){//key0对应的引脚设为中断引脚EINT5rGPFCON&=~GPF5_mask;rGPFCON|=GPF5_eint;//对于EINT5,需要在EINTMASK寄存器中使能它rEINTMASK&=~(1<<5);rINTMSK&=~(1<<4);//EnableEINT4_7interrupt}/********************中断处理***************************/voidEINT_Handle()//中断处理函数{//清中断rEINTPEND|=(1<<5);//EINT4_7合用IRQ4rSRCPND|=1<<4;rINTPND|=1<<4;//点亮LED6rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;rGPCDAT=rGPCDAT&GPC6_ON;}/********************main函数***************************/intMain(){while(1){rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;rGPCDAT=rGPCDAT&GPC5_ON;};return(0);}实验要求(1)按照2.3节介绍的方法,在ADS下创建一个工程ext_interrupt,并将前面示例程序加入工程。按照上面的介绍进行环境设置,并进行程序写入。关掉实验箱电源,将其核心板上的拨动开关拨到右边Nor的位置,观察程序运行结果。按下INTKEY按钮,再次观察程序运行效果。(2)实验过程中请记录并思考以下内容:1)打开s2440addr.h头文件,观察并分析其内容。2)分析中断控制程序的结构。3)仔细分析中断初始化程序和中断处理程序中寄存器的设置方法,并理解其含义。4)总结中断程序的设计方法。实验截图:实验练习题答案打开s2440addr.h头文件,观察并分析其内容。S2440.h的部分代码如下图所示#ifndef__2440ADDR_H__#define__2440ADDR_H__#ifdef__cplusplusextern"C"{#endif//#include"option.h"//Memorycontrol#definerBWSCON(*(volatileunsigned*)0x48000000)//Buswidth&waitstatus#definerBANKCON0(*(volatileunsigned*)0x48000004)//BootROMcontrol#definerBANK

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论