C 用于开发板的ARM组件
我目前正在摆弄一个LPC2378,它附带了一个应用程序板。风扇上有几个部件,其中两个是风扇和加热器 如果端口4的第6位和第7位连接到风扇(电机控制器),则以下代码将开启风扇:C 用于开发板的ARM组件,c,assembly,embedded,arm,C,Assembly,Embedded,Arm,我目前正在摆弄一个LPC2378,它附带了一个应用程序板。风扇上有几个部件,其中两个是风扇和加热器 如果端口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
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
ORR
指令打开一个位,#0x80
常量确定该位(在这种情况下,仅打开位7)。要关闭位,您需要一条AND指令并计算适当的掩码(例如,要关闭位7,您需要使用常量#0x7F和)。位5的适当常数为#0x20
和#0xDF
据我对代码的理解,风扇仅连接到位7(如果位从0开始计算)
以下线路负责打开风扇钻头:
ORR r0, r0, #0x80
您正在将“掩码”中的所有位1设置为1。由于掩码是二进制的0x80
,即1000 0000
,因此它只打开位7
现在,如果需要打开加热器而不是风扇,并且必须设置位5而不是7(在同一端口上),则只需更改该行中的掩码。新掩码应为二进制,即六进制的0x20
,因此新代码应为:
ORR r0, r0, #0x20
另外,如果您想在以后某个时候关闭加热器,您可以通过只取消设置位5来实现,通过使用除位5外到处都是1的掩码进行anding。如果按位and的助记符为BIC
,则该行为:
BIC r0, r0, 0xDF
现在,我已经好几个月没有做过任何汇编了,但是如果我没有大错特错的话,您给出的代码片段实际上是一个子程序。您可以使用类似于call
的功能从主功能调用它,然后将其调用到FanOn
地址。而且,在我看来,子例程在某种程度上很好,它保留了它使用的所有寄存器,例如,它将它们推到第一行的堆栈中,并在最后恢复它们
因此,要重复使用代码,您只需编写一个用于打开加热器的新子例程,以及一个用于关闭每个东西的子例程(如果需要),并且只更改每个子例程的标签/子例程名称,例如FanOff
,HeaterOn
因为它们都保存了所有寄存器,所以您可以顺序使用它们而不用担心。我相信它是BIC(虽然可能是AND),所以BIC r0、r0、0xDF?我不想让人觉得我偏离了原来的问题。由于是“如何重用代码”,如果风扇和加热器都按顺序关闭,我是否需要使用不同的寄存器?@user1080390我在评论中为您的问题添加了答案。你应该在问题中编辑它,扩展它,不会伤害任何人。我不认为你需要在问题中加入答案程序代码,但这只是我的主观意见:D