ARM 汇编在开发板上的应用

3

我目前正在操作一个附有应用板的LPC 2378。风扇上有几个组件,其中两个是风扇和加热器。

如果将端口4的第6位和第7位连接到风扇(电机控制器),则以下代码将打开风扇:

  FanOn
  STMFD r13!,{r0,r5,r14}      ; Push r0, r5 and LR
  LDR R5, =FIO4PIN            ; Address of FIO4PIN
  LDR r0, [r5]                ; Read current Port4
  ORR r0, r0, #0x80
  STR r0, [r5]                ; Output
  LDMFD r13!,{r0,r5,r14}      ; Pop r0, r5 and LR
  mov pc, r14                 ; Put link register back into PC

如何重写此代码块以打开连接到端口 4 的位 5 的加热器(将该位设置为1将打开它,将其设置为0将关闭它)。
;==============================================================================
; Turn Heater On
;==============================================================================
heaterOn
  STMFD r13!,{r0,r5,r14}      ; Push r0, r5 and LR
  LDR R5, =FIO4PIN            ; Address of FIO4PIN
  LDR r0, [r5]                ; Read current Port4
  ORR r0, r0, #0x20
  STR r0, [r5]                ; Output
  LDMFD r13!,{r0,r5,r14}      ; Pop r0, r5 and LR
  mov pc, r14                 ; Put link register back into PC     
;==============================================================================
; Turn The Heater Off
;==============================================================================        
heaterOff
  STMFD r13!,{r0,r5,r14}      ; Push r0, r5 and LR
  LDR R5, =FIO4PIN            ; Address of FIO4PIN
  LDR r0, [r5]                ; Read current Port4
  AND r0, r0, #0xDF
  STR r0, [r5]                ; Output
  LDMFD r13!,{r0,r5,r14}      ; Pop r0, r5 and LR
  mov pc, r14                 ; Put link register back into PC   
2个回答

1

ORR指令打开一位,#0x80常量确定位(在这种情况下,只有第7位被打开)。要关闭位,您需要一个AND指令并计算适当的掩码(例如,要关闭第7位,您将AND与常量# 0x7F)。位5的适当常量是#0x20#0xDF


1

就我理解的代码而言,风扇仅连接到位7(如果从0开始计数)。

以下行代码负责打开风扇位:

ORR r0, r0, #0x80

您正在将“掩码”中为1的所有位设置为1。由于掩码是0x80,即二进制1000 0000,它只打开第7位。

现在,如果您需要打开加热器而不是风扇,并且您必须在同一端口上设置第5位而不是第7位,则只需更改该行中的掩码。新掩码应为二进制0010 0000,即十六进制0x20,因此新代码应为:

ORR r0, r0, #0x20

此外,如果您想在稍后某个时间关闭加热器,则可以通过取消设置位5来实现,即使用一个掩码进行与运算,在除了位5之外的所有位置上都有1。如果按位与的助记符是BIC,则该行代码将如下所示:
BIC r0, r0, 0xDF

现在,我已经好几个月没有做过汇编了,但如果我没有记错的话,你给出的代码片段实际上是一个子程序。您可以使用类似于callFanOn地址的方式从主功能中调用它。对我来说,这个子程序以一种保留它所使用的所有寄存器的方式很好,例如,在第一行将它们推入堆栈中,并在最后恢复它们。

因此,要重复使用该代码,您只需编写一个新的子程序来打开加热器,以及一个用于关闭每个设备的子程序(如果需要),并仅更改每个子程序的标签/子程序名称,例如FanOffHeaterOn...

由于它们都保留了所有寄存器,因此您可以顺序使用它们而不必担心。


我认为应该是BIC(虽然也可能是AND),所以BIC r0,r0,0xDF?我不想看起来好像偏离了原始问题。既然问题是“如何重用代码”,那么如果风扇和加热器都按顺序关闭,我是否需要使用不同的寄存器? - user1080390
@user1080390 我已经在评论中回答了你的问题。你应该将这些答案编辑到问题中,扩展一下问题,这不会伤害任何人。我认为你不需要在问题中放置答案程序代码,但这只是我的主观意见:D - penelope

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接