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.c
alaquellamaré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)