[综合信息] 华大HC32F460之串口

[复制链接]
4083|12
 楼主| binoo7 发表于 2021-2-11 15:23 | 显示全部楼层 |阅读模式
本帖最后由 binoo7 于 2021-2-11 16:56 编辑

#申请原创#  @小跑堂   @小跑堂    @小跑堂 @小跑堂[/url]
今天是除夕,给大家拜个早年,祝大家新年快乐
言归正传,今天来说一下华大的串口部分,根据官方手册介绍:通用串行收发器模块(USART)4 个单元,也就是有4个串口
46146024d0048cf6e.png
这就是关于串口部分的系统框图了,和其他单片机的功能是一样的,只不过他只有4个串口。
既然串口属于外设,肯定大家要关心的是他的时钟在哪?用的是哪里的时钟,根据手册的介绍,
UART 可以选择内部波特率生成器生成的时钟(内部时钟源)或 USARTn_CK 管脚输入的时钟(外部时钟源)作为通信的时钟源。
外部时钟源应用在同步的时候,一般不怎么用,不过大家如果用同步了,记得这个
应用的最多的还是异步通讯,所以我们选择的肯定是内部时钟源,根据系统时钟部分的介绍,4个串口的时钟都是PCLK1,
424646024d13342611.png
PCLK1最高频率 100MHz,挂载外设的时钟频率肯定用不了这么高,所以可选时钟源的分频:1,2,4,8,16,32,64

外甥打灯笼,照旧,我们参照厂家给的例程选取其中的一个做介绍
109806024d1ce21026.png
clk开头的是同步通讯的例程,我们不做详细介绍有需要的大家可以自己去官网下载,然后进行分析,sc开头的是智能卡相关的例程
uart开头的是异步通讯的部分,我们重点来讲解这一部分,异步通讯有6个例程,我们拿其中一个讲解,用的比较多的就是中断的例程,所以我们今天将的是中断部分
先把代码贴上来大家看一下,然后我们再逐句进行分析
  1. /*******************************************************************************
  2. * Copyright (C) 2016, Huada Semiconductor Co., Ltd. All rights reserved.
  3. *
  4. * This software is owned and published by:
  5. * Huada Semiconductor Co., Ltd. ("HDSC").
  6. *
  7. * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
  8. * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
  9. *
  10. * This software contains source code for use with HDSC
  11. * components. This software is licensed by HDSC to be adapted only
  12. * for use in systems utilizing HDSC components. HDSC shall not be
  13. * responsible for misuse or illegal use of this software for devices not
  14. * supported herein. HDSC is providing this software "AS IS" and will
  15. * not be responsible for issues arising from incorrect user implementation
  16. * of the software.
  17. *
  18. * Disclaimer:
  19. * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
  20. * REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
  21. * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
  22. * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
  23. * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
  24. * WARRANTY OF NONINFRINGEMENT.
  25. * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
  26. * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
  27. * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
  28. * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
  29. * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
  30. * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
  31. * SAVINGS OR PROFITS,
  32. * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  33. * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
  34. * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
  35. * FROM, THE SOFTWARE.
  36. *
  37. * This software may be replicated in part or whole for the licensed use,
  38. * with the restriction that this Disclaimer and Copyright notice must be
  39. * included with each copy of this software, whether used in part or whole,
  40. * at all times.
  41. */
  42. /******************************************************************************/
  43. /** \file main.c
  44. **
  45. ** \brief This sample demonstrates UART data receive and transfer by interrupt.
  46. **
  47. **   - 2018-11-27  1.0  Hongjh First version for Device Driver Library of USART
  48. **
  49. ******************************************************************************/

  50. /*******************************************************************************
  51. * Include files
  52. ******************************************************************************/
  53. #include "hc32_ddl.h"

  54. /*******************************************************************************
  55. * Local type definitions ('typedef')
  56. ******************************************************************************/

  57. /*******************************************************************************
  58. * Local pre-processor symbols/macros ('#define')
  59. ******************************************************************************/
  60. /* USART channel definition */
  61. #define USART_CH                        (M4_USART3)

  62. /* USART baudrate definition */
  63. #define USART_BAUDRATE                  (115200ul)

  64. /* USART RX Port/Pin definition */
  65. #define USART_RX_PORT                   (PortE)
  66. #define USART_RX_PIN                    (Pin04)
  67. #define USART_RX_FUNC                   (Func_Usart3_Rx)

  68. /* USART TX Port/Pin definition */
  69. #define USART_TX_PORT                   (PortE)
  70. #define USART_TX_PIN                    (Pin05)
  71. #define USART_TX_FUNC                   (Func_Usart3_Tx)

  72. /* USART interrupt number  */
  73. #define USART_RI_NUM                    (INT_USART3_RI)
  74. #define USART_EI_NUM                    (INT_USART3_EI)
  75. #define USART_TI_NUM                    (INT_USART3_TI)
  76. #define USART_TCI_NUM                   (INT_USART3_TCI)

  77. /*******************************************************************************
  78. * Global variable definitions (declared in header file with 'extern')
  79. ******************************************************************************/

  80. /*******************************************************************************
  81. * Local function prototypes ('static')
  82. ******************************************************************************/
  83. static void ClkInit(void);
  84. static void UsartRxIrqCallback(void);
  85. static void UsartTxIrqCallback(void);
  86. static void UsartTxCmpltIrqCallback(void);

  87. /*******************************************************************************
  88. * Local variable definitions ('static')
  89. ******************************************************************************/
  90. static uint16_t m_u16RxData;

  91. /*******************************************************************************
  92. * Function implementation - global ('extern') and local ('static')
  93. ******************************************************************************/
  94. /**
  95. *******************************************************************************
  96. ** \brief Initialize Clock.
  97. **
  98. ** \param [in] None
  99. **
  100. ** \retval None
  101. **
  102. ******************************************************************************/
  103. static void ClkInit(void)
  104. {
  105.     stc_clk_xtal_cfg_t   stcXtalCfg;
  106.     stc_clk_mpll_cfg_t   stcMpllCfg;
  107.     en_clk_sys_source_t  enSysClkSrc;
  108.     stc_clk_sysclk_cfg_t stcSysClkCfg;

  109.     MEM_ZERO_STRUCT(enSysClkSrc);
  110.     MEM_ZERO_STRUCT(stcSysClkCfg);
  111.     MEM_ZERO_STRUCT(stcXtalCfg);
  112.     MEM_ZERO_STRUCT(stcMpllCfg);

  113.     /* Set bus clk div. */
  114.     stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;
  115.     stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
  116.     stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
  117.     stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
  118.     stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
  119.     stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
  120.     stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
  121.     CLK_SysClkConfig(&stcSysClkCfg);

  122.     /* Switch system clock source to MPLL. */
  123.     /* Use Xtal as MPLL source. */
  124.     stcXtalCfg.enMode = ClkXtalModeOsc;
  125.     stcXtalCfg.enDrv = ClkXtalLowDrv;
  126.     stcXtalCfg.enFastStartup = Enable;
  127.     CLK_XtalConfig(&stcXtalCfg);
  128.     CLK_XtalCmd(Enable);

  129.     /* MPLL config. */
  130.     stcMpllCfg.pllmDiv = 1u; /* XTAL 8M / 1 */
  131.     stcMpllCfg.plln = 50u;   /* 8M*50 = 400M */
  132.     stcMpllCfg.PllpDiv = 4u; /* MLLP = 100M */
  133.     stcMpllCfg.PllqDiv = 4u; /* MLLQ = 100M */
  134.     stcMpllCfg.PllrDiv = 4u; /* MLLR = 100M */
  135.     CLK_SetPllSource(ClkPllSrcXTAL);
  136.     CLK_MpllConfig(&stcMpllCfg);

  137.     /* flash read wait cycle setting */
  138.     EFM_Unlock();
  139.     EFM_SetLatency(EFM_LATENCY_4);
  140.     EFM_Lock();

  141.     /* Enable MPLL. */
  142.     CLK_MpllCmd(Enable);

  143.     /* Wait MPLL ready. */
  144.     while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
  145.     {
  146.     }

  147.     /* Switch system clock source to MPLL. */
  148.     CLK_SetSysClkSource(CLKSysSrcMPLL);
  149. }

  150. /**
  151. *******************************************************************************
  152. ** \brief USART RX irq callback function.
  153. **
  154. ** \param [in] None
  155. **
  156. ** \retval None
  157. **
  158. ******************************************************************************/
  159. static void UsartRxIrqCallback(void)
  160. {
  161.     m_u16RxData = USART_RecData(USART_CH);
  162.     USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
  163. }

  164. /**
  165. *******************************************************************************
  166. ** \brief USART RX error irq callback function.
  167. **
  168. ** \param [in] None
  169. **
  170. ** \retval None
  171. **
  172. ******************************************************************************/
  173. static void UsartErrIrqCallback(void)
  174. {
  175.     if (Set == USART_GetStatus(USART_CH, UsartFrameErr))
  176.     {
  177.         USART_ClearStatus(USART_CH, UsartFrameErr);
  178.     }
  179.     else
  180.     {
  181.     }

  182.     if (Set == USART_GetStatus(USART_CH, UsartParityErr))
  183.     {
  184.         USART_ClearStatus(USART_CH, UsartParityErr);
  185.     }
  186.     else
  187.     {
  188.     }

  189.     if (Set == USART_GetStatus(USART_CH, UsartOverrunErr))
  190.     {
  191.         USART_ClearStatus(USART_CH, UsartOverrunErr);
  192.     }
  193.     else
  194.     {
  195.     }
  196. }

  197. /**
  198. *******************************************************************************
  199. ** \brief USART TX irq callback function.
  200. **
  201. ** \param [in] None
  202. **
  203. ** \retval None
  204. **
  205. ******************************************************************************/
  206. static void UsartTxIrqCallback(void)
  207. {
  208.     USART_SendData(USART_CH, m_u16RxData);
  209.     USART_FuncCmd(USART_CH, UsartTxEmptyInt, Disable);
  210.     USART_FuncCmd(USART_CH, UsartTxCmpltInt, Enable);
  211. }

  212. /**
  213. *******************************************************************************
  214. ** \brief USART TX complete irq callback function.
  215. **
  216. ** \param [in] None
  217. **
  218. ** \retval None
  219. **
  220. ******************************************************************************/
  221. static void UsartTxCmpltIrqCallback(void)
  222. {
  223.     USART_FuncCmd(USART_CH, UsartTxCmpltInt, Disable);
  224.     USART_FuncCmd(USART_CH, UsartTx, Disable);
  225. }

  226. /**
  227. *******************************************************************************
  228. ** \brief  Main function of project
  229. **
  230. ** \param  None
  231. **
  232. ** \retval int32_t return value, if needed
  233. **
  234. ******************************************************************************/
  235. int32_t main(void)
  236. {
  237.     en_result_t enRet = Ok;
  238.     stc_irq_regi_conf_t stcIrqRegiCfg;
  239.     uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
  240.                              PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
  241.     const stc_usart_uart_init_t stcInitCfg = {
  242.         UsartIntClkCkNoOutput,
  243.         UsartClkDiv_1,
  244.         UsartDataBits8,
  245.         UsartDataLsbFirst,
  246.         UsartOneStopBit,
  247.         UsartParityNone,
  248.         UsartSamleBit8,
  249.         UsartStartBitFallEdge,
  250.         UsartRtsEnable,
  251.     };

  252.     /* Initialize Clock */
  253.     ClkInit();

  254.     /* Enable peripheral clock */
  255.     PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);

  256.     /* Initialize USART IO */
  257.     PORT_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC, Disable);
  258.     PORT_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC, Disable);

  259.     /* Initialize UART */
  260.     enRet = USART_UART_Init(USART_CH, &stcInitCfg);
  261.     if (enRet != Ok)
  262.     {
  263.         while (1)
  264.         {
  265.         }
  266.     }
  267.     else
  268.     {
  269.     }

  270.     /* Set baudrate */
  271.     enRet = USART_SetBaudrate(USART_CH, USART_BAUDRATE);
  272.     if (enRet != Ok)
  273.     {
  274.         while (1)
  275.         {
  276.         }
  277.     }
  278.     else
  279.     {
  280.     }

  281.     /* Set USART RX IRQ */
  282.     stcIrqRegiCfg.enIRQn = Int000_IRQn;
  283.     stcIrqRegiCfg.pfnCallback = &UsartRxIrqCallback;
  284.     stcIrqRegiCfg.enIntSrc = USART_RI_NUM;
  285.     enIrqRegistration(&stcIrqRegiCfg);
  286.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  287.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  288.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  289.     /* Set USART RX error IRQ */
  290.     stcIrqRegiCfg.enIRQn = Int001_IRQn;
  291.     stcIrqRegiCfg.pfnCallback = &UsartErrIrqCallback;
  292.     stcIrqRegiCfg.enIntSrc = USART_EI_NUM;
  293.     enIrqRegistration(&stcIrqRegiCfg);
  294.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  295.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  296.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  297.     /* Set USART TX IRQ */
  298.     stcIrqRegiCfg.enIRQn = Int002_IRQn;
  299.     stcIrqRegiCfg.pfnCallback = &UsartTxIrqCallback;
  300.     stcIrqRegiCfg.enIntSrc = USART_TI_NUM;
  301.     enIrqRegistration(&stcIrqRegiCfg);
  302.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  303.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  304.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  305.     /* Set USART TX complete IRQ */
  306.     stcIrqRegiCfg.enIRQn = Int003_IRQn;
  307.     stcIrqRegiCfg.pfnCallback = &UsartTxCmpltIrqCallback;
  308.     stcIrqRegiCfg.enIntSrc = USART_TCI_NUM;
  309.     enIrqRegistration(&stcIrqRegiCfg);
  310.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  311.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  312.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  313.     /*Enable RX && RX interupt function*/
  314.     USART_FuncCmd(USART_CH, UsartRx, Enable);
  315.     USART_FuncCmd(USART_CH, UsartRxInt, Enable);

  316.     while (1)
  317.     {
  318.     }
  319. }

  320. /*******************************************************************************
  321. * EOF (not truncated)
  322. ******************************************************************************/

  1. /* USART 通道号宏定义 */
  2. #define USART_CH                        (M4_USART3)

  3. /* USART 波特率宏定义 */
  4. #define USART_BAUDRATE                  (115200ul)

  5. /* USART 接收功能 */
  6. #define USART_RX_PORT                   (PortE)
  7. #define USART_RX_PIN                    (Pin04)
  8. #define USART_RX_FUNC                   (Func_Usart3_Rx)

  9. /* USART 发送功能 */
  10. #define USART_TX_PORT                   (PortE)
  11. #define USART_TX_PIN                    (Pin05)
  12. #define USART_TX_FUNC                   (Func_Usart3_Tx)

  13. /* USART 中断相关的  */
  14. #define USART_RI_NUM                    (INT_USART3_RI)
  15. #define USART_EI_NUM                    (INT_USART3_EI)
  16. #define USART_TI_NUM                    (INT_USART3_TI)
  17. #define USART_TCI_NUM                   (INT_USART3_TCI)



开头宏定义很好理解,如果有看不懂的可以留言
咱们继续
  1. static void ClkInit(void)
  2. {
  3.     stc_clk_xtal_cfg_t   stcXtalCfg;
  4.     stc_clk_mpll_cfg_t   stcMpllCfg;
  5.     en_clk_sys_source_t  enSysClkSrc;
  6.     stc_clk_sysclk_cfg_t stcSysClkCfg;

  7.     MEM_ZERO_STRUCT(enSysClkSrc);
  8.     MEM_ZERO_STRUCT(stcSysClkCfg);
  9.     MEM_ZERO_STRUCT(stcXtalCfg);
  10.     MEM_ZERO_STRUCT(stcMpllCfg);

  11.     /* Set bus clk div. */
  12.     stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;//100M
  13.     stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;//50M
  14.     stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;//100M
  15.     stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;//50M
  16.     stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;//25M
  17.     stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;//25M
  18.     stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;//50M
  19.     CLK_SysClkConfig(&stcSysClkCfg);

  20.     /* Switch system clock source to MPLL. */
  21.     /* Use Xtal as MPLL source. */
  22.     stcXtalCfg.enMode = ClkXtalModeOsc;
  23.     stcXtalCfg.enDrv = ClkXtalLowDrv;
  24.     stcXtalCfg.enFastStartup = Enable;
  25.     CLK_XtalConfig(&stcXtalCfg);
  26.     CLK_XtalCmd(Enable);

  27.     /* MPLL config. */
  28.     stcMpllCfg.pllmDiv = 1u; /* XTAL 8M / 1 */
  29.     stcMpllCfg.plln = 50u;   /* 8M*50 = 400M */
  30.     stcMpllCfg.PllpDiv = 4u; /* MLLP = 100M */
  31.     stcMpllCfg.PllqDiv = 4u; /* MLLQ = 100M */
  32.     stcMpllCfg.PllrDiv = 4u; /* MLLR = 100M */
  33.     CLK_SetPllSource(ClkPllSrcXTAL);
  34.     CLK_MpllConfig(&stcMpllCfg);

  35.     /* flash read wait cycle setting */
  36.     EFM_Unlock();
  37.     EFM_SetLatency(EFM_LATENCY_4);
  38.     EFM_Lock();

  39.     /* Enable MPLL. */
  40.     CLK_MpllCmd(Enable);

  41.     /* Wait MPLL ready. */
  42.     while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
  43.     {
  44.     }

  45.     /* Switch system clock source to MPLL. 外部高速时钟*/
  46.     CLK_SetSysClkSource(CLKSysSrcMPLL);
  47. }



时钟配置我讲解了很多次了,可以看其他部分的帖子

我们直接看主函数部分吧
    en_result_t enRet = Ok;
    stc_irq_regi_conf_t stcIrqRegiCfg;
    uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \ PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
    const stc_usart_uart_init_t stcInitCfg = {
  这个结构体是关键,定义了参数所以用的const     
                                                                     UsartIntClkCkNoOutput,//0也就是下面这个模式
// CLKC[1:0]  时钟控制位  UART 模式
                                                       00b:时钟源为内部波特率生成器生成的时钟,时钟不输出到USATRTn_CK管脚,USARTn_CK管脚可以当作普通IO使用
                                                       01b:时钟源为内部波特率生成器生成的时钟,时钟输出到USARTn_CK管脚,输出时钟频率和波特率相同
                                             10b or 11b:时钟源为外部输入时钟,输入时钟的频率为波特率的16倍(OVER8=0)或者8倍(OVER8=1)时钟
                                     同步模式
                                             00b or 01b:时钟源为内部波特率生成器生成的时钟,输出到USARTn_CK管脚10b or 11b:时钟源为外部输入时钟,输入时钟的频率和波特率相同
                                     智能卡模式
                                                       00b:时钟源为内部波特率生成器生成的时钟,时钟不输出到CK管脚,CK管脚可以当作普通IO使用
                                                       01b:时钟源为内部波特率生成器生成的时钟,时钟输出到CK管脚10b or 11b:设定禁止注意:CLKC[1:0]位只能在TE=0&RE=0(发送/接收禁止)时设定
                                                                    UsartClkDiv_1,//内部时钟源分频
554266024d824dc80b.png
                                                                    UsartDataBits8,//数据位长度
                                                                    UsartDataLsbFirst,//
                                                                                             //MSB/LSB选择位  UART模式/时钟同步模式/智能卡模式时,MSB/LSB方式选择位
                                                                                             //0:LSB方式
                                                                                             //1:MSB方式
                                                                                            //注意:ML位只能在TE=0&RE=0(发送/接收禁止)时设定

                                                                    UsartOneStopBit,//停止位
                                                                    UsartParityNone,//校验位 三种情况  无校验  奇校验  偶校验
                                                                    UsartSamleBit8,//
                                                                                          //UART过采样模式  UART过采样模式设定,即一位数据传输期间的基本时钟数
                                                                                          //0:16位
                                                                                          //1:8位
                                                                                          //注意:非UART模式时OVER8位必须保持复位值
                                                                                          //OVER8位只能在TE=0&RE=0(发送/接收禁止)时设定

                                                                    UsartStartBitFallEdge,//
                                                                                                   //UART模式接收数据时,开始位检测方式设定位
                                                                                                   //0:开始位检测方式为RX管脚低电平
                                                                                                   //1:开始位检测方式为RX管脚下降沿
                                                                                                    //注意:非UART模式时SBS位须保持复位值SBS位只能在TE=0&RE=0(发送/接收禁止)时设定

                                                                    UsartRtsEnable,
                                                                                                  //CTS功能使能位  CTS功能使能位
                                                                                                   //0:RTS功能
                                                                                                   //1:CTS功能
                                                                                                   //注意:CTSE位只能在TE=0&RE=0(发送/接收禁止)时设定

    };


这个结构体是要配置这个USART_UART_Init初始化函数的
我们把重点的部分摘录出来,其他的可以直接去看代码
en_result_t USART_UART_Init
{
        PR_f.PSC = (uint32_t)(pstcInitCfg->enClkDiv);
        CR1_f.M = (uint32_t)(pstcInitCfg->enDataLength);
        CR1_f.ML = (uint32_t)(pstcInitCfg->enDirection);
        CR2_f.STOP = (uint32_t)(pstcInitCfg->enStopBit);
        CR2_f.CLKC = (uint32_t)(pstcInitCfg->enClkMode);
        switch(pstcInitCfg->enParity)
        {
            case UsartParityNone:
                CR1_f.PCE = (uint32_t)0ul;
                break;
            case UsartParityEven:
                CR1_f.PS = (uint32_t)0ul;
                CR1_f.PCE = (uint32_t)1ul;
                break;
            case UsartParityOdd:
                CR1_f.PS = (uint32_t)1ul;
                CR1_f.PCE = (uint32_t)1ul;
                break;
            default:
                break;
        }
        CR3_f.CTSE = (uint32_t)(pstcInitCfg->enHwFlow);
        CR1_f.SBS = (uint32_t)(pstcInitCfg->enDetectMode);
        CR1_f.OVER8 = (uint32_t)(pstcInitCfg->enSampleMode);
}


/* Set USART RX IRQ */
    stcIrqRegiCfg.enIRQn = Int000_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartRxIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_RI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART RX error IRQ */
    stcIrqRegiCfg.enIRQn = Int001_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_EI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART TX IRQ */
    stcIrqRegiCfg.enIRQn = Int002_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartTxIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_TI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART TX complete IRQ */
    stcIrqRegiCfg.enIRQn = Int003_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartTxCmpltIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_TCI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);


这几种就是中断相关的配置了,大同小异,和以前讲解的中断配置类似,到此就可以完成配置了,当有数据发送过来后,就可以通过中断进行接收
而且这里还有一点要说他的串口自动定义了一个这样特殊的功能,就是和定时器配合产生中断
在用户手册里是这样介绍的
RTOF  UART接收TIMEOUT
标志位
UART接收TIMEOUT标志位
0:无UART接收TIMEOUT
1:发生UART接收TIMEOUT
RTOF置位条件
⚫ 从检测到最后一帧数据的STOP位起经过设定时间后没有检测到新的接收数据
RTOF清零条件
⚫ 清零寄存器CR1.CRTOF位写入
注意:RTOF为由硬件置1,且只有在CR1.RE=1且CR1.RTOE=1时置1。CR1.RE=0
时,TIMEOUT功能有效,但RTOF不置1。
RTOF仅在USART_CR1.RTOE=1时读取值才为有效值,其它情况请忽略该位,使用
UART接收Timeout功能时,设置RTOE=1之前,需软件清除该位。
下面是库函数部分可以作为参考使用
  1. en_result_t USART_UART_Init(M4_USART_TypeDef *USARTx,const stc_usart_uart_init_t *pstcInitCfg);//串口初始化
  2. en_result_t USART_CLKSYNC_Init(M4_USART_TypeDef *USARTx,const stc_usart_clksync_init_t *pstcInitCfg);//同步模式时钟
  3. en_result_t USART_SC_Init(M4_USART_TypeDef *USARTx,const stc_usart_sc_init_t *pstcInitCfg);
  4. en_result_t USART_DeInit(M4_USART_TypeDef *USARTx);
  5. en_flag_status_t USART_GetStatus(M4_USART_TypeDef *USARTx,en_usart_status_t enStatus);
  6. en_result_t USART_ClearStatus(M4_USART_TypeDef *USARTx,en_usart_status_t enStatus);
  7. en_result_t USART_FuncCmd(M4_USART_TypeDef *USARTx,en_usart_func_t enFunc,en_functional_state_t enCmd);
  8. en_result_t USART_SetParity(M4_USART_TypeDef *USARTx,en_usart_parity_t enParity);
  9. en_usart_parity_t USART_GetParity(M4_USART_TypeDef *USARTx);
  10. en_result_t USART_SetOverSampling(M4_USART_TypeDef *USARTx,
  11.                                 en_usart_sample_mode_t enSampleMode);
  12. en_usart_sample_mode_t USART_GetOverSampling(M4_USART_TypeDef *USARTx);
  13. en_result_t USART_SetDataDirection(M4_USART_TypeDef *USARTx,en_usart_data_dir_t enDir);
  14. en_usart_data_dir_t USART_GetTransferDirection(M4_USART_TypeDef *USARTx);
  15. en_result_t USART_SetDataLength(M4_USART_TypeDef *USARTx,en_usart_data_len_t enDataLen);
  16. en_usart_data_len_t USART_GetDataLength(M4_USART_TypeDef *USARTx);
  17. en_result_t USART_SetClkMode(M4_USART_TypeDef *USARTx,en_usart_clk_mode_t enClkMode);
  18. en_usart_clk_mode_t USART_GetClkMode(M4_USART_TypeDef *USARTx);
  19. en_result_t USART_SetMode(M4_USART_TypeDef *USARTx,
  20.                                 en_usart_mode_t enMode);
  21. en_usart_mode_t USART_GetMode(M4_USART_TypeDef *USARTx);
  22. en_result_t USART_SetStopBitsLength(M4_USART_TypeDef *USARTx,en_usart_stop_bit_t enStopBit);
  23. en_usart_stop_bit_t USART_GetStopBitsLength(M4_USART_TypeDef *USARTx);
  24. en_result_t USART_SetSbDetectMode(M4_USART_TypeDef *USARTx,
  25.                                 en_usart_sb_detect_mode_t enDetectMode);
  26. en_usart_sb_detect_mode_t USART_GetSbDetectMode(M4_USART_TypeDef *USARTx);
  27. en_result_t USART_SetHwFlowCtrl(M4_USART_TypeDef *USARTx,
  28.                                 en_usart_hw_flow_ctrl_t enHwFlowCtrl);
  29. en_usart_hw_flow_ctrl_t USART_GetHwFlowCtrl(M4_USART_TypeDef *USARTx);
  30. en_result_t USART_SetClockDiv(M4_USART_TypeDef *USARTx,en_usart_clk_div_t enClkPrescale);
  31. en_usart_clk_div_t USART_GetClockDiv(M4_USART_TypeDef *USARTx);
  32. en_result_t USART_SetScEtuClk(M4_USART_TypeDef *USARTx,en_usart_sc_etu_clk_t enEtuClk);
  33. en_usart_sc_etu_clk_t USART_GetScEtuClk(M4_USART_TypeDef *USARTx);
  34. en_result_t USART_SendData(M4_USART_TypeDef *USARTx, uint16_t u16Data);
  35. uint16_t USART_RecData(M4_USART_TypeDef *USARTx);
  36. en_result_t USART_SetBaudrate(M4_USART_TypeDef *USARTx,uint32_t u32Baudrate);

好啦学习使我们快乐,我们一起加油吧 嘿嘿

jcky001 发表于 2021-2-14 15:04 | 显示全部楼层
好啦学习使我们快乐,我们一起加油吧 嘿嘿
如梦,如梦 发表于 2021-2-20 18:26 | 显示全部楼层
本帖最后由 如梦,如梦 于 2021-2-20 18:31 编辑

楼主,你好,我现在使用HC32F460KCTA画了个最小系统板,在uart_irq_rx_tx的例程上修改串口通道为USART2,引脚为PA11(TX),PA12(RX),使用串口调试助手连续(鼠标点击)发数据123456给单片机会出现数据丢失(丢失时只接收到其中位,如只接收到1234),使用的是外部8M晶振,示波器测量晶振正常,晶振两端引脚对地信号都是8M。另外我在DMA的串口例程使用同样的引脚同样的串口一切正常,能帮我看看吗

#define USART_CH                        (M4_USART2)

/* USART baudrate definition */
#define USART_BAUDRATE                  (115200ul)

/* USART RX Port/Pin definition */
#define USART_RX_PORT                   (PortA)
#define USART_RX_PIN                    (Pin12)
#define USART_RX_FUNC                   (Func_Usart2_Rx)

/* USART TX Port/Pin definition */
#define USART_TX_PORT                   (PortA)
#define USART_TX_PIN                    (Pin11)
#define USART_TX_FUNC                   (Func_Usart2_Tx)

/* USART interrupt number  */
#define USART_RI_NUM                    (INT_USART2_RI)
#define USART_EI_NUM                    (INT_USART2_EI)
#define USART_TI_NUM                    (INT_USART2_TI)
#define USART_TCI_NUM                   (INT_USART2_TCI)

捕获.PNG
 楼主| binoo7 发表于 2021-2-20 20:49 | 显示全部楼层
本帖最后由 binoo7 于 2021-2-20 20:52 编辑
如梦,如梦 发表于 2021-2-20 18:26
楼主,你好,我现在使用HC32F460KCTA画了个最小系统板,在uart_irq_rx_tx的例程上修改串口通道为USART2,引 ...

发一下你的串口接收中断是怎么做的,因为接收中断里有一个发送是要等到发送标志位
如梦,如梦 发表于 2021-2-22 09:46 | 显示全部楼层
我是从华大官网下载的例程,中断部分的回调函数没改过,你看下



#include "hc32_ddl.h"

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* USART channel definition */
#define USART_CH                        (M4_USART2)

/* USART baudrate definition */
#define USART_BAUDRATE                  (115200ul)

/* USART RX Port/Pin definition */
#define USART_RX_PORT                   (PortA)
#define USART_RX_PIN                    (Pin12)
#define USART_RX_FUNC                   (Func_Usart2_Rx)

/* USART TX Port/Pin definition */
#define USART_TX_PORT                   (PortA)
#define USART_TX_PIN                    (Pin11)
#define USART_TX_FUNC                   (Func_Usart2_Tx)

/* USART interrupt number  */
#define USART_RI_NUM                    (INT_USART2_RI)
#define USART_EI_NUM                    (INT_USART2_EI)
#define USART_TI_NUM                    (INT_USART2_TI)
#define USART_TCI_NUM                   (INT_USART2_TCI)

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static void ClkInit(void);
static void UsartRxIrqCallback(void);
static void UsartTxIrqCallback(void);
static void UsartTxCmpltIrqCallback(void);

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static uint16_t m_u16RxData;

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize Clock.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void ClkInit(void)
{
    stc_clk_xtal_cfg_t   stcXtalCfg;
    stc_clk_mpll_cfg_t   stcMpllCfg;
    en_clk_sys_source_t  enSysClkSrc;
    stc_clk_sysclk_cfg_t stcSysClkCfg;

    MEM_ZERO_STRUCT(enSysClkSrc);
    MEM_ZERO_STRUCT(stcSysClkCfg);
    MEM_ZERO_STRUCT(stcXtalCfg);
    MEM_ZERO_STRUCT(stcMpllCfg);

    /* Set bus clk div. */
    stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
    CLK_SysClkConfig(&stcSysClkCfg);

    /* Switch system clock source to MPLL. */
    /* Use Xtal as MPLL source. */
    stcXtalCfg.enMode = ClkXtalModeOsc;
    stcXtalCfg.enDrv = ClkXtalLowDrv;
    stcXtalCfg.enFastStartup = Enable;
    CLK_XtalConfig(&stcXtalCfg);
    CLK_XtalCmd(Enable);

    /* MPLL config. */
    stcMpllCfg.pllmDiv = 1u; /* XTAL 8M / 1 */
    stcMpllCfg.plln = 50u;   /* 8M*50 = 400M */
    stcMpllCfg.PllpDiv = 4u; /* MLLP = 100M */
    stcMpllCfg.PllqDiv = 4u; /* MLLQ = 100M */
    stcMpllCfg.PllrDiv = 4u; /* MLLR = 100M */
    CLK_SetPllSource(ClkPllSrcXTAL);
    CLK_MpllConfig(&stcMpllCfg);

    /* flash read wait cycle setting */
    EFM_Unlock();
    EFM_SetLatency(EFM_LATENCY_4);
    EFM_Lock();

    /* Enable MPLL. */
    CLK_MpllCmd(Enable);

    /* Wait MPLL ready. */
    while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
    {
    }

    /* Switch system clock source to MPLL. */
    CLK_SetSysClkSource(CLKSysSrcMPLL);
}

/**
*******************************************************************************
** \brief USART RX irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void UsartRxIrqCallback(void)
{
    m_u16RxData = USART_RecData(USART_CH);
    USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
}

/**
*******************************************************************************
** \brief USART RX error irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void UsartErrIrqCallback(void)
{
    if (Set == USART_GetStatus(USART_CH, UsartFrameErr))
    {
        USART_ClearStatus(USART_CH, UsartFrameErr);
    }
    else
    {
    }

    if (Set == USART_GetStatus(USART_CH, UsartParityErr))
    {
        USART_ClearStatus(USART_CH, UsartParityErr);
    }
    else
    {
    }

    if (Set == USART_GetStatus(USART_CH, UsartOverrunErr))
    {
        USART_ClearStatus(USART_CH, UsartOverrunErr);
    }
    else
    {
    }
}

/**
*******************************************************************************
** \brief USART TX irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void UsartTxIrqCallback(void)
{
    USART_SendData(USART_CH, m_u16RxData);
    USART_FuncCmd(USART_CH, UsartTxEmptyInt, Disable);
    USART_FuncCmd(USART_CH, UsartTxCmpltInt, Enable);
}

/**
*******************************************************************************
** \brief USART TX complete irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void UsartTxCmpltIrqCallback(void)
{
    USART_FuncCmd(USART_CH, UsartTxCmpltInt, Disable);
    USART_FuncCmd(USART_CH, UsartTx, Disable);
}

/**
*******************************************************************************
** \brief  Main function of project
**
** \param  None
**
** \retval int32_t return value, if needed
**
******************************************************************************/
int32_t main(void)
{
    en_result_t enRet = Ok;
    stc_irq_regi_conf_t stcIrqRegiCfg;
    uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
                             PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
    const stc_usart_uart_init_t stcInitCfg = {
        UsartIntClkCkNoOutput,
        UsartClkDiv_1,
        UsartDataBits8,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityNone,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
    };

    /* Initialize Clock */
    ClkInit();

    /* Enable peripheral clock */
    PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);

    /* Initialize USART IO */
    PORT_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC, Disable);
    PORT_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC, Disable);

    /* Initialize UART */
    enRet = USART_UART_Init(USART_CH, &stcInitCfg);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
    else
    {
    }

    /* Set baudrate */
    enRet = USART_SetBaudrate(USART_CH, USART_BAUDRATE);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
    else
    {
    }

    /* Set USART RX IRQ */
    stcIrqRegiCfg.enIRQn = Int000_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartRxIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_RI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART RX error IRQ */
    stcIrqRegiCfg.enIRQn = Int001_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_EI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART TX IRQ */
    stcIrqRegiCfg.enIRQn = Int002_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartTxIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_TI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART TX complete IRQ */
    stcIrqRegiCfg.enIRQn = Int003_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartTxCmpltIrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_TCI_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /*Enable RX && RX interupt function*/
    USART_FuncCmd(USART_CH, UsartRx, Enable);
    USART_FuncCmd(USART_CH, UsartRxInt, Enable);

    while (1)
    {
    }
}
勇者无惧你和我 发表于 2021-2-22 11:52 | 显示全部楼层
过年的时候,还在个工作的人,都是勤奋的人。
勇敢的大白菜 发表于 2021-2-22 12:12 | 显示全部楼层
感谢楼主新年分享,不错。
 楼主| binoo7 发表于 2021-2-22 13:29 | 显示全部楼层
如梦,如梦 发表于 2021-2-22 09:46
我是从华大官网下载的例程,中断部分的回调函数没改过,你看下

static void UsartRxIrqCallback(void)
{
     m_u16RxData = USART_RecData(USART_CH);
     USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
}
直留下这一个中断,其他的都删除了,还有这个中断里不能这么写 接收到数据后等待发送为空然后就进行发送就好了,不要去使能发送中断,直接static void UsartRxIrqCallback(void)
{
    m_u16RxData = USART_RecData(USART_CH);
    USART_SendData(USART_CH, m_u16RxData);
}用这个试一下
如梦,如梦 发表于 2021-2-22 16:05 | 显示全部楼层
感谢回复,问题找到了,程序正常的,是我的USB转串口模块有问题,换了一个就好了
如梦,如梦 发表于 2021-2-22 16:07 | 显示全部楼层
另外问下,刚看到立创上华大MCU也要订货了,现在华大MCU供货紧张吗
 楼主| binoo7 发表于 2021-2-22 16:58 | 显示全部楼层
如梦,如梦 发表于 2021-2-22 16:07
另外问下,刚看到立创上华大MCU也要订货了,现在华大MCU供货紧张吗

问题解决了就好
我不是华大官方的,
我们在用这款芯片,买了个开发板,在做车市的过程中就把自己的理解和大家分享出来,这样也好让咱们的国产芯片应用更广泛
杨寅辉 发表于 2021-2-22 19:58 | 显示全部楼层
binoo7 发表于 2021-2-22 16:58
问题解决了就好
我不是华大官方的,
我们在用这款芯片,买了个开发板,在做车市的过程 ...

楼主打字错误,应该是测试吧,不是车市。
uikkhkhhh 发表于 2021-5-24 13:20 | 显示全部楼层
楼主请教一下这个 在设置串口接收超时中的定时器填入的cmp的值是啥意思 手册上的公式没理解
1621833616(1).jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

457

帖子

10

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