ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • stm32 uart without HAL
    MCU 2023. 4. 17. 11:52

     

     

     

     

    stm32 펌웨어 작성시 uart송신을 할 때

    보통 HAL_UART_Receive_IT로 interrupt를 활성화하고

    HAL_UART_RxCpltCallback으로 interrupt를 처리하는 방식을 많이 사용할 거 같다.

     

     

    이 방식에는 단점이 존재한다.

     

     

    • 수신이 완료 되면 인터럽트가 비활성화 되므로
      HAL_UART_RxCpltCallback 에서
      HAL_UART_Receive_IT를 다시 호출해야 하는데
      데드락 문제로 HAL_UART_RxCpltCallback이 호출되지 않으면
      더 이상 수신을 받을 수 없다.

    • 수신 사이즈가 정해져 있어서 가변적인 data나 실시간 data 수신에 제약이 있다.

    • 그렇다고 수신 사이즈를 1로 설정하면 HAL라이브러리가 무거워서 그런지
      오버런이 엄청 발생한다.



    그래서 필요에 따라 다음과 같은 방식을 고려해 봐야 한다.

    #include "stm32f1xx_ll_usart.h"
    #include "stm32f1xx_ll_gpio.h"
    #include "stm32f1xx_ll_bus.h"
    #include "stm32f1xx_ll_rcc.h"
    
    void UART_Config(void) {
        // GPIO 설정
        LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
        LL_GPIO_InitTypeDef GPIO_InitStruct;
        LL_GPIO_StructInit(&GPIO_InitStruct);
        GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
        GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
        LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
        GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
        GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
        LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        // UART 설정
        LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
        LL_USART_InitTypeDef USART_InitStruct;
        LL_USART_StructInit(&USART_InitStruct);
        USART_InitStruct.BaudRate = 115200;
        USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
        USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
        USART_InitStruct.Parity = LL_USART_PARITY_NONE;
        USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
        USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
        LL_USART_Init(USART1, &USART_InitStruct);
        LL_USART_Enable(USART1);
    
        // 인터럽트 활성화
        NVIC_EnableIRQ(USART1_IRQn);
        NVIC_SetPriority(USART1_IRQn, 0);
        LL_USART_EnableIT_RXNE(USART1);
    }
    void USART1_IRQHandler(void) {
        if (LL_USART_IsActiveFlag_RXNE(USART1)) {
            uint8_t received_data = LL_USART_ReceiveData8(USART1);
    
            // 여기서 데이터를 처리하거나 저장하세요.
    
            // 예를 들어, 데이터를 에코로 다시 전송할 수 있습니다.
            LL_USART_TransmitData8(USART1, received_data);
        }
    }
    int main(void) {
        SystemClock_Config();
        UART_Config();
    
        while (1) {
            // 메인 루프에서 다른 작업 수행
        }
    }



    설정과 관련된 부분들은 cubemx -> project manager에서
    HAL인지 LL인지 설정하면 자동으로 해준다.

    'MCU' 카테고리의 다른 글

    stm32f103xb 오픈소스 빌드 하기  (1) 2024.02.25
    stm32 printf  (0) 2023.04.17

    댓글

Designed by Tistory.