[DemoCode下载] 通过寄存器实现M051的串口收发

[复制链接]
1479|5
 楼主| 734774645 发表于 2017-12-27 10:47 | 显示全部楼层 |阅读模式
  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. * $Revision: 8 $
  5. * $Date: 15/07/13 1:27p $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Transmit and receive data from PC terminal through RS232 interface.
  7. *
  8. * @note
  9. * Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "M051Series.h"

  14. #define PLLCON_SETTING  CLK_PLLCON_50MHz_HXT
  15. #define PLL_CLOCK       50000000

  16. #define RXBUFSIZE 1024

  17. /*---------------------------------------------------------------------------------------------------------*/
  18. /* Global variables                                                                                        */
  19. /*---------------------------------------------------------------------------------------------------------*/
  20. uint8_t g_u8RecData[RXBUFSIZE]  = {0};

  21. volatile uint32_t g_u32comRbytes = 0;
  22. volatile uint32_t g_u32comRhead  = 0;
  23. volatile uint32_t g_u32comRtail  = 0;
  24. volatile int32_t g_bWait         = TRUE;

  25. /*---------------------------------------------------------------------------------------------------------*/
  26. /* Define functions prototype                                                                              */
  27. /*---------------------------------------------------------------------------------------------------------*/
  28. int32_t main(void);
  29. void UART_TEST_HANDLE(void);
  30. void UART_FunctionTest(void);


  31. void SYS_Init(void)
  32. {
  33.     /*---------------------------------------------------------------------------------------------------------*/
  34.     /* Init System Clock                                                                                       */
  35.     /*---------------------------------------------------------------------------------------------------------*/

  36.     /* Enable Internal RC 22.1184MHz clock */
  37.     CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;

  38.     /* Waiting for Internal RC clock ready */
  39.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk));
  40.    
  41.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  42.     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
  43.     CLK->CLKDIV = (CLK->CLKDIV & (~CLK_CLKDIV_HCLK_N_Msk)) | CLK_CLKDIV_HCLK(1);

  44.     /* Set PLL to Power down mode and HW will also clear PLL_STB bit in CLKSTATUS register */
  45.     CLK->PLLCON |= CLK_PLLCON_PD_Msk;        
  46.    
  47.     /* Enable external XTAL 12MHz clock */
  48.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

  49.     /* Waiting for external XTAL clock ready */
  50.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk));

  51.     /* Set core clock as PLL_CLOCK from PLL */
  52.     CLK->PLLCON = PLLCON_SETTING;
  53.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk));
  54.     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_PLL;

  55.     /* Update System Core Clock */
  56.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  57.     //SystemCoreClockUpdate();
  58.     PllClock        = PLL_CLOCK;            // PLL
  59.     SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  60.     CyclesPerUs     = PLL_CLOCK / 1000000;  // For CLK_SysTickDelay()

  61.     /* Enable UART module clock */
  62.     CLK->APBCLK |= CLK_APBCLK_UART0_EN_Msk;

  63.     /* Select UART module clock source */
  64.     CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_UART_S_Msk)) | CLK_CLKSEL1_UART_S_HXT;

  65.     /*---------------------------------------------------------------------------------------------------------*/
  66.     /* Init I/O Multi-function                                                                                 */
  67.     /*---------------------------------------------------------------------------------------------------------*/

  68.     /* Set P3 multi-function pins for UART0 RXD and TXD */
  69.     SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
  70.     SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);

  71. }

  72. void UART0_Init()
  73. {
  74.     /*---------------------------------------------------------------------------------------------------------*/
  75.     /* Init UART                                                                                               */
  76.     /*---------------------------------------------------------------------------------------------------------*/
  77.     /* Reset UART0 */
  78.     SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
  79.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;

  80.     /* Configure UART0 and set UART0 Baudrate */
  81.     UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
  82.     UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
  83. }

  84. /*---------------------------------------------------------------------------------------------------------*/
  85. /* UART Test Sample                                                                                        */
  86. /* Test Item                                                                                               */
  87. /* It sends the received data to HyperTerminal.                                                            */
  88. /*---------------------------------------------------------------------------------------------------------*/

  89. /*---------------------------------------------------------------------------------------------------------*/
  90. /* MAIN function                                                                                           */
  91. /*---------------------------------------------------------------------------------------------------------*/

  92. int main(void)
  93. {
  94.     /* Unlock protected registers */
  95.     SYS_UnlockReg();

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

  98.     /* Lock protected registers */
  99.     SYS_LockReg();

  100.     /* Init UART0 for printf and testing */
  101.     UART0_Init();

  102.     /*---------------------------------------------------------------------------------------------------------*/
  103.     /* SAMPLE CODE                                                                                             */
  104.     /*---------------------------------------------------------------------------------------------------------*/

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

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

  107.     /* UART sample function */
  108.     UART_FunctionTest();
  109.    
  110.     while(1);

  111. }

  112. /*---------------------------------------------------------------------------------------------------------*/
  113. /* ISR to handle UART Channel 0 interrupt event                                                            */
  114. /*---------------------------------------------------------------------------------------------------------*/
  115. void UART0_IRQHandler(void)
  116. {
  117.     UART_TEST_HANDLE();
  118. }

  119. /*---------------------------------------------------------------------------------------------------------*/
  120. /* UART Callback function                                                                                  */
  121. /*---------------------------------------------------------------------------------------------------------*/
  122. void UART_TEST_HANDLE()
  123. {
  124.     uint8_t u8InChar = 0xFF;
  125.     uint32_t u32IntSts = UART0->ISR;

  126.     if(u32IntSts & UART_ISR_RDA_INT_Msk)
  127.     {
  128.         printf("\nInput:");

  129.         /* Get all the input characters */
  130.         while(UART0->ISR & UART_ISR_RDA_IF_Msk)
  131.         {
  132.             /* Get the character from UART Buffer */
  133.             u8InChar = UART0->RBR;

  134.             printf("%c ", u8InChar);

  135.             if(u8InChar == '0')
  136.             {
  137.                 g_bWait = FALSE;
  138.             }

  139.             /* Check if buffer full */
  140.             if(g_u32comRbytes < RXBUFSIZE)
  141.             {
  142.                 /* Enqueue the character */
  143.                 g_u8RecData[g_u32comRtail] = u8InChar;
  144.                 g_u32comRtail = (g_u32comRtail == (RXBUFSIZE - 1)) ? 0 : (g_u32comRtail + 1);
  145.                 g_u32comRbytes++;
  146.             }
  147.         }
  148.         printf("\nTransmission Test:");
  149.     }

  150.     if(u32IntSts & UART_ISR_THRE_INT_Msk)
  151.     {
  152.         uint16_t tmp;
  153.         tmp = g_u32comRtail;
  154.         if(g_u32comRhead != tmp)
  155.         {
  156.             u8InChar = g_u8RecData[g_u32comRhead];
  157.             while(UART_IS_TX_FULL(UART0));  /* Wait Tx is not full to transmit data */            
  158.             UART_WRITE(UART0, u8InChar);
  159.             g_u32comRhead = (g_u32comRhead == (RXBUFSIZE - 1)) ? 0 : (g_u32comRhead + 1);
  160.             g_u32comRbytes--;
  161.         }
  162.     }
  163. }

  164. /*---------------------------------------------------------------------------------------------------------*/
  165. /*  UART Function Test                                                                                     */
  166. /*---------------------------------------------------------------------------------------------------------*/
  167. void UART_FunctionTest()
  168. {
  169.     printf("+-----------------------------------------------------------+\n");
  170.     printf("|  UART Function Test                                       |\n");
  171.     printf("+-----------------------------------------------------------+\n");
  172.     printf("|  Description :                                            |\n");
  173.     printf("|    The sample code will print input char on terminal      |\n");
  174.     printf("|    Please enter any to start     (Press '0' to exit)      |\n");
  175.     printf("+-----------------------------------------------------------+\n");

  176.     /*
  177.         Using a RS232 cable to connect UART0 and PC.
  178.         UART0 is set to debug port. UART0 is enable RDA and RLS interrupt.
  179.         When inputing char to terminal screen, RDA interrupt will happen and
  180.         UART0 will print the received char on screen.
  181.     */

  182.     /* Enable Interrupt and install the call back function */
  183.     UART0->IER |= UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_RTO_IEN_Msk ;
  184.     NVIC_EnableIRQ(UART0_IRQn);
  185.     while(g_bWait);

  186.     /* Disable Interrupt */
  187.     UART0->IER &= ~(UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_RTO_IEN_Msk);
  188.     NVIC_DisableIRQ(UART0_IRQn);
  189.     g_bWait = TRUE;
  190.     printf("\nUART Sample Demo End.\n");

  191. }



 楼主| 734774645 发表于 2017-12-27 10:48 | 显示全部楼层
那么修改成串口1的也是很容易的,看着手册的结构图,看看要修改哪些就行了。
643757107 发表于 2017-12-27 17:07 | 显示全部楼层
用寄存器做,比较复杂,容易出错,不如库函数搞,但是有时候库函数有错了,就很难发现了。
598330983 发表于 2017-12-31 19:50 | 显示全部楼层
研究清楚这个套路,还是用寄存器做效率高啊。
 楼主| 734774645 发表于 2017-12-31 20:01 | 显示全部楼层
寄存器都用宏替换了,需要先学习下寄存器命名法则
wahahaheihei 发表于 2017-12-31 20:59 | 显示全部楼层
也是使用了不少现成的函数啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

211

主题

3588

帖子

15

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