笔者不再对MDK工程的搭建或Proteus LPC2103仿真电路的搭建进行详细讲解,在文章的末尾给出了流水灯汇编实现的MDK工程以及Proteus工程,读者自行学习验证。
- 新建MDK工程LEDs,选择NXP下LPC2103目标芯片。
- 我们采用的是汇编实现,选择“否”不需要加入启动代码到工程。
- 新建一个LEDs.s的汇编源代码文件并加入工程,用汇编实现流水灯代码。
PINSEL0 EQU 0xE002C000
IO0PIN EQU 0xE0028000
IO0SET EQU 0xE0028004
IO0DIR EQU 0xE0028008
IO0CLR EQU 0xE002800C
AREA RESET, CODE, READONLY
ARM ; 表明为ARM代码
ENTRY ; 代码入口
Start
LDR R0, =PINSEL0 ; 引脚功能寄存器1设置
LDR R1, [R0] ; 获得寄存器值
LDR R2, =0xffff
BIC R1, R1, R2 ; 清除R1的低16位
STR R1, [R0]; 写回寄存器P0.0~P0.7为GPIO功能
LDR R0, =IO0DIR ; IO口输入输出控制
LDR R1, [R0] ; 获得寄存器值
ORR R1, R1, #0xff ; 置位低8位(输出)
STR R1, [R0] ;P0.0~P0.7为输出
LDR R0, =IO0PIN ; 引脚值寄存器
LDR R1, [R0] ; 获得寄存器的值
ORR R1, R1, #0xff ; 置位低8位,输出高电平
STR R1, [R0] ; LED1~LED8灭
LDR R0, =IO0SET
LDR R1, =IO0CLR
Loop
MOV R2, #(1<<0)
STR R2, [R1] ; LED0亮
BL Delay_1s
STR R2, [R0] ; LED0灭
MOV R2, #(1<<1)
STR R2, [R1] ; LED1亮
BL Delay_1s
STR R2, [R0] ; LED1灭
MOV R2, #(1<<2)
STR R2, [R1] ; LED2亮
BL Delay_1s
STR R2, [R0] ; LED2灭
MOV R2, #(1<<3)
STR R2, [R1] ; LED3亮
BL Delay_1s
STR R2, [R0] ; LED3灭
MOV R2, #(1<<4)
STR R2, [R1] ; LED4亮
BL Delay_1s
STR R2, [R0] ; LED4灭
MOV R2, #(1<<5)
STR R2, [R1] ; LED5亮
BL Delay_1s
STR R2, [R0] ; LED5灭
MOV R2, #(1<<6)
STR R2, [R1] ; LED6亮
BL Delay_1s
STR R2, [R0] ; LED6灭
MOV R2, #(1<<7)
STR R2, [R1] ; LED7亮
BL Delay_1s
STR R2, [R0] ; LED7灭
B Loop
; 软件延时函数,arm汇编较精确计算,延时1s
; 由于暂未设置时钟,系统时钟为外部晶体时钟12M
Delay_1s
LDR R12, =3000000 ; ARM CLOCK 12M
Delay1
SUBS R12, R12, #1 ; 指令执行需1个ARM CLOCK
BNE Delay1 ; 跳转会清流水线,3个ARM CLOCK
BX LR
; Delay1处循环一次需(1+3)=4个ARM CLOCK
; 共延时R12*(1+3)=12000000个ARM CLOCK,即1s
END
在工程属性中点选Create HEX File,编译后会生成hex文件,这个文件是加载进Proteus仿真或者通过ISP下载进LPC2000系列芯片的代码文件。
点击编译后,会给出段未匹配到的警告,不用管,正确生成hex代码文件后,可通过MDK的Debug进行仿真查看代码的运行。
通过Proteus搭建电路,加载进生成的hex文件,可以很直观的观察流水灯,Proteus设置12M的仿真时钟时,已无法实时仿真了,仿真的时间有一定的延长。