LPC2131 problema al leer pines IO

4

Necesito leer un valor de un interruptor DIP. Está conectado a los puertos P1.16 hasta P1.21. Uso el siguiente código:

para inicializar:

#define PORT_ADDRESS                    0x003F0000
#define PORT_ADDRESS_OFFSET             16

IODIR1 &= ~(PORT_ADDRESS);

leer:

int value = (IOPIN1 & PORT_ADDRESS) >> PORT_ADDRESS_OFFSET;

El problema es que no importa cuáles sean las configuraciones del interruptor DIP, el valor leído siempre es cero. El código funcionó antes, pero se detuvo y no tengo idea de por qué.

    
pregunta Bogi

3 respuestas

1

La función de los pines no fue seleccionada correctamente. Cuando se reinicia el microcontrolador, el valor de P1.20 determina cómo se comportarán los pines P1.16 hasta P1.23. En mi caso, cuando P1.20 se puso a cero, no funcionó, y cuando se configuró a uno funcionó.

Corrección: configure manualmente las funciones de pin utilizando el registro PINSEL2:

    PINSEL2 &= ~(0x8);
    IODIR1 &= ~(PORT_ADDRESS);
    
respondido por el Bogi
1

No mencionó dónde se declara IOPIN1, pero asegúrese de que esté declarado volatile o el compilador pueda optimizar la lectura del valor si no cree que haya cambiado, lo que lleva a una funcionalidad intermitente.

Si está declarado en algún archivo de encabezado suministrado por el proveedor, probablemente ya lo haya hecho por usted.

    
respondido por el Mark
0

Tus #defines son muy confusos. No estás definiendo una dirección de puerto en absoluto; Estás dando una máscara de bits para tu interruptor. Tampoco muestra si está colocando estos pines de puerto en modo GPIO. El estado predeterminado de PINSEL1 es tener todo en modo GPIO, pero nunca debe hacer suposiciones.

#define SW_MASK 0x3f
#define SW_OFFSET 16

PINSEL1 &= ~(0x00ffffff);
IO1DIR = ~(SW_MASK << SW_OFFSET);
int sw = (IO1PIN >> SW_OFFSET) & SW_MASK;

Este es básicamente el código que tiene, aunque con el código PINSEL1, y está dispuesto a ser un poco menos confuso (para mí).

Jobi tiene razón: es mejor que tenga una resistencia pull-up en P0.20 para que el chip no fuerce estos pines en su función de "puerto de rastreo". Consulte la página 70 del manual del usuario de LPC213x.

Tenga cuidado: ha puesto uno de los conmutadores DIP en P0.20. Aísle ese pin en un reinicio (un pequeño transistor con un temporizador RCD en la base que desconecta el interruptor de P0.20 cuando reinicie la CPU hará el truco), o asegúrese de que nunca deje el interruptor DIP en P0. 20 "encendido" (conectado a tierra) al reiniciar. Mejor aún: simplemente mueva el conmutador a una E / S diferente y vuélvalo a combinar en un código para que su aplicación nunca sepa la diferencia.

por ejemplo si mueve ese interruptor de P0.20 a P0.22, puede recuperar su valor "limpio" de este modo:

#define SW_MASK 0x6f
#define SW_OFFSET 16

PINSEL1 &= ~(0x03ffffff);
IO1DIR = ~(SW_MASK << SW_OFFSET);

int sw;
sw = (IO1PIN >> SW_OFFSET) & SW_MASK;
if(sw & (1 << 6)) sw |= (1 << 4);
sw &= ~(1 << 6);

(hay maneras más astutas de hacer esto, pero estoy tratando de mostrarte lo que está pasando, no ser astuto).

He alterado la máscara para que no lea en P0.20 (cambio de SW_MASK), y que también configure P0.22 en GPIO (cambio de PINSEL1). El bloque que calcula 'sw' establecerá el bit 4 si se establece el bit 6 (esto es P0.20 que se movió a P0.22). Luego "borrará" el bit 6, que ahora está en la posición del bit 4. El valor de su interruptor será correcto.

(la mayoría de los sistemas embebidos no se preocupan por las posiciones reales de los bits, pero puede que sí, por lo que sugerí esto)

    
respondido por el akohlsmith

Lea otras preguntas en las etiquetas