ARM嵌入式设计实验.docx
《ARM嵌入式设计实验.docx》由会员分享,可在线阅读,更多相关《ARM嵌入式设计实验.docx(21页珍藏版)》请在冰豆网上搜索。
ARM嵌入式设计实验
汇编指令实验一
COUNTEQU0x40003100;定义一个变量,地址为0x40003100
AREAExample2,CODE,READONLY;声明代码段Example2
ENTRY;标识程序入口
CODE32;声明32位ARM指令
STARTLDRR1,=COUNT;R1<=COUNT
MOVR0,#0;R0<=0
STRR0,[R1];[R1]<=R0,即设置COUNT为0
LOOPLDRR1,=COUNT
LDRR0,[R1];R0<=[R1]
ADDR0,R0,#1;R0<=R0+1
CMPR0,#10;R0与10比较,影响条件码标志
MOVHSR0,#0;若R0大于等于10,则此指令执行,R0<=0
STRR0,[R1];[R1]<=R0,即保存COUNT
BLOOP
END
汇编指令实验二
;文件名:
TEST4.S
;功能:
计算X的n次方的值
;说明:
X和n均为无符号整数
XEQU9;定义X的值为9
nEQU8;定义n的值为8
AREAExample4,CODE,READONLY;声明代码段Example4
ENTRY;标识程序入口
CODE32;声明32位ARM指令
STARTLDRSP,=0x40003F00;设置堆栈(满递减堆栈,使用STMFD/LMDFD指令)
LDRR0,=X
LDRR1,=n
BLPOW;调用子程序POW,返回值为R0
HALTBHALT
;名称:
POW
;功能:
整数乘方运算。
;入口参数:
R0底数
;R1指数
;出口参数:
R0运算结果
;占用资源:
R0、R1
;说明:
本子程序不考虑溢出问题
POW
STMFDSP!
{R1-R12,LR};寄存器入栈保护
MOVSR2,R1;将指数值复制到R2,并影响条件码标志
MOVEQR0,#1;若指数为0,则设置R0=1
BEQPOW_END;若指数为0,则返回
CMPR2,#1
BEQPOW_END;若指数为1,则返回。
(此时R0没有被更改)
MOVR1,R0;设置DO_MUL子程序的入口参数R0和R1
SUBR2,R2,#1;计数器R2=指数值减1
POW_L1BLDO_MUL;调用DO_MUL子程序,R0=R1*R0
SUBSR2,R2,#1;每循环一次,计数器R2减1
BNEPOW_L1;若计数器R2不为0,跳转到POW_L1
POW_ENDLDMFDSP!
{R1-R12,PC};寄存器出栈,返回
;名称:
DO_MUL
;功能:
32位乘法运算。
;入口参数:
R0乘数
;R1被乘数
;出口参数:
R0计算结果
;占用资源:
R0、R1
;说明:
本子程序不会破坏R1
DO_MULMULR0,R1,R0;R0=R1*R0
MOVPC,LR;返回
END
工程模板应用试验
(1)
Startup.s程序:
;起动文件。
初始化C程序的运行环境,然后进入C程序代码。
IMPORT|Image$$RO$$Limit|
IMPORT|Image$$RW$$Base|
IMPORT|Image$$ZI$$Base|
IMPORT|Image$$ZI$$Limit|
IMPORTMain;声明C程序中的Main()函数
AREAStart,CODE,READONLY;声明代码段Start
ENTRY;标识程序入口
CODE32;声明32位ARM指令
ResetLDRSP,=0x40003F00
;初始化C程序的运行环境
LDRR0,=|Image$$RO$$Limit|
LDRR1,=|Image$$RW$$Base|
LDRR3,=|Image$$ZI$$Base|
CMPR0,R1
BEQLOOP1
LOOP0CMPR1,R3
LDRCCR2,[R0],#4
STRCCR2,[R1],#4
BCCLOOP0
LOOP1LDRR1,=|Image$$ZI$$Limit|
MOVR2,#0
LOOP2CMPR3,R1
STRCCR2,[R3],#4
BCCLOOP2
BMain;跳转到C程序代码Main()函数
END
TEST.C程序:
#defineuint8unsignedchar
#defineuint32unsignedint
#defineN100
uint32sum;
//使用加法运算来计算1+2+3+...+(N-1)+N的值。
(N>0)
voidMain(void)
{uint32i;
sum=0;
for(i=0;i<=N;i++)
{sum+=i;
}
while
(1);
}
(2)
Startup.s程序:
;起动文件。
初始化C程序的运行环境,然后进入C程序代码。
IMPORT|Image$$RO$$Limit|
IMPORT|Image$$RW$$Base|
IMPORT|Image$$ZI$$Base|
IMPORT|Image$$ZI$$Limit|
IMPORTMain;声明C程序中的Main()函数
AREAStart,CODE,READONLY;声明代码段Start
ENTRY;标识程序入口
CODE32;声明32位ARM指令
ResetLDRSP,=0x40003F00
;初始化C程序的运行环境
LDRR0,=|Image$$RO$$Limit|
LDRR1,=|Image$$RW$$Base|
LDRR3,=|Image$$ZI$$Base|
CMPR0,R1
BEQLOOP1
LOOP0CMPR1,R3
LDRCCR2,[R0],#4
STRCCR2,[R1],#4
BCCLOOP0
LOOP1LDRR1,=|Image$$ZI$$Limit|
MOVR2,#0
LOOP2CMPR3,R1
STRCCR2,[R3],#4
BCCLOOP2
BMain;跳转到C程序代码Main()函数
END
ADD.S程序:
;加法函数,原型为uint32Add(uint32x,uint32y)。
EXPORTAdd
AREAAddC,CODE,READONLY;声明代码段AddC
ENTRY;标识程序入口
CODE32;声明32位ARM指令
AddADDR0,R0,R1;输入参数x为R0,y为R1
MOVPC,LR;返回值为R0
END
TEST.C程序:
#defineuint8unsignedchar
#defineuint32unsignedint
externuint32Add(uint32x,uint32y);
uint32sum;
//调用汇编程序Add实现加法运算
voidMain(void)
{sum=Add(555,168);
while
(1);
}
GPIO输出控制实验
/*******************************************************************
*文件名:
main.c
*功能:
LED显示控制。
*通过GPIO直接控制8个LED产生流水灯效果
*说明:
将跳线JP23全部短接,JP15跳线全部断开。
*这个警告可忽略,C2892E:
signedconstantoverflow
********************************************************************/
#include"config.h"
#defineLED11<<16//P2.16
#defineLED21<<17//P2.17
#defineLED31<<18//P2.18
#defineLED41<<19//P2.19
#defineLED51<<20//P2.20
#defineLED61<<21//P2.21
#defineLED71<<22//P2.22
#defineLED81<<23//P2.23
#defineLEDCON0x00ff0000
constuint32DISP_TAB[8]={0xff01ffff,0xff02ffff,0xff04ffff,0xff08ffff,
0xff10ffff,0xff20ffff,0xff40ffff,0xff80ffff};
/********************************************************************
*名称:
DelayNS()
*功能:
长软件延时
*入口参数:
dly延时参数,值越大,延时越久
*出口参数:
无
********************************************************************/
voidDelayNS(uint32dly)
{uint32i;
for(;dly>0;dly--)
{
for(i=0;i<5000;i++);
}
}
/********************************************************************
*名称:
main()
*功能:
根据表DISP_TAB来控制LED显示。
********************************************************************/
intmain(void)
{uint8i;
/*PINSEL2使用启动代码的默认配置,切勿任意配置PINSEL2,否则总线会受到干扰*/
IO2DIR=LEDCON;//配置LED控制I/O方向
while
(1)
{
for(i=0;i<8;i++)
{
IO2CLR=DISP_TAB[i];//输出LED显示数据
DelayNS(10);//延时
IO2SET=0xffffffff;
}
}
return(0);
}
步进电机实验
/********************************************************************
*文件名:
main.c
*功能:
LED显示控制。
*通过GPIO控制步进电机
*说明:
将跳线JP14和JP19全部短接。
********************************************************************/
#include"config.h"
#defineLED11<<16//P2.16
#defineMOTOA1<<24//P2.24
#defineMOTOB1<<25//P2.25
#defineMOTOC1<<26//P2.26
#defineMOTOD1<<27//P2.27
#defineLEDCON0x00ff0000//LED控制字
#defineMOTOCON0x0f000000//MOTO控制字
#defineGPIOSET(PIN)IO2SET=PIN//方便修改置位端口
#defineGPIOCLR(PIN)IO2CLR=PIN//方便修改清位端口
voidDelayNS(uint32dly);
voidMOTO_Mode1(uint8i);//A-B-C-D
voidMOTO_Mode2(uint8i);//AB-BC-CD-DA-AB
voidMOTO_Mode3(uint8i);//A-AB-B-BC-C-CD-D-DA-A
/********************************************************************
*名称:
main()
*功能:
根据表DISP_TAB来控制LED显示。
********************************************************************/
intmain(void)
{
/*PINSEL2使用启动代码的默认配置,切勿任意配置PINSEL2,否则总线会受到干扰*/
IO2DIR=LEDCON|MOTOCON;//配置LED控制I/O方向
MOTO_Mode1(10);//A-B-C-D
//MOTO_Mode2(10);//AB-BC-CD-DA-AB
//MOTO_Mode3(10);//A-AB-B-BC-C-CD-D-DA-A
return(0);
}
/********************************************************************
*名称:
DelayNS()
*功能:
长软件延时
*入口参数:
dly延时参数,值越大,延时越久
*出口参数:
无
********************************************************************/
voidDelayNS(uint32dly)
{uint32i;
for(;dly>0;dly--)
{
for(i=0;i<5000;i++);
}
}
/********************************************************************
*名称:
MOTO_Mode1()
*功能:
单四拍程序
*入口参数:
uint8i延时参数,值越大,延时越久
*出口参数:
无
********************************************************************/
voidMOTO_Mode1(uint8i)//A-B-C-D
{
while
(1)
{
GPIOCLR(LED1);//点亮LED1,方便监视程序状态
/*A*/
GPIOSET(MOTOA);
DelayNS(i);
GPIOCLR(MOTOA);
/*B*/
GPIOSET(MOTOB);
DelayNS(i);
GPIOCLR(MOTOB);
/*C*/
GPIOSET(MOTOC);
DelayNS(i);
GPIOCLR(MOTOC);
GPIOSET(LED1);//熄灭LED1,方便监视程序状态
/*D*/
GPIOSET(MOTOD);
DelayNS(i);
GPIOCLR(MOTOD);
}
}
/********************************************************************
*名称:
MOTO_Mode2()
*功能:
双四拍程序
*入口参数:
uint8i延时参数,值越大,延时越久
*出口参数:
无
********************************************************************/
voidMOTO_Mode2(uint8i)//AB-BC-CD-DA-AB
{
while
(1)
{
GPIOCLR(LED1);//点亮LED1,方便监视程序状态
/*AB*/
GPIOSET(MOTOA);
GPIOSET(MOTOB);
DelayNS(i);
GPIOCLR(MOTOA);
GPIOCLR(MOTOB);
/*BC*/
GPIOSET(MOTOB);
GPIOSET(MOTOC);
DelayNS(i);
GPIOCLR(MOTOB);
GPIOCLR(MOTOC);
GPIOSET(LED1);//熄灭LED1,方便监视程序状态
/*CD*/
GPIOSET(MOTOC);
GPIOSET(MOTOD);
DelayNS(i);
GPIOCLR(MOTOC);
GPIOCLR(MOTOD);
/*DA*/
GPIOSET(MOTOD);
GPIOSET(MOTOA);
DelayNS(i);
GPIOCLR(MOTOD);
GPIOCLR(MOTOA);
}
}
/********************************************************************
*名称:
MOTO_Mode3()
*功能:
单双八拍程序
*入口参数:
uint8i延时参数,值越大,延时越久
*出口参数:
无
********************************************************************/
voidMOTO_Mode3(uint8i)//A-AB-B-BC-C-CD-D-DA-A
{
while
(1)
{
GPIOCLR(LED1);//点亮LED1,方便监视程序状态
/*A*/
GPIOSET(MOTOA);
DelayNS(i);
GPIOCLR(MOTOA);
/*AB*/
GPIOSET(MOTOA);
GPIOSET(MOTOB);
DelayNS(i);
GPIOCLR(MOTOA);
GPIOCLR(MOTOB);
/*B*/
GPIOSET(MOTOB);
DelayNS(i);
GPIOCLR(MOTOB);
/*BC*/
GPIOSET(MOTOB);
GPIOSET(MOTOC);
DelayNS(i);
GPIOCLR(MOTOB);
GPIOCLR(MOTOC);
/*C*/
GPIOSET(MOTOC);
DelayNS(i);
GPIOCLR(MOTOC);
GPIOSET(LED1);//熄灭LED1,方便监视程序状态
/*CD*/
GPIOSET(MOTOC);
GPIOSET(MOTOD);
DelayNS(i);
GPIOCLR(MOTOC);
GPIOCLR(MOTOD);
/*D*/
GPIOSET(MOTOD);
DelayNS(i);
GPIOCLR(MOTOD);
/*DA*/
GPIOSET(MOTOD);
GPIOSET(MOTOA);
DelayNS(i);
GPIOCLR(MOTOD);
GPIOCLR(MOTOA);
}
}
外部中断实验
/********************************************************************
*文件名:
main.c
*功能:
使用外部中断3进行B1的控制,每当有一次中断时,即取反B1控制口,
*使用非向量中断方式。
*说明:
将跳线器JP9、JP22短接,JP20断开。
按下KEY1观察BUZZER效果。
********************************************************************/
#include"config.h"
#defineBEEPCON1<<7//P0.7引脚控制B1,低电平蜂鸣,1<<7等价于0x80
/********************************************************************
*名称:
IRQ_Eint3()
*功能:
外部中断EINT3服务函数,取反B1控制口。
*入口参数:
无
*出口参数:
无
********************************************************************/
void__irqIRQ_Eint3(void)
{uint32i;
i=IO0SET;//读取当前B1控制值
if((i&BEEPCON)==0)//控制B1输出取反
{
IO0SET=BEEPCON;
}
else
{
IO0CLR=BEEPCON;
}
/*等待外部中断信号恢复为高电平(若信号保持为低电平,中断标志会一直置位)*/
while((EXTINT&1<<3)!
=0)
{
EXTINT=1<<3;//清除EINT3中断标志,1<<3等价于0x08
}
VICVectAddr=0;//向量中断结束
}
/********************************************************************
*名称:
main()
*功能:
初始化