سؤال

Here are my defines:

/* 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))

Code:

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

I'm programming for the LPC2148 and I'm trying to write ARM assembler code to move the contents of P0.7 to P0.20. I'm not familiar at all with assembly syntax so I'm getting all kinds of compile errors when I try to fix this code. How can I easily move the bit of P0.7 to P0.20 (in assembler code)?


Tried this in C code:

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

But didn't work either.. not getting any output on P0.20.


Tried simulating PWM in C code:

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

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

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

Tried unconditionally setting the value of P0.20:

//IOSET = 0x00100000;    // commenting out to toggle between setting and clearing
IOCLR = 0x00100000;
هل كانت مفيدة؟

المحلول 2

I realized why I couldn't do what I wanted to do. I confused pins/ports with registers. What I thought I'd do was simply connect the output of P0.7 to P0.20 (which is probably possible by passing values to working registers) but my teacher explained to me that PINSEL is used to select the function of a given port and that some functions (such as PWM) can only be bound to specified registers (found in the table of PINSEL in the LPC2xxx manual.

نصائح أخرى

On the LPC2148 IO0SET is at address 0xE0028004 and IO0CLR is at address 0xE002800C and IO0PIN is at 0xE0028000.

Here is an assembly solution, there are many ways to do this.

.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

assemble this with as

arm-whatever-as copy.s -o copy.o

then call it from your C code

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

and link it or add it to gcc (and gcc will pass it to the linker)

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

you could also easily pass in the pin number (mask is better) for the two and have it reusable.

real assembly is so much easier than inline, it is an even longer research project to figure out how to turn the real assembly into inline assembly properly (for each compiler and possibly version as it will vary, assembly language tends to be more portable)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top