嵌入式导论实验报告Guo-Lab1
ARM——Assembled and C
实验题目
熟悉实验环境和实验工具
实验目的
搭建实验环境——Keil,熟悉开发板EK-TM4C123GXL,熟悉C语言和汇编指令的编写
实验要求
开发板的LED灯闪烁不同颜色,生成波形,改变占空比,学会正确的调试开发板
实验源码和结果
- EK-TM4C123GXL
LED 电路图
- 使开发板的灯RGB闪烁
代码
使用C和Assemble混合编程
C:
int main(void)
{
uint_32_t status;
PortF_Init();
while(1)
{
switch(status)
case 0x01:
PortF_Output(BLUE);
break;
case 0x10:
PortF_Output(RED);
break;
case 0x00:
PortF_Output(GREEN);
break;
case 0x11:
PortF_Output(0);
break;
}
}
ASM:
GPIO_PORTF_DATA_R EQU 0x400253FC
GPIO_PORTF_DIR_R EQU 0x40025400
GPIO_PORTF_AFSEL_R EQU 0x40025420
GPIO_PORTF_PUR_R EQU 0x40025510
GPIO_PORTF_DEN_R EQU 0x4002551C
GPIO_PORTF_LOCK_R EQU 0x40025520
GPIO_PORTF_CR_R EQU 0x40025524
GPIO_PORTF_AMSEL_R EQU 0x40025528
GPIO_PORTF_PCTL_R EQU 0x4002552C
GPIO_LOCK_KEY EQU 0x4C4F434B ; Unlocks the GPIO_CR register
RED EQU 0x02
BLUE EQU 0x04
GREEN EQU 0x08
SW1 EQU 0x10 ; on the left side of the Launchpad board
SW2 EQU 0x01 ; on the right side of the Launchpad board
SYSCTL_RCGCGPIO_R EQU 0x400FE608
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
EXPORT Start
Start
BL PortF_Init ; initialize input and output pins of Port F
loop
LDR R0, =FIFTHSEC ; R0 = FIFTHSEC (delay 0.2 second)
BL delay ; delay at least (3*R0) cycles
BL PortF_Input ; read all of the switches on Port F
CMP R0, #0x01 ; R0 == 0x01?
BEQ sw1pressed ; if so, switch 1 pressed
CMP R0, #0x10 ; R0 == 0x10?
BEQ sw2pressed ; if so, switch 2 pressed
CMP R0, #0x00 ; R0 == 0x00?
BEQ bothpressed ; if so, both switches pressed
CMP R0, #0x11 ; R0 == 0x11?
BEQ nopressed ; if so, neither switch pressed
; if none of the above, unexpected return value
MOV R0, #(RED+GREEN+BLUE) ; R0 = (RED|GREEN|BLUE) (all LEDs on)
BL PortF_Output ; turn all of the LEDs on
B loop
sw1pressed
MOV R0, #BLUE ; R0 = BLUE (blue LED on)
BL PortF_Output ; turn the blue LED on
B loop
sw2pressed
MOV R0, #RED ; R0 = RED (red LED on)
BL PortF_Output ; turn the red LED on
B loop
bothpressed
MOV R0, #GREEN ; R0 = GREEN (green LED on)
BL PortF_Output ; turn the green LED on
B loop
nopressed
MOV R0, #0 ; R0 = 0 (no LEDs on)
BL PortF_Output ; turn all of the LEDs off
B loop
;------------delay------------
; Delay function for testing, which delays about 3*count cycles.
; Input: R0 count
; Output: none
ONESEC EQU 5333333 ; approximately 1s delay at ~16 MHz clock
QUARTERSEC EQU 1333333 ; approximately 0.25s delay at ~16 MHz clock
FIFTHSEC EQU 1066666 ; approximately 0.2s delay at ~16 MHz clock
delay
SUBS R0, R0, #1 ; R0 = R0 - 1 (count = count - 1)
BNE delay ; if count (R0) != 0, skip to 'delay'
BX LR ; return
;------------PortF_Init------------
; Initialize GPIO Port F for negative logic switches on PF0 and
; PF4 as the Launchpad is wired. Weak internal pull-up
; resistors are enabled, and the NMI functionality on PF0 is
; disabled. Make the RGB LED's pins outputs.
; Input: none
; Output: none
; Modifies: R0, R1, R2
PortF_Init
LDR R1, =SYSCTL_RCGCGPIO_R ; 1) activate clock for Port F
LDR R0, [R1]
ORR R0, R0, #0x20 ; set bit 5 to turn on clock
STR R0, [R1]
NOP
NOP ; allow time for clock to finish
LDR R1, =GPIO_PORTF_LOCK_R ; 2) unlock the lock register
LDR R0, =0x4C4F434B ; unlock GPIO Port F Commit Register
STR R0, [R1]
LDR R1, =GPIO_PORTF_CR_R ; enable commit for Port F
MOV R0, #0xFF ; 1 means allow access
STR R0, [R1]
LDR R1, =GPIO_PORTF_AMSEL_R ; 3) disable analog functionality
MOV R0, #0 ; 0 means analog is off
STR R0, [R1]
LDR R1, =GPIO_PORTF_PCTL_R ; 4) configure as GPIO
MOV R0, #0x00000000 ; 0 means configure Port F as GPIO
STR R0, [R1]
LDR R1, =GPIO_PORTF_DIR_R ; 5) set direction register
MOV R0,#0x0E ; PF0 and PF7-4 input, PF3-1 output
STR R0, [R1]
LDR R1, =GPIO_PORTF_AFSEL_R ; 6) regular port function
MOV R0, #0 ; 0 means disable alternate function
STR R0, [R1]
LDR R1, =GPIO_PORTF_PUR_R ; pull-up resistors for PF4,PF0
MOV R0, #0x11 ; enable weak pull-up on PF0 and PF4
STR R0, [R1]
LDR R1, =GPIO_PORTF_DEN_R ; 7) enable Port F digital port
MOV R0, #0xFF ; 1 means enable digital I/O
STR R0, [R1]
BX LR
;------------PortF_Input------------
; Read and return the status of the switches.
; Input: none
; Output: R0 0x01 if only Switch 1 is pressed
; R0 0x10 if only Switch 2 is pressed
; R0 0x00 if both switches are pressed
; R0 0x11 if no switches are pressed
; Modifies: R1
PortF_Input
LDR R1, =GPIO_PORTF_DATA_R ; pointer to Port F data
LDR R0, [R1] ; read all of Port F
AND R0,R0,#0x11 ; just the input pins PF0 and PF4
BX LR ; return R0 with inputs
;------------PortF_Output------------
; Set the output state of PF3-1.
; Input: R0 new state of PF
; Output: none
; Modifies: R1
PortF_Output
LDR R1, =GPIO_PORTF_DATA_R ; pointer to Port F data
STR R0, [R1] ; write to PF3-1
BX LR
ALIGN ; make sure the end of this section is aligned
END ; end of file
- 改变周期方波的占空比
加入nop可以改变占空比
代码
GPIO_PORTD_DATA_R EQU 0x400073FC
GPIO_PORTD_DIR_R EQU 0x40007400
GPIO_PORTD_LOCK_R EQU 0x4C4F434B
GPIO_PORTD_AFSEL_R EQU 0x40007420
GPIO_PORTD_DEN_R EQU 0x4000751C
SYSCTL_RCGCGPIO_R EQU 0x400FE108
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
EXPORT Start
GPIO_Init
; 1) activate clock for Port D
LDR R1, =SYSCTL_RCGCGPIO_R
LDR R0, [R1]
ORR R0, R0, #0x04
STR R0, [R1]
NOP
NOP
NOP
NOP
; 3) set direction register
LDR R1, =GPIO_PORTD_DIR_R
LDR R0, [R1]
ORR R0, R0, #0x04
BIC R0, R0, #0x01
STR R0, [R1]
; 4) regular port function
LDR R1, =GPIO_PORTD_AFSEL_R
LDR R0, [R1]
BIC R0,R0,#0x05
STR R0,[R1]
; 5) enable digital port
LDR R1, =GPIO_PORTD_DEN_R
LDR R0, [R1]
ORR R0, R0, #0x05
STR R0, [R1]
BX LR
Start
BL GPIO_Init
LDR R0, =GPIO_PORTD_DATA_R
loop
LDR R1,[R0]
AND R1,#0x01
EOR R1,#0x01
STR R1,[R0]
;------------
nop
nop
;------------
LSL R1,#2
STR R1,[R0]
B loop
loop
LDR R1,[R0]
AND R1,#0x01
EOR R1,#0x01
STR R1,[R0]
;------------
nop
nop
nop
nop
nop
nop
nop
;------------
LSL R1,#2
STR R1,[R0]
B loop
ALIGN; make sure the end of this section is aligned
END ; end of file
实验总结
1.C与汇编混合编程体会
可以用C去做一些主要演算主要处理,搭一个整体的逻辑框架,用汇编去做一些驱动函数,中断处理函数,或者对管脚和端口的设置函数。
2.实验使用到的ARM 指令总结
除了一些上学期学过的类似于MIPS和x86的寄存器和汇编指令,如ADD,SUB,MOV之外,学会使用新的指令
LDR指令的格式:
LDR{条件} 目的寄存器 <存储器地址>
作用:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。
ORR 指令的格式为:
ORR{条件}{S} 目的寄存器,操作数 1,操作数 2
ORR 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数 1应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数 1 的某些位。
STR指令的格式为:
STR{条件} 源寄存器,<存储器地址>
STR指令用亍从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,寻址方式灵活多样,使用方式可参考指令LDR。
BIC : 位清除(Bit Clear)
BIC{条件}{S}
BIC是在一个字中清除位的一种方法,与 OR 位设置是相反的操作。操作数 2 是一个 32 位位掩码(mask)。如果如果在掩码中设置了某一位,则清除这一位。未设置的掩码位指示此位保持不变。
3.遇到的问题
驱动问题,总是无法flush到板子上,尝试了各种办法最后使用舍友的电脑完成的实验。。。