USART_GetITStatus
인터넷에 떠도는 소스이다.
여기서 문제점은 USART_GetITStatus함수가 매우 길고, 여러번 호출해야한다는 점이다.
물론, 코드 호환성과 조금 덜복잡한 코드를 피하기 위해서는 좋은 방법이 될 수 있으나,
인터럽트가 매우 빨리 수행되어야하는 입장에서는 좋지 못하다.
void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){ // check RX interrupt RxMessage = USART_ReceiveData(USART1); RxUpdate = 1; USART_ClearITPendingBit(USART1,USART_IT_RXNE); } if(USART_GetITStatus(USART1,USART_IT_TXE)!=RESET){ // check TX interrupt USART_SendData(USART1TxBuffer[TxCounter++]); USART_ClearITPendingBit(USART1 USART_IT_TXE); if(TxBuffer[TxCounter] == 0 | TxCounter > TxBufferSize){ USART_ITConfig(USART1,USART_IT_TXE,DISABLE); // disable transmit interrupt TxReady = 1; } } } |
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) { uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; ITStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_GET_IT(USART_IT));
/* The CTS interrupt is not available for UART4 and UART5 */ if (USART_IT == USART_IT_CTS) { assert_param(IS_USART_1236_PERIPH(USARTx)); }
/* Get the USART register index */ usartreg = (((uint8_t)USART_IT) >> 0x05); /* Get the interrupt position */ itmask = USART_IT & IT_MASK; itmask = (uint32_t)0x01 << itmask;
if (usartreg == 0x01) /* The IT is in CR1 register */ { itmask &= USARTx->CR1; } else if (usartreg == 0x02) /* The IT is in CR2 register */ { itmask &= USARTx->CR2; } else /* The IT is in CR3 register */ { itmask &= USARTx->CR3; }
bitpos = USART_IT >> 0x08; bitpos = (uint32_t)0x01 << bitpos; bitpos &= USARTx->SR; if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) { bitstatus = SET; } else { bitstatus = RESET; }
return bitstatus; } |
오래전 방식대로, 인터럽트 플래그 레지스터를 직접 엑세스하는 방식이 더 빠르다. 물론, 코드 호환성은 없다.
속도가 우선이냐? 코드호환성이 우선이냐?의 문제이다.
우리는 코드호환성을 위해, 너무많은 속도를 희생하고 있다.