7 votos

Son punteros tratados de manera diferente en AVR en comparación a decir x86?

Microcontrolador: ATtiny13

IDE: Atmel Studio

Estoy tratando de escribir un Hola Mundo con la solicitud por escrito de alta a puerto PB4.

Esto funciona bien:

int main(void)
{
    DDRB = 0x10;
    PORTB = 0x10;

    while(1)
    {
    }
}

Buscando en la definición de DDRB y PORTB, apuntan a 0x17 y 0x18, como se esperaba.

Esto, sin embargo, no funciona:

int main(void)
{
    char *dir = (void *)0x17;
    char *port = (void *)0x18;

    *dir = (unsigned int)0x10;
    *port = (unsigned int)0x10;

    while(1)
    {
    }
}

Es mi código mal, o tengo que hacer algo más para el uso de punteros?

23voto

user4245 Puntos 324

Los punteros a punteros. Que es lo que son. No se tratan de manera diferente a todos (¿cómo podría usted tratar de manera diferente?)

Las principales diferencias entre X86 y AVR son:

  • AVR es de 8 bits, X86 de 32 bits (o de 64 bits para la arquitectura x86_64), por lo que los punteros son de un tamaño diferente.
  • El AVR es Modificado de Harvard la arquitectura, así que hay más de un espacio de direcciones, por lo que usted tiene que asegurarse de que se hace referencia al derecho del espacio de direcciones.

También, el código no tiene ningún sentido:

char *dir = (void *)0x17;

Asignar un void * char *?

error: invalid conversion from ‘void*' to ‘char*'

No estoy creado para la compilación de la ATTiny13 en el momento, por lo que estos números son todas para el ATMega328p:

El acceso a DDRB y PORTB resultados en esta asamblea:

12c:    80 e1           ldi r24, 0x10   ; 16  
12e:    84 b9           out 0x04, r24   ; 4
130:    85 b9           out 0x05, r24   ; 5

El acceso a un puntero a una posición de la memoria de resultados en esta asamblea:

12c:    80 e1           ldi r24, 0x10   ; 16
12e:    80 93 17 00     sts 0x0017, r24
132:    80 93 18 00     sts 0x0018, r24

Como se puede ver, DDRB y PORTB no son variables normales. DDRB se define como:

#define DDRB _SFR_IO8(0x04)

y PORTB como:

#define PORTB _SFR_IO8(0x05)

_SFR_IO8() es una macro:

#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

y _MMIO_BYTE es:

#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

__SFR_OFFSET puede ser 0 o 0 x 20 dependiendo del chip (normalmente 0x20).

Así que, eso quiere decir que las direcciones de DDRB y PORTB debe ser más de 0x20.

Mirando el 328P chip, DDRB es 0x04 y PORTB es 0x05. Así, la forma de acceder a los 0x24 y alt + 0x25, con el derecho de los tipos de datos así:

volatile uint8_t *dir = (volatile uint8_t *)0x24;
volatile uint8_t *port = (volatile uint8_t *)0x25;

*dir = 0x10;
*port = 0x10;

resultados en esta asamblea:

12c:    80 e1           ldi r24, 0x10   ; 16
12e:    84 b9           out 0x04, r24   ; 4
130:    85 b9           out 0x05, r24   ; 5

Familiar de la mirada? El compilador ha reconocido la 0x20 desplazamiento, se dio cuenta de que están Sfr, y compilado en el derecho out instrucciones sin la 0x20 desplazamiento.

Así, acceder a sus direcciones de puerto de + 0x20 puede trabajar para el ATTiny13.

Con sólo mirar a la ATTiny25, DDRB = 0x10 resultados en:

out 0x17, r24

y el acceso a un puntero en la dirección 0x37 resultados en:

out 0x17, r24

Por lo que parece probable es que (agregar 0x20 a su dirección de puntero).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X