将寄存器的内容移动到另一个寄存器中

时间:2012-12-06 13:37:17

标签: assembly arm move cpu-registers lpc

以下是我的定义:

/* General Purpose Input/Output (GPIO) */
#define IOPIN          (*((volatile unsigned long *) 0xE0028000))
#define IOSET          (*((volatile unsigned long *) 0xE0028004))
#define IODIR          (*((volatile unsigned long *) 0xE0028008))
#define IOCLR          (*((volatile unsigned long *) 0xE002800C))

代码:

void put_on_other_port (void) {
asm("LDR R0, 0x00000080");
asm("STR R0, [0x00100000]");
}

我正在为LPC2148编程,我正在尝试编写ARM汇编程序代码以将P0.7的内容移动到P0.20。我对汇编语法一点也不熟悉所以当我尝试修复这段代码时,我遇到了各种编译错误。 如何轻松地将P0.7的位移到P0.20(用汇编代码)?


用C代码试过:

IODIR |= 0x00100000;
.
.
.
if (IOPIN & 0x00000080)
            IOSET = 0x00100000;
        else
            IOCLR = 0x00100000;

但是也没有工作......没有在P0.20上获得任何输出。


尝试在C代码中模拟PWM:

IODIR |= 0x00100000;
.
.
.
int i;

IOSET = 0x00100000;
for (i = 0; i < 10000; i++);

IOCLR = 0x00100000;
for (i = 0; i < 10000; i++);

尝试无条件地设置P0.20的值:

//IOSET = 0x00100000;    // commenting out to toggle between setting and clearing
IOCLR = 0x00100000;

2 个答案:

答案 0 :(得分:1)

在LPC2148上,IO0SET位于地址0xE0028004,IO0CLR位于地址0xE002800C,IO0PIN位于0xE0028000。

这是一个装配解决方案,有很多方法可以做到这一点。

.globl copy_gpio_pin_state
copy_gpio_pin_state:
  ldr r0,=0xE0028000
  mov r2,#0x00100000
  ldr r1,[r0,#0x00]
  tst r1,#0x80
  streq r2,[r0,#0x0C]
  strne r2,[r0,#0x04]
  bx lr

将其与as

组合在一起
arm-whatever-as copy.s -o copy.o

然后从你的C代码中调用它

void copy_gpio_pin_state ( void );
...
copy_gpio_pin_state();

并将其链接或添加到gcc(并且gcc会将其传递给链接器)

arm-whatever-gcc myprog.c copy.o -o ...
or
arm-whatever-ld ... myprog.o copy.o -o ...

你也可以轻松传入两个引脚号(掩码更好),并让它可以重复使用。

真正的程序集比内联容易得多,它是一个更长的研究项目,用于弄清楚如何将实际的程序集正确地转换为内联汇编(对于每个编译器和可能的版本,因为它会有所不同,汇编语言往往更多便携式)

答案 1 :(得分:0)

我意识到为什么我不能做我想做的事。 我把引脚/端口与寄存器混淆了。我认为我要做的只是将P0.7的输出连接到P0.20(这可能通过将值传递给工作寄存器来实现)但我的老师向我解释说PINSEL被使用了选择给定端口的功能,并且某些功能(如PWM)只能绑定到指定的寄存器(可在LPC2xxx手册的PINSEL表中找到。