ИМХО, не привязываясь к архитектуре не получится. В аналогичной задаче для MB90 сделал так:
В таблице
static const INT8U Tests_Pins[]на этапе компиляции кодируется информация о пине: номер порта, номер бита, значение активного уровня. Макросы и функция для удобства манипулирования:
#define TESTS_PIN_VAL_MASK (1<<3) #define tests_pinH(port, bit) ((0x0##port<<4) + TESTS_PIN_VAL_MASK + ##bit) #define tests_pinL(port, bit) ((0x0##port<<4) + 0 + ##bit) #define tests_pin(port, bit, val) tests_pin##val(port, bit) #define TESTS_PIN(x) tests_pin(x) /* производит упаковку данных о пине в байт: */ /* port3 port2 port1 port0 val bit2 bit1 bit0 */ /* port = номер и одновременно адрес порта, 4 бита */ /* (pin >> 4) */ /* bit = номер бита в байте порта , 3 бита */ /* (pin & 0x07) */ /* val = 0, если в описании пина L */ /* (pin & TESTS_PIN_VAL_MASK) */ #define TESTS_PIN_ON_H(pin) *(__io unsigned char *)(pin >> 4) |= (1<<(pin & 0x07)) #define TESTS_PIN_ON_L(pin) *(__io unsigned char *)(pin >> 4) &= ~(1<<(pin & 0x07)) #define tests_pinO(pin) *(__io unsigned char *)(0x10 + (pin >> 4)) |= (1<<(pin & 0x07)) #define tests_pinI(pin) *(__io unsigned char *)(0x10 + (pin >> 4)) &= ~(1<<(pin & 0x07)) #define TESTS_PIN_DIRECT(pin, mode) tests_pin##mode(pin) //... #pragma inline Tests_PinOn static void Tests_PinOn (INT8U pin) { if (pin & TESTS_PIN_VAL_MASK) /* val == H */ { TESTS_PIN_ON_H(pin); } else /* val == L */ { TESTS_PIN_ON_L(pin); } }Мне надо было сделать бегущий огонек. Собственно манипуляция в цикле:
for (i = 0; i < sizeof(Tests_Pins); i++) { pin_code = Tests_Pins[i]; TESTS_PIN_DIRECT(pin_code, O); Tests_PinOn(pin_code); OSTimeDly(TESTS_PIN_ON_DURATION); TESTS_PIN_DIRECT(pin_code, I); }