F722ZE의 USART예제
동작
- 호스트에서 수신한 데이터를 그대로 다시 보내기
- 소스 위치
https://github.com/heecheol-jung/F722ZE_USART_Example
1. 공통 설정
1.1. USART설정
항목 | 값 |
Baud rate | 115200 |
Word length | 8 bits |
Parity | None |
Stop bits | 1 |
1.2. STM32CubeIDE설정
- 포매터 설정
Window -> Preference -> C/C++ -> Code Style -> Formatter -> Import
-> c_style디렉토리의 My_Formatter.xml선택 -> Apply and Close
2. 폴링 예제
- HAL_UART_Receive와 HAL_UART_Transmit 함수 사용
- USART_ISR의 RXNE비트 검사
- main.c
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE))
{
HAL_UART_Receive(&huart3, g_app.rx_buf, 1, FW_APP_PROTO_RX_TIMEOUT);
HAL_UART_Transmit(&huart3, g_app.rx_buf, 1, FW_APP_PROTO_TX_TIMEOUT);
}
3. 인터럽트 수신 예제
- HAL_UART_Receive_IT와 수신 큐 사용
- 인터럽트 설정
- 수신(fw_app.c)
// Callback function for UART data reception.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart3)
{
fl_q_push(&g_app.q1, g_app.rx_buf1[0]);
HAL_UART_Receive_IT(&huart3, g_app.rx_buf1, 1);
}
}
- 송신(main.c)
_rx_count = fl_q_count(&g_app.q1);
if (_rx_count > 0)
{
for (uint32_t i = 0; i < _rx_count; i++)
{
fl_q_pop(&g_app.q1, &_rx_data);
HAL_UART_Transmit(&huart3, &_rx_data, 1, FW_APP_PROTO_TX_TIMEOUT);
}
}
4. 인터럽트 송/수신 예제
- HAL_UART_Receive_IT, HAL_UART_Transmit_IT, 수신 큐 사용
- 수신(fw_app.c)
// Callback function for UART data reception.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart3)
{
fl_q_push(&g_app.q1, g_app.rx_buf1[0]);
HAL_UART_Receive_IT(&huart3, g_app.rx_buf1, 1);
}
}
- 송신(main.c, fw_app.c)
_rx_count = fl_q_count(&g_app.q1);
if (_rx_count > 0)
{
for (uint32_t i = 0; i < _rx_count; i++)
{
fl_q_pop(&g_app.q1, &_rx_data);
if (g_app.tx_len1 < FW_APP_TX_BUF_SIZE)
{
g_app.tx_buf1[g_app.tx_len1++] = _rx_data;
if (g_app.tx_len1 == FW_APP_TX_BUF_SIZE)
{
fw_app_int_transmit();
}
}
}
if (g_app.tx_len1 > 0)
{
fw_app_int_transmit();
}
}
FL_DECLARE(void) fw_app_int_transmit(void)
{
HAL_StatusTypeDef ret;
uint8_t wait_count = 0;
ret = HAL_UART_Transmit_IT(&huart3, g_app.tx_buf1, (uint16_t)g_app.tx_len1);
if (ret == HAL_OK)
{
while (1)
{
if (huart3.gState == HAL_UART_STATE_READY)
{
break;
}
HAL_Delay(1);
wait_count++;
if (wait_count >= FW_APP_INT_TX_MAX_COUNT)
{
break;
}
}
}
g_app.tx_len1 = 0;
}
5. DMA 수신 예제
- HAL_UART_Receive_DMA, DMA의 NDTR레지스터, 수신 큐 사용
- 인터럽트 설정
- DMA수신 설정
Mode : Circular
- DMA_SxNDTR를 이용해서 큐의 head위치를 계산하는데 사용
- 수신(fw_app.c)
HAL_UART_Receive_DMA(&huart3, _g_q1_buf, sizeof(_g_q1_buf));
- 송신(main.c)
_rx_count = fl_dma_q_count(&g_app.q1);
if (_rx_count > 0)
{
for (uint32_t i = 0; i < _rx_count; i++)
{
fl_dma_q_pop(&g_app.q1, &_rx_data);
HAL_UART_Transmit(&huart3, &_rx_data, 1, FW_APP_PROTO_TX_TIMEOUT);
}
}
6. DMA 송/수신 예제
- HAL_UART_Receive_DMA, HAL_UART_Transmit_DMA, DMA의 NDTR레지스터, 수신 큐 사용
- 인터럽트 설정
- DMA수신 설정
Mode : Circular
- DMA송신 설정
Mode : Normal
- DMA_SxNDTR를 이용해서 큐의 head위치를 계산하는데 사용
- 수신(fw_app.c)
HAL_UART_Receive_DMA(&huart3, _g_q1_buf, sizeof(_g_q1_buf));
-송신(main.c, fw_app.c)
_rx_count = fl_dma_q_count(&g_app.q1);
if (_rx_count > 0)
{
fl_bool_t tx_ready = FL_FALSE;
for (uint32_t i = 0; i < _rx_count; i++)
{
fl_dma_q_pop(&g_app.q1, &_rx_data);
if (g_app.tx_len1 < FW_APP_TX_BUF_SIZE)
{
g_app.tx_buf1[g_app.tx_len1++] = _rx_data;
if (g_app.tx_len1 == FW_APP_TX_BUF_SIZE)
{
fw_app_dma_transmit();
}
}
}
if (g_app.tx_len1 > 0)
{
fw_app_dma_transmit();
}
}
FL_DECLARE(void) fw_app_dma_transmit(void)
{
HAL_StatusTypeDef ret;
uint8_t wait_count = 0;
ret = HAL_UART_Transmit_DMA(&huart3, g_app.tx_buf1, (uint16_t)g_app.tx_len1);
if (ret == HAL_OK)
{
while (1)
{
if (huart3.gState == HAL_UART_STATE_READY)
{
break;
}
HAL_Delay(1);
wait_count++;
if (wait_count >= FW_APP_DMA_TX_MAX_COUNT)
{
break;
}
}
}
g_app.tx_len1 = 0;
}
7. USB CDC예제
- CDC_Receive_FS, CDC_Transmit_FS, 수신큐 사용
- 수신(usbd_cdc_if.c)
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
for (uint32_t i = 0; i < *Len; i++)
{
fl_q_push(&g_app.q1, Buf[i]);
}
return (USBD_OK);
/* USER CODE END 6 */
}
- 송신(main.c)
_rx_count = fl_q_count(&g_app.q1);
if (_rx_count > 0)
{
for (uint32_t i = 0; i < _rx_count; i++)
{
fl_q_pop(&g_app.q1, &g_app.tx_buf1[g_app.tx_len1++]);
}
CDC_Transmit_FS(g_app.tx_buf1, g_app.tx_len1);
g_app.tx_len1 = 0;
}
'STM32' 카테고리의 다른 글
F722ZE Parser Example2 (0) | 2021.09.12 |
---|---|
F722ZE Parser Example (0) | 2021.09.08 |