打印
[综合信息]

华大HC32F460之串口

[复制链接]
2796|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
binoo7|  楼主 | 2021-2-11 15:23 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 binoo7 于 2021-2-11 16:56 编辑

#申请原创#  @小跑堂   @小跑堂    @小跑堂 @小跑堂[/url]
今天是除夕,给大家拜个早年,祝大家新年快乐
言归正传,今天来说一下华大的串口部分,根据官方手册介绍:通用串行收发器模块(USART)4 个单元,也就是有4个串口

这就是关于串口部分的系统框图了,和其他单片机的功能是一样的,只不过他只有4个串口。
既然串口属于外设,肯定大家要关心的是他的时钟在哪?用的是哪里的时钟,根据手册的介绍,
UART 可以选择内部波特率生成器生成的时钟(内部时钟源)或 USARTn_CK 管脚输入的时钟(外部时钟源)作为通信的时钟源。
外部时钟源应用在同步的时候,一般不怎么用,不过大家如果用同步了,记得这个
应用的最多的还是异步通讯,所以我们选择的肯定是内部时钟源,根据系统时钟部分的介绍,4个串口的时钟都是PCLK1,

PCLK1最高频率 100MHz,挂载外设的时钟频率肯定用不了这么高,所以可选时钟源的分频:1,2,4,8,16,32,64

外甥打灯笼,照旧,我们参照厂家给的例程选取其中的一个做介绍

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

/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"

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

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

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

/* USART RX Port/Pin definition */
#define USART_RX_PORT                   (PortE)
#define USART_RX_PIN                    (Pin04)
#define USART_RX_FUNC                   (Func_Usart3_Rx)

/* USART TX Port/Pin definition */
#define USART_TX_PORT                   (PortE)
#define USART_TX_PIN                    (Pin05)
#define USART_TX_FUNC                   (Func_Usart3_Tx)

/* USART interrupt number  */
#define USART_RI_NUM                    (INT_USART3_RI)
#define USART_EI_NUM                    (INT_USART3_EI)
#define USART_TI_NUM                    (INT_USART3_TI)
#define USART_TCI_NUM                   (INT_USART3_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)
    {
    }
}

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

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

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

/* USART 接收功能 */
#define USART_RX_PORT                   (PortE)
#define USART_RX_PIN                    (Pin04)
#define USART_RX_FUNC                   (Func_Usart3_Rx)

/* USART 发送功能 */
#define USART_TX_PORT                   (PortE)
#define USART_TX_PIN                    (Pin05)
#define USART_TX_FUNC                   (Func_Usart3_Tx)

/* USART 中断相关的  */
#define USART_RI_NUM                    (INT_USART3_RI)
#define USART_EI_NUM                    (INT_USART3_EI)
#define USART_TI_NUM                    (INT_USART3_TI)
#define USART_TCI_NUM                   (INT_USART3_TCI)



开头宏定义很好理解,如果有看不懂的可以留言
咱们继续
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;//100M
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;//50M
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;//100M
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;//50M
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;//25M
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;//25M
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;//50M
    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);
}



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

我们直接看主函数部分吧
    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,//内部时钟源分频

                                                                    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之前,需软件清除该位。
下面是库函数部分可以作为参考使用
en_result_t USART_UART_Init(M4_USART_TypeDef *USARTx,const stc_usart_uart_init_t *pstcInitCfg);//串口初始化
en_result_t USART_CLKSYNC_Init(M4_USART_TypeDef *USARTx,const stc_usart_clksync_init_t *pstcInitCfg);//同步模式时钟
en_result_t USART_SC_Init(M4_USART_TypeDef *USARTx,const stc_usart_sc_init_t *pstcInitCfg);
en_result_t USART_DeInit(M4_USART_TypeDef *USARTx);
en_flag_status_t USART_GetStatus(M4_USART_TypeDef *USARTx,en_usart_status_t enStatus);
en_result_t USART_ClearStatus(M4_USART_TypeDef *USARTx,en_usart_status_t enStatus);
en_result_t USART_FuncCmd(M4_USART_TypeDef *USARTx,en_usart_func_t enFunc,en_functional_state_t enCmd);
en_result_t USART_SetParity(M4_USART_TypeDef *USARTx,en_usart_parity_t enParity);
en_usart_parity_t USART_GetParity(M4_USART_TypeDef *USARTx);
en_result_t USART_SetOverSampling(M4_USART_TypeDef *USARTx,
                                en_usart_sample_mode_t enSampleMode);
en_usart_sample_mode_t USART_GetOverSampling(M4_USART_TypeDef *USARTx);
en_result_t USART_SetDataDirection(M4_USART_TypeDef *USARTx,en_usart_data_dir_t enDir);
en_usart_data_dir_t USART_GetTransferDirection(M4_USART_TypeDef *USARTx);
en_result_t USART_SetDataLength(M4_USART_TypeDef *USARTx,en_usart_data_len_t enDataLen);
en_usart_data_len_t USART_GetDataLength(M4_USART_TypeDef *USARTx);
en_result_t USART_SetClkMode(M4_USART_TypeDef *USARTx,en_usart_clk_mode_t enClkMode);
en_usart_clk_mode_t USART_GetClkMode(M4_USART_TypeDef *USARTx);
en_result_t USART_SetMode(M4_USART_TypeDef *USARTx,
                                en_usart_mode_t enMode);
en_usart_mode_t USART_GetMode(M4_USART_TypeDef *USARTx);
en_result_t USART_SetStopBitsLength(M4_USART_TypeDef *USARTx,en_usart_stop_bit_t enStopBit);
en_usart_stop_bit_t USART_GetStopBitsLength(M4_USART_TypeDef *USARTx);
en_result_t USART_SetSbDetectMode(M4_USART_TypeDef *USARTx,
                                en_usart_sb_detect_mode_t enDetectMode);
en_usart_sb_detect_mode_t USART_GetSbDetectMode(M4_USART_TypeDef *USARTx);
en_result_t USART_SetHwFlowCtrl(M4_USART_TypeDef *USARTx,
                                en_usart_hw_flow_ctrl_t enHwFlowCtrl);
en_usart_hw_flow_ctrl_t USART_GetHwFlowCtrl(M4_USART_TypeDef *USARTx);
en_result_t USART_SetClockDiv(M4_USART_TypeDef *USARTx,en_usart_clk_div_t enClkPrescale);
en_usart_clk_div_t USART_GetClockDiv(M4_USART_TypeDef *USARTx);
en_result_t USART_SetScEtuClk(M4_USART_TypeDef *USARTx,en_usart_sc_etu_clk_t enEtuClk);
en_usart_sc_etu_clk_t USART_GetScEtuClk(M4_USART_TypeDef *USARTx);
en_result_t USART_SendData(M4_USART_TypeDef *USARTx, uint16_t u16Data);
uint16_t USART_RecData(M4_USART_TypeDef *USARTx);
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 (431.59 KB )

捕获.PNG

使用特权

评论回复
地板
binoo7|  楼主 | 2021-2-20 20:49 | 只看该作者
本帖最后由 binoo7 于 2021-2-20 20:52 编辑
如梦,如梦 发表于 2021-2-20 18:26
楼主,你好,我现在使用HC32F460KCTA画了个最小系统板,在uart_irq_rx_tx的例程上修改串口通道为USART2,引 ...

发一下你的串口接收中断是怎么做的,因为接收中断里有一个发送是要等到发送标志位

使用特权

评论回复
5
如梦,如梦| | 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)
    {
    }
}

使用特权

评论回复
6
勇者无惧你和我| | 2021-2-22 11:52 | 只看该作者
过年的时候,还在个工作的人,都是勤奋的人。

使用特权

评论回复
7
勇敢的大白菜| | 2021-2-22 12:12 | 只看该作者
感谢楼主新年分享,不错。

使用特权

评论回复
8
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);
}用这个试一下

使用特权

评论回复
9
如梦,如梦| | 2021-2-22 16:05 | 只看该作者
感谢回复,问题找到了,程序正常的,是我的USB转串口模块有问题,换了一个就好了

使用特权

评论回复
10
如梦,如梦| | 2021-2-22 16:07 | 只看该作者
另外问下,刚看到立创上华大MCU也要订货了,现在华大MCU供货紧张吗

使用特权

评论回复
11
binoo7|  楼主 | 2021-2-22 16:58 | 只看该作者
如梦,如梦 发表于 2021-2-22 16:07
另外问下,刚看到立创上华大MCU也要订货了,现在华大MCU供货紧张吗

问题解决了就好
我不是华大官方的,
我们在用这款芯片,买了个开发板,在做车市的过程中就把自己的理解和大家分享出来,这样也好让咱们的国产芯片应用更广泛

使用特权

评论回复
12
杨寅辉| | 2021-2-22 19:58 | 只看该作者
binoo7 发表于 2021-2-22 16:58
问题解决了就好
我不是华大官方的,
我们在用这款芯片,买了个开发板,在做车市的过程 ...

楼主打字错误,应该是测试吧,不是车市。

使用特权

评论回复
13
uikkhkhhh| | 2021-5-24 13:20 | 只看该作者
楼主请教一下这个 在设置串口接收超时中的定时器填入的cmp的值是啥意思 手册上的公式没理解

1621833616(1).jpg (215.26 KB )

1621833616(1).jpg

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

454

帖子

8

粉丝