¿Establecer registros DDR y PORT en función del número de pin (AVR)?

0

Estoy escribiendo una función de inicialización en un ATTiny441 para establecer el registro de dirección de datos (DDR) para el puerto A o B según el número de pin físico.

Hastaahoramiimplementaciónpareceunpocotorpe.Acontinuaciónsemuestralafuncióndeinicializaciónennrf.calaquellamaréenmain.c:

/*nrf.c*/#import<avr/io.h>#import"t441.h"

bool ce_port_a;
uint8_t ce_bit;


void nrf_init(uint8_t ce_pin,
              uint8_t csn_pin)
{
    /* Map CE pin */
    t441_map_pins(ce_pin, &ce_bit, &ce_port_a);

    /* Set CE to output */
    if(ce_port_a) DDRA |= BIT(ce_bit);
    else DDRB |= BIT(ce_bit);

    /* Clear CE */
    _nrf_toggle_ce(0);

    /* ... */
}

En el mismo nrf.c , aquí está la función que se usa para alternar el pin CE:

/* nrf.c */
void _nrf_toggle_ce(uint8_t direction)
{
    /* Set CE */
    if(direction) ce_port_a ? SET_BIT(PORTA, ce_bit) : SET_BIT(PORTB, ce_bit);
    /* Clear CE */
    else ce_port_a ? CLEAR_BIT(PORTA, ce_bit) : CLEAR_BIT(PORTB, ce_bit);
}

(Tenga en cuenta que las funciones SET_BIT () y CLEAR_BIT () están definidas en otra parte, pero supongo que son lo suficientemente descriptivas).

Y, finalmente, aquí está la función en t441.c que asigna el número de pin físico a un número de puerto y bit:

/* t441.c */
uint8_t t441_port_b_map[4] = {0, 1, 3, 2};

void t441_map_pins(uint8_t pin_num, uint8_t *port_pin_num, bool *port_a)
{
    if(pin_num < 6)
    {
        /* Pin is on Port B */
        *port_a = false;
        *port_pin_num = t441_port_b_map[pin_num - 2];
    }
    else
    {
        /* Pin is on Port A */
        *port_a = true;
        *port_pin_num = 13 - pin_num;
    }
}

Pregunta: ¿Existe una forma más simple o más elegante de abordar esto? Me preocupa un poco el uso de la memoria del programa, pero principalmente la reutilización del código, por ejemplo, tener que cambiar significativamente las cosas si se usa un microcontrolador con más de dos puertos IO.

(Moveré esto a Stack Overflow si es apropiado)

    
pregunta calcium3000

1 respuesta

0

Probablemente no soy el más calificado para responder, pero compilaré lo que la gente ha dicho hasta ahora.

De Chris Stratton :

  

En general, es una mala idea. Usa el puerto lógico   Asignaciones, y si lo desea, # definalas por función de radio. Si tu   Realmente quiero ver lo que un usuario pin abstracción introduce en términos de   Complicación, mira el código central de Arduino donde hacen eso.

De Harry Svensson :

  

Hay mucho código sucediendo durante el tiempo de ejecución en lugar de compilar   hora. El código de tiempo de ejecución consumirá una valiosa memoria EEPROM. Tu definitivamente   Necesito hacer uso de #ifdef junto con #define si quieres   descifra tu código. Ya que solo son evaluados durante la compilación.   tiempo.

Y de Lundin :

  

No hay ninguna razón para configurarlo "según el número de pin físico". Tú   Necesito preguntarte por qué necesitas que los números de pin sean variables en   Relación con los puertos. ¿Esperas que Atmel reasigne de repente el   puertos? ¿Necesita que el código sea portátil a otro paquete en el   ¿Al mismo tiempo que necesita operaciones basadas en el número de pin? Si no, entonces tu   Solo estamos inventando requerimientos artificiales y haciendo metacomprogramas.   Solo codifique la configuración del puerto o #define todas las constantes. Toggling   DDR en tiempo de ejecución, en lugar de solo configurarlo una vez, es bastante raro   caso también, ¿realmente necesitas hacer eso?

Parece que la mejor manera de abordarlo es con los comandos del preprocesador, por ejemplo. #ifdef , #define , y así sucesivamente. Como solo uso un solo IC, no hay necesidad de desperdiciar memoria en la portabilidad del código.

    
respondido por el calcium3000

Lea otras preguntas en las etiquetas