[DemoCode下载] M261的串口自动波特率

[复制链接]
577|8
 楼主| xuanhuanzi 发表于 2019-6-24 23:57 | 显示全部楼层 |阅读模式
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. *           Show how to use auto baud rate detection function.
  5. *
  6. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2019 Nuvoton Technology Corp. All rights reserved.
  7. *
  8. ******************************************************************************/
  9. #include <stdio.h>
  10. #include "NuMicro.h"



  11. /*---------------------------------------------------------------------------------------------------------*/
  12. /* Define functions prototype                                                                              */
  13. /*---------------------------------------------------------------------------------------------------------*/
  14. void AutoBaudRate_Test(void);
  15. void AutoBaudRate_TxTest(void);
  16. void AutoBaudRate_RxTest(void);


  17. void SYS_Init(void)
  18. {

  19.     /* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */
  20.     SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF2MFP_Msk)) | SYS_GPF_MFPL_PF2MFP_XT1_OUT;
  21.     SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF3MFP_Msk)) | SYS_GPF_MFPL_PF3MFP_XT1_IN;

  22.     /*---------------------------------------------------------------------------------------------------------*/
  23.     /* Init System Clock                                                                                       */
  24.     /*---------------------------------------------------------------------------------------------------------*/

  25.     /* Enable HIRC clock */
  26.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  27.     /* Wait for HIRC clock ready */
  28.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

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

  31.     /* Enable HXT clock */
  32.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  33.     /* Wait for HXT clock ready */
  34.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  35.     /* Enable PLL */
  36.     CLK->PLLCTL = CLK_PLLCTL_128MHz_HIRC;

  37.     /* Waiting for PLL stable */
  38.     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);

  39.     /* Select HCLK clock source as PLL and HCLK source divider as 2 */
  40.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(2));

  41.     /* Enable UART module clock */
  42.     CLK_EnableModuleClock(UART0_MODULE);
  43.     CLK_EnableModuleClock(UART1_MODULE);

  44.     /* Select UART module clock source as HXT and UART module clock divider as 1 */
  45.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
  46.     CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HXT, CLK_CLKDIV0_UART1(1));

  47.     /*---------------------------------------------------------------------------------------------------------*/
  48.     /* Init I/O Multi-function                                                                                 */
  49.     /*---------------------------------------------------------------------------------------------------------*/

  50.     /* Set multi-function pins for UART0 RXD and TXD */
  51.     SYS->GPB_MFPH = (SYS->GPB_MFPH & (~(UART0_RXD_PB12_Msk | UART0_TXD_PB13_Msk))) | UART0_RXD_PB12 | UART0_TXD_PB13;

  52.     /* Set PB multi-function pins for UART1 RXD(PB.6) and TXD(PB.7) */
  53.     SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB6MFP_Msk)) | SYS_GPB_MFPL_PB6MFP_UART1_RXD;
  54.     SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB7MFP_Msk)) | SYS_GPB_MFPL_PB7MFP_UART1_TXD;

  55. }

  56. void UART0_Init(void)
  57. {
  58.     /*---------------------------------------------------------------------------------------------------------*/
  59.     /* Init UART                                                                                               */
  60.     /*---------------------------------------------------------------------------------------------------------*/
  61.     /* Reset UART0 */
  62.     SYS_ResetModule(UART0_RST);

  63.     /* Configure UART0 and set UART0 baud rate */
  64.     UART_Open(UART0, 115200);
  65. }

  66. void UART1_Init(void)
  67. {
  68.     /*---------------------------------------------------------------------------------------------------------*/
  69.     /* Init UART                                                                                               */
  70.     /*---------------------------------------------------------------------------------------------------------*/
  71.     /* Reset UART1 */
  72.     SYS_ResetModule(UART1_RST);

  73.     /* Configure UART1 and set UART1 Baudrate */
  74.     UART_Open(UART1, 115200);
  75. }

  76. /*---------------------------------------------------------------------------------------------------------*/
  77. /*  Main Function                                                                                          */
  78. /*---------------------------------------------------------------------------------------------------------*/
  79. int32_t main(void)
  80. {

  81.     /* Unlock protected registers */
  82.     SYS_UnlockReg();

  83.     /* Init System, peripheral clock and multi-function I/O */
  84.     SYS_Init();

  85.     /* Lock protected registers */
  86.     SYS_LockReg();

  87.     /* Init UART0 for printf */
  88.     UART0_Init();

  89.     /* Init UART1 */
  90.     UART1_Init();

  91.     /*---------------------------------------------------------------------------------------------------------*/
  92.     /* SAMPLE CODE                                                                                             */
  93.     /*---------------------------------------------------------------------------------------------------------*/

  94.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

  95.     printf("\nUART Sample Program\n");

  96.     /* UART auto baud rate sample function */
  97.     AutoBaudRate_Test();

  98.     printf("\nUART Sample Program End\n");

  99.     while(1);

  100. }

  101. /*---------------------------------------------------------------------------------------------------------*/
  102. /*  Auto Baud Rate Function Test                                                                           */
  103. /*---------------------------------------------------------------------------------------------------------*/
  104. void AutoBaudRate_Test()
  105. {

  106.     uint32_t u32Item;

  107.     printf("\n");
  108.     printf("+-----------------------------------------------------------+\n");
  109.     printf("|     Pin Configure                                         |\n");
  110.     printf("+-----------------------------------------------------------+\n");
  111.     printf("|  ______                                            _____  |\n");
  112.     printf("| |      |                                          |     | |\n");
  113.     printf("| |Master|--UART1_TXD(PB.7)  <==>  UART1_RXD(PB.6)--|Slave| |\n");
  114.     printf("| |      |                                          |     | |\n");
  115.     printf("| |______|                                          |_____| |\n");
  116.     printf("|                                                           |\n");
  117.     printf("+-----------------------------------------------------------+\n");

  118.     printf("\n");
  119.     printf("+-----------------------------------------------------------+\n");
  120.     printf("|     Auto Baud Rate Function Test                          |\n");
  121.     printf("+-----------------------------------------------------------+\n");
  122.     printf("|  Description :                                            |\n");
  123.     printf("|    The sample code needs two boards. One is Master and    |\n");
  124.     printf("|    the other is slave.  Master will send input pattern    |\n");
  125.     printf("|    0x1 with different baud rate. It can check if Slave    |\n");
  126.     printf("|    calculates correct baud rate.                          |\n");
  127.     printf("+-----------------------------------------------------------+\n");
  128.     printf("|  Please select Master or Slave test                       |\n");
  129.     printf("|  [0] Master    [1] Slave                                  |\n");
  130.     printf("+-----------------------------------------------------------+\n");
  131.     u32Item = getchar();

  132.     if(u32Item == '0')
  133.         AutoBaudRate_TxTest();
  134.     else
  135.         AutoBaudRate_RxTest();

  136. }

  137. /*---------------------------------------------------------------------------------------------------------*/
  138. /*  Auto Baud Rate Function Tx Test                                                                        */
  139. /*---------------------------------------------------------------------------------------------------------*/
  140. void AutoBaudRate_TxTest()
  141. {
  142.     uint32_t u32Item;

  143.     do
  144.     {

  145.         printf("\n");
  146.         printf("+-----------------------------------------------------------+\n");
  147.         printf("|     Auto Baud Rate Function Test (Master)                 |\n");
  148.         printf("+-----------------------------------------------------------+\n");
  149.         printf("| [1] baud rate 38400 bps                                   |\n");
  150.         printf("| [2] baud rate 57600 bps                                   |\n");
  151.         printf("| [3] baud rate 115200 bps                                  |\n");
  152.         printf("|                                                           |\n");
  153.         printf("| Select baud rate and master will send 0x1 to slave ...    |\n");
  154.         printf("+-----------------------------------------------------------+\n");
  155.         printf("| Quit                                              - [ESC] |\n");
  156.         printf("+-----------------------------------------------------------+\n\n");
  157.         u32Item = getchar();
  158.         if(u32Item == 27) break;        
  159.         printf("%c\n", u32Item);

  160.         /* Set different baud rate */
  161.         switch(u32Item)
  162.         {
  163.             case '1':
  164.                 UART1->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 38400);
  165.                 break;
  166.             case '2':
  167.                 UART1->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 57600);
  168.                 break;
  169.             default:
  170.                 UART1->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
  171.                 break;
  172.         }

  173.         /* Send input pattern 0x1 for auto baud rate detection bit length is 1-bit */
  174.         UART_WRITE(UART1, 0x1);

  175.     }
  176.     while(1);

  177. }

  178. /*---------------------------------------------------------------------------------------------------------*/
  179. /*  Get UART Baud Rate Function                                                                            */
  180. /*---------------------------------------------------------------------------------------------------------*/
  181. uint32_t GetUartBaudrate(UART_T* uart)
  182. {
  183.     uint8_t u8UartClkSrcSel = 0, u8UartClkDivNum = 0;
  184.     uint32_t au32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC};
  185.     uint32_t u32BaudDiv;

  186.     /* Get UART clock source selection and UART clock divider number */
  187.     switch((uint32_t)uart)
  188.     {
  189.         case UART0_BASE:
  190.             u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk) >> CLK_CLKSEL1_UART0SEL_Pos;
  191.             u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos;
  192.             break;
  193.         case UART1_BASE:
  194.             u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos;
  195.             u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos;
  196.             break;
  197.         case UART2_BASE:
  198.             u8UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos;
  199.             u8UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos;
  200.             break;
  201.         case UART3_BASE:
  202.             u8UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART3SEL_Msk) >> CLK_CLKSEL3_UART3SEL_Pos;
  203.             u8UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART3DIV_Msk) >> CLK_CLKDIV4_UART3DIV_Pos;
  204.             break;
  205.         case UART4_BASE:
  206.             u8UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART4SEL_Msk) >> CLK_CLKSEL3_UART4SEL_Pos;
  207.             u8UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART4DIV_Msk) >> CLK_CLKDIV4_UART4DIV_Pos;
  208.             break;
  209.         case UART5_BASE:
  210.             u8UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART5SEL_Msk) >> CLK_CLKSEL3_UART5SEL_Pos;
  211.             u8UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART5DIV_Msk) >> CLK_CLKDIV4_UART5DIV_Pos;
  212.             break;
  213.     }

  214.     /* Get PLL clock frequency if UART clock source selection is PLL */
  215.     if(u8UartClkSrcSel == 1)
  216.         au32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();

  217.     /* Get UART baud rate divider */
  218.     u32BaudDiv = (uart->BAUD & UART_BAUD_BRD_Msk) >> UART_BAUD_BRD_Pos;

  219.     /* Calculate UART baud rate if baud rate is set in MODE 0 */
  220.     if((uart->BAUD & (UART_BAUD_BAUDM1_Msk | UART_BAUD_BAUDM0_Msk)) == UART_BAUD_MODE0)
  221.         return ((au32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1) / (u32BaudDiv + 2)) >> 4;

  222.     /* Calculate UART baud rate if baud rate is set in MODE 2 */
  223.     else if((uart->BAUD & (UART_BAUD_BAUDM1_Msk | UART_BAUD_BAUDM0_Msk)) == UART_BAUD_MODE2)
  224.         return ((au32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1) / (u32BaudDiv + 2));

  225.     /* Calculate UART baud rate if baud rate is set in MODE 1 */
  226.     else if((uart->BAUD & (UART_BAUD_BAUDM1_Msk | UART_BAUD_BAUDM0_Msk)) == UART_BAUD_BAUDM1_Msk)
  227.         return ((au32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1) / (u32BaudDiv + 2)) / (((uart->BAUD & UART_BAUD_EDIVM1_Msk) >> UART_BAUD_EDIVM1_Pos) + 1);

  228.     /* Unsupported baud rate setting */
  229.     else
  230.         return 0;
  231. }

  232. /*---------------------------------------------------------------------------------------------------------*/
  233. /*  Auto Baud Rate Function Rx Test                                                                                 */
  234. /*---------------------------------------------------------------------------------------------------------*/
  235. void AutoBaudRate_RxTest()
  236. {
  237.     /* Enable auto baud rate detect function */
  238.     UART1->ALTCTL |= UART_ALTCTL_ABRDEN_Msk;

  239.     printf("\nreceiving input pattern... ");

  240.     /* Wait until auto baud rate detect finished or time-out */
  241.     while((UART1->ALTCTL & UART_ALTCTL_ABRIF_Msk) == 0);

  242.     if(UART1->FIFOSTS & UART_FIFOSTS_ABRDIF_Msk)
  243.     {
  244.         /* Clear auto baud rate detect finished flag */
  245.         UART1->FIFOSTS = UART_FIFOSTS_ABRDIF_Msk;
  246.         printf("Baud rate is %dbps.\n", GetUartBaudrate(UART1));
  247.     }
  248.     else if(UART1->FIFOSTS & UART_FIFOSTS_ABRDTOIF_Msk)
  249.     {
  250.         /* Clear auto baud rate detect time-out flag */
  251.         UART1->FIFOSTS = UART_FIFOSTS_ABRDTOIF_Msk;
  252.         printf("Time-out!\n");
  253.     }

  254. }

  255. /*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/


 楼主| xuanhuanzi 发表于 2019-6-24 23:57 | 显示全部楼层
对波特率自动设置感兴趣的可以学习一下。
 楼主| xuanhuanzi 发表于 2019-6-24 23:57 | 显示全部楼层
这个例子通用性很强
21mengnan 发表于 2019-6-24 23:59 | 显示全部楼层
多谢分享,我去下载看看。
zhuotuzi 发表于 2019-6-26 00:01 | 显示全部楼层
学习一下这个方法。
mintspring 发表于 2019-6-27 00:01 | 显示全部楼层
这个功能很好。
heisexingqisi 发表于 2019-6-27 00:36 | 显示全部楼层
例子很丰富,要不然真不好学。
xinpian101 发表于 2019-6-27 23:45 | 显示全部楼层
这属于硬件实现,还是软件实现
xinpian101 发表于 2019-6-27 23:45 | 显示全部楼层
这属于硬件实现,还是软件实现
您需要登录后才可以回帖 登录 | 注册

本版积分规则

183

主题

2331

帖子

3

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