[DemoCode下载] M0518_Series_BSP_CMSIS_V3.00.002\SampleCode\StdDriver\UART_Autoflow_Master

[复制链接]
gaoyang9992006 发表于 2015-2-27 11:31 | 显示全部楼层 |阅读模式
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.00
  4. * $Revision: 2 $
  5. * $Date: 14/12/25 10:24a $
  6. * @brief
  7. *           Transmit and receive data with auto flow control.
  8. *           This sample code needs to work with UART_Autoflow_Slave.
  9. * @note
  10. * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
  11. *
  12. ******************************************************************************/
  13. #include <stdio.h>
  14. #include "M0518.h"


  15. #define PLL_CLOCK   50000000

  16. #define RXBUFSIZE   1024


  17. /*---------------------------------------------------------------------------------------------------------*/
  18. /* Define functions prototype                                                                              */
  19. /*---------------------------------------------------------------------------------------------------------*/
  20. extern char GetChar(void);
  21. int32_t main(void);
  22. void AutoFlow_FunctionTxTest(void);


  23. void SYS_Init(void)
  24. {
  25.     /*---------------------------------------------------------------------------------------------------------*/
  26.     /* Init System Clock                                                                                       */
  27.     /*---------------------------------------------------------------------------------------------------------*/

  28.     /* Enable Internal RC 22.1184MHz clock */
  29.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  30.     /* Waiting for Internal RC clock ready */
  31.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  32.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  33.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  34.     /* Enable external XTAL 12MHz clock */
  35.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  36.     /* Waiting for external XTAL clock ready */
  37.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  38.     /* Set core clock as PLL_CLOCK from PLL */
  39.     CLK_SetCoreClock(PLL_CLOCK);

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

  43.     /* Select UART module clock source */
  44.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
  45.     CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

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

  49.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  50.     /* Set GPB multi-function pins for UART1 RXD, TXD, nRTS and nCTS */

  51.     SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk |
  52.                       SYS_GPB_MFP_PB4_Msk | SYS_GPB_MFP_PB5_Msk |
  53.                       SYS_GPB_MFP_PB6_Msk | SYS_GPB_MFP_PB7_Msk);

  54.     SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD |
  55.                      SYS_GPB_MFP_PB4_UART1_RXD | SYS_GPB_MFP_PB5_UART1_TXD |
  56.                      SYS_GPB_MFP_PB6_UART1_nRTS | SYS_GPB_MFP_PB7_UART1_nCTS);

  57. }

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

  65.     /* Configure UART0 and set UART0 Baudrate */
  66.     UART_Open(UART0, 115200);
  67. }

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

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

  78. /*---------------------------------------------------------------------------------------------------------*/
  79. /* MAIN function                                                                                           */
  80. /*---------------------------------------------------------------------------------------------------------*/

  81. int main(void)
  82. {

  83.     /* Unlock protected registers */
  84.     SYS_UnlockReg();

  85.     /* Init System, IP clock and multi-function I/O */
  86.     SYS_Init();

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

  89.     /* Init UART0 for printf */
  90.     UART0_Init();

  91.     /* Init UART1 for testing */
  92.     UART1_Init();

  93.     /*---------------------------------------------------------------------------------------------------------*/
  94.     /* SAMPLE CODE                                                                                             */
  95.     /*---------------------------------------------------------------------------------------------------------*/

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

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

  98.     /* UART auto flow sample master function */
  99.     AutoFlow_FunctionTxTest();

  100.     while(1);

  101. }

  102. /*---------------------------------------------------------------------------------------------------------*/
  103. /*  AutoFlow Function Tx Test                                                                                 */
  104. /*---------------------------------------------------------------------------------------------------------*/
  105. void AutoFlow_FunctionTxTest()
  106. {
  107.     uint32_t u32i;

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

  119.     printf("\n");
  120.     printf("+-----------------------------------------------------------+\n");
  121.     printf("|       AutoFlow Function Test (Master)                     |\n");
  122.     printf("+-----------------------------------------------------------+\n");
  123.     printf("|  Description :                                            |\n");
  124.     printf("|    The sample code needs two boards. One is Master and    |\n");
  125.     printf("|    the other is slave. Master will send 1k bytes data     |\n");
  126.     printf("|    to slave.Slave will check if received data is correct  |\n");
  127.     printf("|    after getting 1k bytes data.                           |\n");
  128.     printf("|    Press any key to start...                              |\n");
  129.     printf("+-----------------------------------------------------------+\n");
  130.     GetChar();

  131.     /* Enable RTS and CTS autoflow control */
  132.     UART_EnableFlowCtrl(UART1);

  133.     /* Send 1k bytes data */
  134.     for(u32i = 0; u32i < RXBUFSIZE; u32i++)
  135.     {
  136.         /* Send 1 byte data */
  137.         UART_WRITE(UART1, u32i & 0xFF);

  138.         /* Wait if Tx FIFO is full */
  139.         while(UART_IS_TX_FULL(UART1));
  140.     }

  141.     printf("\n Transmit Done\n");

  142. }


 楼主| gaoyang9992006 发表于 2015-2-27 11:32 | 显示全部楼层
大家一起研究一下这个例程如何啊?
 楼主| gaoyang9992006 发表于 2015-2-27 11:35 | 显示全部楼层
说明文件给的是:
Transmit and receive data with auto flow control. This
sample code needs to work with UART_Autoflow_Slave.
 楼主| gaoyang9992006 发表于 2015-2-27 11:36 | 显示全部楼层
发送和接收数据通过自动流控制,这个例程需要配合UART_Autoflow_Slave,才可以工作。
这里我们看出来了,自动流模式发送,必须自动流模式接收
 楼主| gaoyang9992006 发表于 2015-2-27 11:41 | 显示全部楼层
int main(void)
{

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    /* Init UART1 for testing */
    UART1_Init();

    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    printf("\n\nCPU @ %dHz\n", SystemCoreClock);

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

    /* UART auto flow sample master function */
    AutoFlow_FunctionTxTest();

    while(1);

}从这个主函数结构我们看出来,模块化编程的妙处,五个初始化子函数,按续排列,打印消息,最后调用自动流函数发送测试子函数。意死循环等待结束。
 楼主| gaoyang9992006 发表于 2015-2-27 11:43 | 显示全部楼层
SYS_UnlockReg();
第一个初始化子函数,我们发现,总是出现这个,看。
  /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();
解锁寄存器与锁定寄存器,在任何一个例程都会出现,而且总是在前三。
 楼主| gaoyang9992006 发表于 2015-2-27 11:45 | 显示全部楼层
闲话少说,这三个的两个都不用搭理,看中间的,SYS_Init();
这个里面可以关心一下,毕竟跟我们硬件配置相关嘛,包括初始化系统,IP始终,IO配置,等。这也是该例程的最大的一个子函数,看来,这个才是难点。
 楼主| gaoyang9992006 发表于 2015-2-27 12:00 | 显示全部楼层
void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC 22.1184MHz clock */               这里我们可以根据情况修改RC振荡器的频率,对应的下面的也要相应的修改。
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);


    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */ 这里请看该芯片的系统图,把握好关系,什么分频之类的
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external XTAL 12MHz clock */                      这里使能外部的震荡器,就是晶振的频率,要跟你的外部相连的晶振保持一致,这里根据官方板子用的是12M,你也可以是24M
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);


    /* Waiting for external XTAL clock ready */  等外部晶振准备外币
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */            从PLL(锁相环)配置核心时钟。我们的晶振频率都是有限的,需要通过锁相环提供更高频率的时钟。不要问为什么,因为需要任性
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */                  串口模块当然也要使用时钟进行同步,照猫画虎就行了,看下面的,具体宏替代了什么,看头文件
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(UART1_MODULE);

    /* Select UART module clock source */                      选择串口模块的时钟源,
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
    CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set GPB multi-function pins for UART0 RXD and TXD */              配置GPB端口的管脚,使用他们的串口发送接收功能。
    /* Set GPB multi-function pins for UART1 RXD, TXD, nRTS and nCTS */

    SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk |
                                       SYS_GPB_MFP_PB4_Msk | SYS_GPB_MFP_PB5_Msk |
                                       SYS_GPB_MFP_PB6_Msk | SYS_GPB_MFP_PB7_Msk   );                照猫画虎,看好了,括号里的,

    SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD |
                                    SYS_GPB_MFP_PB4_UART1_RXD | SYS_GPB_MFP_PB5_UART1_TXD |
                                    SYS_GPB_MFP_PB6_UART1_nRTS | SYS_GPB_MFP_PB7_UART1_nCTS);

}

 楼主| gaoyang9992006 发表于 2015-2-27 12:01 | 显示全部楼层
可以参考手册里给出的串口所公用的是哪几个管脚就好理解上面的语句了。
 楼主| gaoyang9992006 发表于 2015-2-27 12:05 | 显示全部楼层
void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART0 module */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

void UART1_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART1 module */
    SYS_ResetModule(UART1_RST);

    /* Configure UART1 and set UART1 Baudrate */
    UART_Open(UART1, 115200);
}
这两个针对串口收发器进行初始化配置,初始化模块,重设。
然后以设定的波特率打开对应的串口,这个很好模仿的

 楼主| gaoyang9992006 发表于 2015-2-27 12:09 | 显示全部楼层
/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype                                                                              */
/*---------------------------------------------------------------------------------------------------------*/
extern char GetChar(void);
int32_t main(void);
void AutoFlow_FunctionTxTest(void);

回到例程的开头,看声明了什么函数。
外部函数,GetChar();该函数来自,stdio.h
主函数,
自动流函数发送测试函数。

 楼主| gaoyang9992006 发表于 2015-2-27 12:14 | 显示全部楼层
/*---------------------------------------------------------------------------------------------------------*/
/*  AutoFlow Function Tx Test                                                                                 */
/*---------------------------------------------------------------------------------------------------------*/
void AutoFlow_FunctionTxTest()
{
    uint32_t u32i;

    printf("\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|     Pin Configure                                         |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|  ______                                            _____  |\n");
    printf("| |      |                                          |     | |\n");
    printf("| |Master|--UART1_TXD(PB.5)  <==>  UART1_RXD(PB.4)--|Slave| |\n");
    printf("| |      |--UART1_nCTS(PB.7) <==> UART1_nRTS(PB.6)--|     | |\n");
    printf("| |______|                                          |_____| |\n");
    printf("|                                                           |\n");
    printf("+-----------------------------------------------------------+\n");

    printf("\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|       AutoFlow Function Test (Master)                     |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|  Description :                                            |\n");
    printf("|    The sample code needs two boards. One is Master and    |\n");
    printf("|    the other is slave. Master will send 1k bytes data     |\n");
    printf("|    to slave.Slave will check if received data is correct  |\n");
    printf("|    after getting 1k bytes data.                           |\n");
    printf("|    Press any key to start...                              |\n");
    printf("+-----------------------------------------------------------+\n");
    GetChar();

    /* Enable RTS and CTS autoflow control */
    UART_EnableFlowCtrl(UART1);

    /* Send 1k bytes data */
    for(u32i = 0; u32i < RXBUFSIZE; u32i++)
    {
        /* Send 1 byte data */
        UART_WRITE(UART1, u32i & 0xFF);

        /* Wait if Tx FIFO is full */
        while(UART_IS_TX_FULL(UART1));
    }

    printf("\n Transmit Done\n");

}
这个函数看着很长,实际上很短,前面都是打印消息。
printf("|    Press any key to start...                              |\n");
    printf("+-----------------------------------------------------------+\n");
    GetChar();

    /* Enable RTS and CTS autoflow control */
    UART_EnableFlowCtrl(UART1);

    /* Send 1k bytes data */
    for(u32i = 0; u32i < RXBUFSIZE; u32i++)
    {
        /* Send 1 byte data */
        UART_WRITE(UART1, u32i & 0xFF);

        /* Wait if Tx FIFO is full */
        while(UART_IS_TX_FULL(UART1));
看,这段,打印按任意键开始后,输出一串省略号,等带getchar.
后面开始使能RTS,CTS自动流控制器,发送1K比特的数据,我们看,通过串口写,把内容发送给了串口1,等FIFO,满信号后,等待发送完成,完成后继续下一个,这个机制很好,避免数据拥堵


598330983 发表于 2015-2-27 13:51 | 显示全部楼层
讲的很不错,要是结合手册作为证据就好了
598330983 发表于 2015-2-27 13:52 | 显示全部楼层
gaoyang9992006 发表于 2015-2-27 12:09
/*-------------------------------------------------------------------------------------------------- ...

我都是void main(void);
这里不懂为何要int32
598330983 发表于 2015-2-27 13:56 | 显示全部楼层
gaoyang9992006 发表于 2015-2-27 11:43
SYS_UnlockReg();
第一个初始化子函数,我们发现,总是出现这个,看。
  /* Unlock protected registers */ ...

是的,第一个,第三个,我就不知道什么时候修改过,
 楼主| gaoyang9992006 发表于 2015-2-27 14:03 | 显示全部楼层
598330983 发表于 2015-2-27 13:56
是的,第一个,第三个,我就不知道什么时候修改过,

说句实在话,我也不知道。头文件这么说的、
#define UNLOCKREG(x)        do{*((__IO uint32_t *)(GCR_BASE + 0x100)) = 0x59;*((__IO uint32_t *)(GCR_BASE + 0x100)) = 0x16;*((__IO uint32_t *)(GCR_BASE + 0x100)) = 0x88;}while(*((__IO uint32_t *)(GCR_BASE + 0x100))==0)
#define LOCKREG(x)          *((__IO uint32_t *)(GCR_BASE + 0x100)) = 0x00
 楼主| gaoyang9992006 发表于 2015-2-27 14:04 | 显示全部楼层
头文件关于unlockreg的定义很抽象的,咱们不懂也罢。
598330983 发表于 2015-2-27 15:28 来自手机 | 显示全部楼层
不得不说很赞,划分一下竟然看明白了
598330983 发表于 2015-2-27 15:29 来自手机 | 显示全部楼层
不得不说很赞,划分一下竟然看明白了
598330983 发表于 2015-2-27 15:29 来自手机 | 显示全部楼层
那个初始化配置有的不是太懂啊,求进一步谅解
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2048

主题

16368

帖子

221

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