[BGI evaluation] + serial port DMA to send and receive data

If the serial port transmission is realized by interrupt, the interrupt function must be frequently entered, which will undoubtedly increase the burden of the MCU and interfere with the operation of normal programs. For some real-time applications, such as digital display applications, the LCD screen display may be affected and not normal display. The DMA is used to send and receive data through the serial port. During the data sending and receiving process, no MCU intervention is required. The DMA independently completes the data sending and receiving. After receiving or sending, it enters the interrupt for subsequent processing, so the MCU is more efficient.
In the routine provided by BGI, the application of serial port DMA transceiver is relatively simple. I will use DMA to implement serial port transceiver based on previous experience.

It is implemented on the basis of DEMO board D provided by Huada free of charge. The MCU model is HC32F460. A brief introduction to the resources used by the current routine
1. It has 2 DMA control units and a total of 8 independent channels, which can independently operate different DMA transfer functions. ;
2, there are four serial transceiver modules (USART unit), the flexibility to full duplex data exchange with an external device;


realizes the functions of,
1, system initialization and delay tick,
2, send and receive serial data, with DMA implementation, the maximum data sent
and received at a time is USART_DATA_BUFF_SIZE-1 characters, 3. Use the receive timeout interrupt to achieve a transmission of less than (USART_DATA_BUFF_SIZE-1) characters in the received data at a time,


there are 4 files, respectively as follows:

  Systick.c system tick file

/************************************************* *****************************
* File name: SysTick.c
* Description: SysTick system tick clock 10us interrupt function library, interrupt time Freely configurable,
* 1us 10us 1ms interrupt is commonly used.         
* Experimental platform: Huada HC32F460
* Hardware connection: -----------------
* | |
* | None |
* | |
* ----------- ------
* Library version:
*
* Author: David liu  
* Blog: https://blog.csdn.net/qq_15548761
******************** ************************************************** ************/
#include "systick.h"
#include "usart.h"

uint32_t TimingDelay volatile;

uint16_t mainDelayMS;

uint16_t beepCnt;
uint8_t beepTimes;

uint16_t TimerSoundON;
uint16_t TimerSoundOFF;


/ *
* function name: SysTick_Init
* Description: start the system timer tick the SysTick
* Input: None
* Output: None
* Call: external call 
* /
void SysTick_Init(void)
{
    stc_irq_regi_conf_t stcIrqRegiCfg;
        /* SystemFrequency / 1000 1ms interrupt once
         * SystemFrequency / 100000 10us interrupt once
         * SystemFrequency / 1000000 1us interrupt once
         */
        TimingDelay = 0;
        if (SysTick_Config(SystemCoreClock / 1000))
        while(1);
    
//  SysTick->LOAD  = (uint32_t)((SystemCoreClock / 1000) - 1UL);                         /* set reload register */
//  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
//  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
//  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
//                   SysTick_CTRL_TICKINT_Msk   |
//                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
    /* Set USART RX error IRQ */
StcIrqRegiCfg.enIRQn = SysTick_IRQn //;
// = & stcIrqRegiCfg.pfnCallback SysTick_IRQHandler;
// stcIrqRegiCfg.enIntSrc = USART_RTO_NUM;
// enIrqRegistration (& stcIrqRegiCfg);
// NVIC_SetPriority (stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
// NVIC_ClearPendingIRQ (stcIrqRegiCfg.enIRQn) ;
// NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}


/*
* Function name: Delay_us
* Description : Us delay program, 1ms as a unit
* Input:-nTime
* Output: None
* Call: Delay_us( 1) to achieve the delay Time is 1 * 10us = 10us
*: external call 
*/

void SysTickDelay_ms(__IO uint32_t nTime)

  TimingDelay = nTime;

  while(TimingDelay != 0)
  {
      __nop();
      usart_rxData_process();
  }
}

void BIBI_CntDown(void);
/*
* Function name: TimingDelay_Decrement
* Description: Get the beat program
* Input: None
* Output: None
* calls: SysTick interrupt function SysTick_Handler () call
* /  
void SysTick_IRQHandler (void)
{
    static uint16_t timeCnt = 0;
    IF (TimingDelay)
        TimingDelay--;
        IF (mainDelayMS)
                mainDelayMS--;

        timeCnt ++;
        if(timeCnt >= 500)
        {
                timeCnt = 0;
        }
        BIBI_CntDown();
        
}


void        BIBI_CntDown(void)
{
        if(beepCnt)                //        蜂鸣器延时
        {
                beepCnt--;
                if(!beepCnt)
                {
                        if(!beepTimes)
                                BeepOut(0);
                        else
                        {
                                beepTimes--;
                                if(beepTimes%2)
                                {
                                        beepCnt = TimerSoundOFF;
                    BeepOut(0);
                                }
                                else
                                {
                    BeepOut(1);
                                        beepCnt = TimerSoundON;
                                }
                        }
                }
        }
}


void        BIBI_Start(uint8_t        bibiTimes)
{
        {
                beepTimes = bibiTimes*2-1;
                BeepOut(1);
                beepCnt = DEF_BIBI_DELAY_TIMER;
        TimerSoundON  = DEF_BIBI_DELAY_TIMER ;
                TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
        }
}


void        BIBI_LongStart(uint8_t        bibiTimes)
{
        {
                beepTimes = bibiTimes*2-1;
                BeepOut(1);
                beepCnt = DEF_LONG_BIBI_DELAY;
        TimerSoundON  = DEF_LONG_BIBI_DELAY ;
                TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
        }
}

/*****************************************************************
      void  Buzzer(unsigned char idata  SoundType );
*****************************************************************/
void Buzzer(unsigned char  SoundType )
{
//    switch(SoundType)
//        { 
//        case SHORT_BI   :   TimerSoundON  = DEF_BIBI_DELAY_TIMER ;
//                                        TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
//                                                        beepTimes     = 1 ;          // On  1-time
//                                                        break;
//                case SHORT_BI_2 :   TimerSoundON  = DEF_BIBI_DELAY_TIMER ;
//                                                        TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
//                                                        beepTimes     = 3 ;          // On, Off, On
//                                                        break;
//                case SHORT_BI_3 :   TimerSoundON  = DEF_BIBI_DELAY_TIMER ;
//                                        TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
//                                                        beepTimes     = 5 ;          // On, Off, On, Off, On ( 3-times)
//                                                        break;
//                case LONG_BI    :   TimerSoundON  = DEF_BIBI_DELAY_TIMER*3 ;
//                                        TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
//                                                        beepTimes     = 9;           // On  10/2=5 times
//                                                        break;
//                case LONG_BI_2  :   TimerSoundON  = DEF_BIBI_DELAY_TIMER*3 ;
//                                        TimerSoundOFF = DEF_BIBI_DELAY_TIMER ;
//                                                        beepTimes     = 19;           //  On, Off, 10 times
//                                                        break;
//        }
        BeepOut(1);
        beepCnt = TimerSoundON;
}



void Sound_KeyOK(void)
{
//    Buzzer(SHORT_BI);
}

void Sound_KeyError(void)
{
//    Buzzer(SHORT_BI_2);
}

void Sound_AxisError(void)
{
//    Buzzer(LONG_BI);
}



/************************* *****END OF FILE***********************************/



  SysTick.h

#ifndef __SYSTICK_H
#define __SYSTICK_H

#include "hc32_ddl.h"

#define                DEF_BIBI_DELAY_TIMER                20        //80
#define                DEF_LONG_BIBI_DELAY                        80        //300
#define     TIME_READ_COUNTER       15

#define     BeepOut(x)     // x = x

void SysTick_Init(void);
void Delay_10us(__IO uint32_t nTime);
void SysTickDelay_ms(__IO uint32_t nTime);

void Sound_KeyOK(void);
void Sound_KeyError(void);
void Sound_AxisError(void);


#endif /* __SYSTICK_H */

Serial data transceiver implementation file 
usart.h

#ifndef __USART_H__
#define __USART_H__

#include "hc32_ddl.h"
#include <stdio.h>
#include "hc32f46x_dmac.h"

#define     USART_DATA_BUFF_SIZE        100
#define     USART_ARRAY_SIZE        3

#define     ENABLE_USART_DMA        1

/* DMAC */
#define USART_DMA_UNIT                        (M4_DMA1)
#define RX_DMA_CH                          (DmaCh0)
#define RX_DMA_TRG_SEL                     (EVT_USART3_RI)
#define TX_DMA_CH                          (DmaCh1)
#define TX_DMA_TRG_SEL                     (EVT_USART3_TI)

/* DMA block transfer complete interrupt */
#define RX_DMA_BTC_INT_NUM                 (INT_DMA1_TC0)
#define RX_DMA_BTC_INT_IRQn                (Int002_IRQn)
#define TX_DMA_BTC_INT_NUM                 (INT_DMA1_TC1)
#define TX_DMA_BTC_INT_IRQn                (Int001_IRQn)


/* 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)
#define USART_RI_IRQn                    (Int003_IRQn)
#define USART_EI_IRQn                    (Int004_IRQn)
#define USART_TI_IRQn                    (Int005_IRQn)
#define USART_TCI_IRQn                   (Int006_IRQn)
#define USART_RTO_NUM                    (INT_USART3_RTO)
#define USART_RTO_IRQn                    (Int007_IRQn)

/* Timer0 unit definition */
#define TMR_UNIT                        (M4_TMR02)
#define TMR_FCG_PERIPH                  (PWC_FCG2_PERIPH_TIM02)

extern  uint8_t  rcvBuff[USART_ARRAY_SIZE][USART_DATA_BUFF_SIZE];
extern  uint8_t  rcvPoint ;
extern  uint8_t  rcvReceived ;
extern  uint8_t  sndBuff[USART_DATA_BUFF_SIZE];

void USART_Config(void);
void Usart_Rx_Tx(void);
void UsartRxErrProcess(void);

void    usart_tx_start_sending(uint8_t *pbuff, uint16_t  size);
void    usart_rxData_process(void);

#endif

usart.c
 

#include "usart.h"


uint8_t rcvBuff[USART_ARRAY_SIZE][USART_DATA_BUFF_SIZE];
uint8_t rcvPoint = 0;
uint8_t rcvReceived = 0;
uint8_t rcvCount = 1;
uint8_t rcvCount = 1; uint8_t rcvCount = 1; uint8_t sndB


reception timeout completion callback function, // call
// after the current set of data reception completion operation
void usart_rx_receive_finish (void)
{
#if (ENABLE_USART_DMA ==. 1)
    uint16_t CNT;

    DMA_ChannelCmd (USART_DMA_UNIT, RX_DMA_CH, the Disable);
    CNT = DMA_GetTransferCnt (USART_DMA_UNIT, RX_DMA_CH);
    rcvBuff [ rcvPoint][0] = USART_DATA_BUFF_SIZE-cnt;
    rcvReceived++;
    rcvPoint++;
    if(rcvPoint >= USART_ARRAY_SIZE)
        rcvPoint = 0;
    /* Initialize DMA. */
    DMA_SetBlockSize(USART_DMA_UNIT, RX_DMA_CH, 1);
    DMA_SetTransferCnt(USART_DMA_UNIT, RX_DMA_CH, USART_DATA_BUFF_SIZE-1);
    DMA_SetDesAddress(USART_DMA_UNIT, RX_DMA_CH, (uint32_t)(&rcvBuff[rcvPoint][1]));
    DMA_ChannelCmd(USART_DMA_UNIT, RX_DMA_CH,  Enable);
#else
    rcvBuff[rcvPoint][0] = rcvCount-1;
    rcvReceived++;
    rcvCount = 1;
    rcvPoint++;
    if(rcvPoint >= USART_ARRAY_SIZE)
        rcvPoint = 0;
#endif
}

//  启动发送数据,
void    usart_tx_start_sending(uint8_t *pbuff, uint16_t  size)
{
    uint16_t i;
    for(i  = 0; i < size; i++)
    {
        sndBuff[i] = *pbuff++;
    }
#if     (ENABLE_USART_DMA == 1)
    DMA_SetBlockSize(USART_DMA_UNIT, TX_DMA_CH, 1);
    DMA_SetTransferCnt(USART_DMA_UNIT, TX_DMA_CH, size);
    DMA_SetSrcAddress(USART_DMA_UNIT, TX_DMA_CH, (uint32_t)(&sndBuff[0]));
    /* Enable the specified DMA channel. */
    DMA_ChannelCmd(USART_DMA_UNIT, TX_DMA_CH, Enable);

    /* Clear DMA flag. */
    DMA_ClearIrqFlag(USART_DMA_UNIT, TX_DMA_CH, TrnCpltIrq);
        USART_FuncCmd(USART_CH, UsartTx, Enable);
    USART_FuncCmd(USART_CH, UsartTxEmptyInt, Enable);
#else
#endif
}

#if     (ENABLE_USART_DMA == 1)
/**
*******************************************************************************
** \brief DMA block transfer complete irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void usart_rx_Dma_IrqCallback(void)
{
    DMA_ClearIrqFlag(USART_DMA_UNIT, RX_DMA_CH, TrnCpltIrq);
    usart_rx_receive_finish();
}


/**
*******************************************************************************
** \brief DMA block transfer complete irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void usart_tx_Dma_IrqCallback(void)
{
    DMA_ClearIrqFlag(USART_DMA_UNIT, TX_DMA_CH, TrnCpltIrq);
    /* Enable the specified DMA channel. */
    DMA_ChannelCmd(USART_DMA_UNIT, TX_DMA_CH, Disable);
        USART_FuncCmd(USART_CH, UsartTx, Disable);
}
#endif


/**
*******************************************************************************
** \brief USART RX irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void UsartRxIrqCallback(void)
{
    rcvBuff[rcvPoint][rcvCount++] = USART_RecData(USART_CH);
//    USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
    if(rcvCount >= USART_DATA_BUFF_SIZE-1)
    {
        usart_rx_receive_finish();
    }
}

/**
*******************************************************************************
** \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);
    }

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

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


/**
*******************************************************************************
** \brief USART RX Timer out irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void usart_rx_timeOut_IrqCallback(void)
{
    {
        TIMER0_Cmd(TMR_UNIT, Tim0_ChannelA,Disable);
        USART_ClearStatus(USART_CH, UsartRxTimeOut);
        usart_rx_receive_finish();
    }
}


#if     (ENABLE_USART_DMA == 1)
/**
*******************************************************************************
** \brief Initialize DMA.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void DmaInit(void)
{
    stc_dma_config_t stcDmaInit;
    stc_irq_regi_conf_t stcIrqRegiCfg;

    /* Enable peripheral clock */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1,Enable);

    /* Enable DMA. */
    DMA_Cmd(USART_DMA_UNIT,Enable);

    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 1 block */
    stcDmaInit.u16TransferCnt = USART_DATA_BUFF_SIZE-1;
    stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_CH->DR)+2ul); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)(&rcvBuff[0][1]);     /* Set destination address. */
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix;  /* Set source address mode. */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease;  /* Set destination address mode. */
    stcDmaInit.stcDmaChCfg.enIntEn = Enable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
    DMA_InitChannel(USART_DMA_UNIT, RX_DMA_CH, &stcDmaInit);

    /* Enable the specified DMA channel. */
    DMA_ChannelCmd(USART_DMA_UNIT, RX_DMA_CH, Enable);

    /* Clear DMA flag. */
    DMA_ClearIrqFlag(USART_DMA_UNIT, RX_DMA_CH, TrnCpltIrq);

    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_PTDIS,Enable);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(USART_DMA_UNIT, RX_DMA_CH, RX_DMA_TRG_SEL);

    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 1 block */
    stcDmaInit.u16TransferCnt = USART_DATA_BUFF_SIZE-1;
    stcDmaInit.u32SrcAddr = (uint32_t)(&sndBuff[1]); /* Set source address. */
    stcDmaInit.u32DesAddr = ((uint32_t)(&USART_CH->DR));     /* Set destination address. */
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressIncrease;  /* Set source address mode. */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressFix;  /* Set destination address mode. */
    stcDmaInit.stcDmaChCfg.enIntEn = Enable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
    DMA_InitChannel(USART_DMA_UNIT, TX_DMA_CH, &stcDmaInit);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(USART_DMA_UNIT, TX_DMA_CH, TX_DMA_TRG_SEL);

    /* Set DMA block transfer complete IRQ */
    stcIrqRegiCfg.enIRQn = RX_DMA_BTC_INT_IRQn;
    stcIrqRegiCfg.pfnCallback = &usart_rx_Dma_IrqCallback;
    stcIrqRegiCfg.enIntSrc = RX_DMA_BTC_INT_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
    
    stcIrqRegiCfg.enIRQn = TX_DMA_BTC_INT_IRQn;
    stcIrqRegiCfg.pfnCallback = &usart_tx_Dma_IrqCallback;
    stcIrqRegiCfg.enIntSrc = TX_DMA_BTC_INT_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}
#endif

void Timer0Init(void);

//  串行数据收发器配置函数
void USART_Config(void)
{
        en_result_t enRet = Ok;
    stc_irq_regi_conf_t stcIrqRegiCfg;
        uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART3;
        const stc_usart_uart_init_t stcInitCfg = 
        {
        UsartIntClkCkOutput,
        UsartClkDiv_1,
        UsartDataBits8,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityNone,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
        };

        /* 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);

#if     (ENABLE_USART_DMA == 1)
    DmaInit();
#endif
    Timer0Init();

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

        /* Set baudrate */
        enRet = USART_SetBaudrate(USART_CH, USART_BAUDRATE);
        if (enRet != Ok)
        {
                while (1)
                {
                }
        }
    
#if     (ENABLE_USART_DMA == 0)
         /* Set USART RX IRQ */
    stcIrqRegiCfg.enIRQn = USART_RI_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);
#endif    
    / * Set USART RX error IRQ * /
    stcIrqRegiCfg.enIRQn = USART_EI_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 RX error IRQ */
    stcIrqRegiCfg.enIRQn = USART_RTO_IRQn;
    stcIrqRegiCfg.pfnCallback = &usart_rx_timeOut_IrqCallback;
    stcIrqRegiCfg.enIntSrc = USART_RTO_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
    
    /*Enable TX && RX && RX interrupt function*/
        USART_FuncCmd(USART_CH, UsartRx, Enable);
    USART_FuncCmd(USART_CH, UsartRxInt, Enable);
    
    USART_FuncCmd(USART_CH, UsartTimeOut, Enable);
    USART_FuncCmd(USART_CH, UsartTimeOutInt, Enable);
}


/**
*******************************************************************************
** \brief Initliaze Timer0.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
void Timer0Init(void)
{
    stc_clk_freq_t stcClkTmp;
    stc_tim0_base_init_t stcTimerCfg;
    stc_tim0_trigger_init_t StcTimer0TrigInit;

    MEM_ZERO_STRUCT(stcClkTmp);
    MEM_ZERO_STRUCT(stcTimerCfg);
    MEM_ZERO_STRUCT(StcTimer0TrigInit);

    /* Timer0 peripheral enable */
    PWC_Fcg2PeriphClockCmd(TMR_FCG_PERIPH, Enable);

    /* Clear CNTAR register for channel A */
    TIMER0_WriteCntReg(TMR_UNIT, Tim0_ChannelA, 0u);
    TIMER0_WriteCntReg(TMR_UNIT, Tim0_ChannelB, 0u);

    /* Config register for channel A */
    stcTimerCfg.Tim0_CounterMode = Tim0_Async;
    stcTimerCfg.Tim0_AsyncClockSource = Tim0_XTAL32;
    stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv8;
    stcTimerCfg.Tim0_CmpValue = 3200u;
    TIMER0_BaseInit (TMR_UNIT, Tim0_ChannelA, & stcTimerCfg);

    / * * In Flag Compare the Clear /
    TIMER0_ClearFlag (TMR_UNIT, Tim0_ChannelA);

    / * * Trigger Config Timer0 Hardware /
    StcTimer0TrigInit.Tim0_InTrigEnable = to false;
    StcTimer0TrigInit.Tim0_InTrigClear = to true;
    StcTimer0TrigInit.Tim0_InTrigStart = to true;
    StcTimer0TrigInit .Tim0_InTrigStop = false;
    TIMER0_HardTriggerInit(TMR_UNIT, Tim0_ChannelA, &StcTimer0TrigInit);
}


// Analyze and process a set of received data
// This function is called in the delay function to get a timely response
void usart_rxData_process(void)
{
    static uint8_t txPoint = 0;
    if(rcvReceived> 0)
    {
        rcvReceived--;
        usart_tx_start_sending(&rcvBuff[txPoint][1], rcvBuff[txPoint][0]);
        txPoint++;
        if(txPoint>=USART_ARRAY_SIZE)
            txPoint = 0;
    }
}

For applications that often use serial ports to send and receive data, use DMA to achieve MCU efficiency and improve system performance.
Post the code and discuss it together. Please correct me if there is something wrong.

Guess you like

Origin blog.csdn.net/qq_15548761/article/details/109096856