[DemoCode下载] 如何使用UART的接收超时功能来接收未知数据长度的数据包

[复制链接]
1256|4
 楼主| 643757107 发表于 2024-2-19 21:25 | 显示全部楼层 |阅读模式
  1. /******************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * $Revision: 3 $
  5. * $Date: 18/05/30 3:53p $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Show how to use the UART Rx timeout function for receiving unknown data length package.
  7. *
  8. * SPDX-License-Identifier: Apache-2.0
  9. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2018 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "NuMicro.h"

  14. #define FIFO_THRESHOLD 4
  15. #define RX_BUFFER_SIZE 128
  16. #define RX_TIMEOUT_CNT 60 //40~255

  17. enum
  18. {
  19.     eUART_RX_Received_Data_Finish = 0,
  20.     eUART_RX_Received_Data_NOT_Finish
  21. };

  22. volatile uint8_t g_au8UART_RX_Buffer[RX_BUFFER_SIZE] = {0}; // UART Rx received data Buffer (RAM)
  23. volatile uint8_t g_bUART_RX_Received_Data_State = eUART_RX_Received_Data_NOT_Finish;
  24. volatile uint8_t g_u8UART_RDA_Trigger_Cnt = 0; // UART RDA interrupt trigger times counter
  25. volatile uint8_t g_u8UART_RXTO_Trigger_Cnt = 0; // UART RXTO interrupt trigger times counter

  26. void UART02_IRQHandler(void)
  27. {
  28.     uint8_t i;
  29.     static uint16_t u16UART_RX_Buffer_Index = 0;

  30.     if(UART_GET_INT_FLAG(UART0, UART_INTSTS_RDAINT_Msk))
  31.     {
  32.         /* UART receive data available flag */

  33.         /* Record RDA interrupt trigger times */
  34.         g_u8UART_RDA_Trigger_Cnt++;

  35.         /* Move the data from Rx FIFO to sw buffer (RAM). */
  36.         /* Every time leave 1 byte data in FIFO for Rx timeout */
  37.         for(i = 0 ; i < (FIFO_THRESHOLD - 1) ; i++)
  38.         {
  39.             g_au8UART_RX_Buffer[u16UART_RX_Buffer_Index] = UART_READ(UART0);
  40.             u16UART_RX_Buffer_Index ++;

  41.             if (u16UART_RX_Buffer_Index >= RX_BUFFER_SIZE)
  42.                 u16UART_RX_Buffer_Index = 0;
  43.         }
  44.     }
  45.     else if(UART_GET_INT_FLAG(UART0, UART_INTSTS_RXTOINT_Msk))
  46.     {
  47.         /* When Rx timeout flag is set to 1, it means there is no data needs to be transmitted. */

  48.         /* Record Timeout times */
  49.         g_u8UART_RXTO_Trigger_Cnt++;

  50.         /* Move the last data from Rx FIFO to sw buffer. */
  51.         while(UART_GET_RX_EMPTY(UART0) == 0)
  52.         {
  53.             g_au8UART_RX_Buffer[u16UART_RX_Buffer_Index] = UART_READ(UART0);
  54.             u16UART_RX_Buffer_Index ++;
  55.         }

  56.         /* Clear UART RX parameter */

  57.         UART_DISABLE_INT(UART0, UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
  58.         u16UART_RX_Buffer_Index = 0;
  59.         g_bUART_RX_Received_Data_State = eUART_RX_Received_Data_Finish;
  60.     }
  61. }

  62. void SYS_Init(void)
  63. {
  64.     /* Unlock protected registers */
  65.     SYS_UnlockReg();

  66.     /*---------------------------------------------------------------------------------------------------------*/
  67.     /* Init System Clock                                                                                       */
  68.     /*---------------------------------------------------------------------------------------------------------*/

  69.     /* Enable HIRC and LIRC clock */
  70.     CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);
  71.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  72.     /* Wait for HIRC and LIRC clock ready */
  73.     CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);
  74.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  75.     /* Select HCLK clock source as HIRC and HCLK clock divider as 1 */
  76.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

  77.     /* Enable UART module clock */
  78.     CLK_EnableModuleClock(UART0_MODULE);

  79.     /* Select UART module clock source as HIRC and UART module clock divider as 1 */
  80.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));

  81.     /*---------------------------------------------------------------------------------------------------------*/
  82.     /* Init I/O Multi-function                                                                                 */
  83.     /*---------------------------------------------------------------------------------------------------------*/

  84.     /* Set PB multi-function pins for UART0 RXD=PB.12 and TXD=PB.13 */
  85.     SYS->GPB_MFPH = ((SYS->GPB_MFPH & (~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)))
  86.                      | (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD));

  87.     /* Lock protected registers */
  88.     SYS_LockReg();
  89. }

  90. void UART0_Init(void)
  91. {
  92.     /*---------------------------------------------------------------------------------------------------------*/
  93.     /* Init UART                                                                                               */
  94.     /*---------------------------------------------------------------------------------------------------------*/
  95.     /* Reset UART0 */
  96.     SYS_ResetModule(UART0_RST);

  97.     /* Configure UART0 and set UART0 baud rate */
  98.     UART_Open(UART0, 115200);

  99.     /* Enable UART RDA and RX timeout interrupt */
  100.     UART_EnableInt(UART0, UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
  101.     NVIC_EnableIRQ(UART02_IRQn);

  102.     /* Set RX Trigger Level as 4 bytes */
  103.     UART0->FIFO = ((UART0->FIFO & (~UART_FIFO_RFITL_Msk)) | UART_FIFO_RFITL_4BYTES);

  104.     /* Set Timeout time counter in 60 bit-time and enable time-out counter */
  105.     UART_SetTimeoutCnt(UART0, RX_TIMEOUT_CNT);
  106. }

  107. void DescriptionMessage(void)
  108. {
  109.     printf("+----------------------------------------------------------------------+\n");
  110.     printf("|  This sample code performs how to receive unknow data length package.|\n");
  111.     printf("|                                                                      |\n");
  112.     printf("|   (1) Please send data to UART0 Rx(PB.12)                            |\n");
  113.     printf("|   (2) UART will receive data by UART Rx RDA and RXTO interrupt.      |\n");
  114.     printf("|   (3) User can modify the Rx Timeout counter RX_TIMEOUT_CNT for      |\n");
  115.     printf("|       diffirent timeout period.                                      |\n");
  116.     printf("|                                                                      |\n");
  117.     printf("|   Description for RX_TIMEOUT_CNT :                                   |\n");
  118.     printf("|   -UART data = 8 bits                                                |\n");
  119.     printf("|   -UART Parity = None                                                |\n");
  120.     printf("|   -RX_TIMEOUT_CNT = 60                                               |\n");
  121.     printf("|     If there is no data comes in 60 baudrate clock,                  |\n");
  122.     printf("|     the UART Rx timeout interrupt flag will be set to 1.             |\n");
  123.     printf("|     RX_TIMEOUT_CNT = 60 = 6 * ( 1 start + 8 data bits + 1 stop bit ) |\n");
  124.     printf("|                         = 6 bytes data transmittion times            |\n");
  125.     printf("+----------------------------------------------------------------------+\n\n");

  126.     UART_WAIT_TX_EMPTY(UART0);
  127. }

  128. /*---------------------------------------------------------------------------------------------------------*/
  129. /*  Main Function                                                                                          */
  130. /*---------------------------------------------------------------------------------------------------------*/
  131. int32_t main(void)
  132. {
  133.     uint32_t u32ResetBufferIndex;
  134.     /* Init System, peripheral clock and multi-function I/O */
  135.     SYS_Init();

  136.     /* Init UART */
  137.     UART0_Init();

  138.     /* Print description message */
  139.     DescriptionMessage();

  140.     while(1)
  141.     {
  142.         /* Wait to receive UART data */
  143.         while(UART_RX_IDLE(UART0));

  144.         /* Start to received UART data */
  145.         g_bUART_RX_Received_Data_State = eUART_RX_Received_Data_NOT_Finish;
  146.         /* Wait for receiving UART message finished */
  147.         while(g_bUART_RX_Received_Data_State != eUART_RX_Received_Data_Finish);

  148.         printf("\nUART0 Rx Received Data : %s\n",g_au8UART_RX_Buffer);
  149.         printf("UART0 Rx RDA (Fifofull) interrupt times : %d\n",g_u8UART_RDA_Trigger_Cnt);
  150.         printf("UART0 Rx RXTO (Timeout) interrupt times : %d\n",g_u8UART_RXTO_Trigger_Cnt);

  151.         /* Reset SRAM Buffer */
  152.         u32ResetBufferIndex = 0;
  153.         while(g_au8UART_RX_Buffer[u32ResetBufferIndex] != '\0')
  154.             g_au8UART_RX_Buffer[u32ResetBufferIndex++] = '\0';
  155.         /* Reset UART interrupt parameter */
  156.         UART_EnableInt(UART0, UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
  157.         g_u8UART_RDA_Trigger_Cnt = 0; // UART RDA interrupt times
  158.         g_u8UART_RXTO_Trigger_Cnt = 0; // UART RXTO interrupt times
  159.     }
  160. }


 楼主| 643757107 发表于 2024-2-19 21:25 | 显示全部楼层
#define FIFO_THRESHOLD 4
#define RX_BUFFER_SIZE 128
#define RX_TIMEOUT_CNT 60 //40~255
  1. 这些宏定义了FIFO的阈值、接收缓冲区的大小和接收超时计数器的值。

 楼主| 643757107 发表于 2024-2-19 21:26 | 显示全部楼层
  1. volatile uint8_t g_au8UART_RX_Buffer[RX_BUFFER_SIZE] = {0}; // UART Rx received data Buffer (RAM)
  2. volatile uint8_t g_bUART_RX_Received_Data_State = eUART_RX_Received_Data_NOT_Finish;
  3. volatile uint8_t g_u8UART_RDA_Trigger_Cnt = 0; // UART RDA interrupt trigger times counter
  4. volatile uint8_t g_u8UART_RXTO_Trigger_Cnt = 0; // UART RXTO interrupt trigger times counter

这些全局变量用于存储接收到的数据、接收状态以及接收中断触发次数。
 楼主| 643757107 发表于 2024-2-19 21:26 | 显示全部楼层
UART02_IRQHandler()函数:
这是UART0的中断服务程序。当接收到数据或者发生接收超时时会触发相应的中断,进行相应的处理。

SYS_Init()函数:
这个函数用于初始化系统时钟和UART0模块。

UART0_Init()函数:
这个函数用于初始化UART0模块,包括设置波特率、启用接收中断和接收超时中断等。

DescriptionMessage()函数:
这个函数用于打印描述信息,说明了代码的作用以及如何使用。
可怜的小弗朗士 发表于 2024-3-8 15:16 | 显示全部楼层
超时中断和空闲中断哪个好用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

223

主题

3972

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部