Делаю варианты настроек для разных режимов. Примерно так:
/* Prepare UART configuration variants */ static const uint16_t USART_CTLR1_Disabled = 0 /* Configure UART, enable the transmitter but don't enable a reception nor Rx and Tx interrupts */ | 0 * USART_CTLR1_M_EXT_1 | 0 * USART_CTLR1_M_EXT_0 /* M bit determines character size */ | 1 * USART_CTLR1_UE /* Enable USART module */ | 1 * USART_CTLR1_M /* 9-bit character is used for 8 bit payload and one address/data bit */ | 1 * USART_CTLR1_WAKE /* Use received byte address flag to wake up the receiver from silent (muted) state */ | 0 * USART_CTLR1_PCE /* Parity control is disabled */ | 0 * USART_CTLR1_PS /* Even parity (not used) */ | 0 * USART_CTLR1_PEIE /* Don't enable parity error interrupt */ | 0 * USART_CTLR1_TXEIE /* Don't enable transmission buffer free interrupt */ | 0 * USART_CTLR1_TCIE /* Don't enable transmission complete interrupt */ | 0 * USART_CTLR1_RXNEIE /* Inhibit Rx data register not empty interrupt */ | 0 * USART_CTLR1_IDLEIE /* Inhibit Idle state interrupt */ | 1 * USART_CTLR1_TE /* Keep the transmitter always enabled, the transmission on the bus is directed by DE signal of line driver */ | 0 * USART_CTLR1_RE /* Don't enable the receiver */ | 0 * USART_CTLR1_RWU /* Receiver is in active mode, is not muted */ | 0 * USART_CTLR1_SBK; /* Don't send a break character */ static const uint16_t USART_CTLR1_RxMuted = /* Mute USART receiver until an address byte is received */ USART_CTLR1_Disabled | USART_CTLR1_RE | USART_CTLR1_RXNEIE | USART_CTLR1_RWU; static const uint16_t USART_CTLR1_RxDMA = USART_CTLR1_Disabled | USART_CTLR1_RE; /* Enable UART reception but with UART Rx/Tx buffer IRQs disabled */ static const uint16_t USART_CTLR1_Tx = USART_CTLR1_Disabled | USART_CTLR1_TXEIE; /* Tx buffer not empty interrupt enabled */ static const uint16_t USART_CTLR1_TxDMA = USART_CTLR1_Disabled | USART_CTLR1_TCIE; /* Transmission complete interrupt enabled */
А потом, в ходе выполнения, подставляешь нужный вариант и записываешь регистр периферии целиком.
Плюсы:
- на Си;
- биты определяются масками от производителя МК, вероятность ошибки низка;
- не выполняет R-M-W для изменения каждого параметра, выполняет только атомарную запись в одно действие;
- экономит такты, экономит память;
- программист контролирует все параметры и полностью, осознанно, определяет режим работы периферийного модуля.
Минусы:
- Требуется изучить по мануалу и сознательно определить каждый параметр, каждый бит. Долго.
- Требуется подготовить набор возможных конфигураций. По ходу написания кода, приходится возвращаться и добавлять варианты.
При таком подходе, эффективность работы с периферией, становится максимальной. Код становится прямолинейным и простым, обращения к регистрам периферии - атомарными. Главное - контроль за битами не у ХАЛа, а у тебя, программиста.