打印
[技术问答]

HC32F460 串口1DMA 只能收不能发 是什么问题

[复制链接]
197|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feng89|  楼主 | 2025-2-16 21:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*****************以下是串口1 配置 *******************/

/*
  再次复位 DMA,防止假死
*/

/* DMA definition */
#define RX1_DMA_UNIT                     (CM_DMA2)
#define RX1_DMA_CH                       (DMA_CH0)
#define RX1_DMA_FCG_ENABLE()             (FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA2, ENABLE))
#define RX1_DMA_TRIG_SEL                 (AOS_DMA2_0)
#define RX1_DMA_TRIG_EVT_SRC             (EVT_SRC_USART1_RI)
#define RX1_DMA_RECONF_TRIG_SEL          (AOS_DMA_RC)
#define RX1_DMA_RECONF_TRIG_EVT_SRC      (EVT_SRC_AOS_STRG)
#define RX1_DMA_TC_INT                   (DMA_INT_TC_CH0)
#define RX1_DMA_TC_FLAG                  (DMA_FLAG_TC_CH0)
#define RX1_DMA_TC_IRQn                  (INT042_IRQn)
#define RX1_DMA_TC_INT_SRC               (INT_SRC_DMA2_TC0)

#define TX1_DMA_UNIT                     (CM_DMA2)
#define TX1_DMA_CH                       (DMA_CH1)
#define TX1_DMA_FCG_ENABLE()             (FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA2, ENABLE))
#define TX1_DMA_TRIG_SEL                 (AOS_DMA2_1)
#define TX1_DMA_TRIG_EVT_SRC             (EVT_SRC_USART1_TI)
#define TX1_DMA_TC_INT                   (DMA_INT_TC_CH1)
#define TX1_DMA_TC_FLAG                  (DMA_FLAG_TC_CH1)
#define TX1_DMA_TC_IRQn                  (INT043_IRQn)
#define TX1_DMA_TC_INT_SRC               (INT_SRC_DMA2_TC1)

static void USART1_TxComplete_IrqCallback(void) //发送完成中断
{
    USART_FuncCmd(CM_USART1, (USART_TX | USART_INT_TX_CPLT), DISABLE);
    USART_ClearStatus(CM_USART1, USART_FLAG_TX_CPLT);
}
/**
接收错误中断.
*/
static void USART1_RxError_IrqCallback(void)
{
    (void)USART_ReadData(CM_USART1);
    USART_ClearStatus(CM_USART1, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR | USART_FLAG_OVERRUN));
}
int cnt;
char Dbuf1_T[60];

static void USART1_RxFull_IrqCallback(void) //中断方式接收数据
{
           Dbuf1_T[cnt++]=CM_USART1->RDR;
           if(cnt>50) cnt=0;
}
/*
接收完成设定的字节中断
*/
static void RX1_DMA_TC_IrqCallback(void)
{
    DMA_ClearTransCompleteStatus(RX1_DMA_UNIT, RX1_DMA_TC_FLAG);
}
/*
发送完成中断
*/
int oy;
static void TX1_DMA_TC_IrqCallback(void)
{
    USART_FuncCmd(CM_USART1, USART_INT_TX_CPLT, ENABLE);
    DMA_ClearTransCompleteStatus(TX1_DMA_UNIT, TX1_DMA_TC_FLAG);
          OUTCLRYAB1();
        oy++;
}


static int32_t DMA_Config_UART1(void)
{
    int32_t i32Ret;
    stc_dma_init_t stcDmaInit;
    stc_dma_llp_init_t stcDmaLlpInit;
    stc_irq_signin_config_t stcIrqSignConfig;
    static stc_dma_llp_descriptor_t stcLlpDesc;
    /* DMA&AOS FCG enable */
    RX1_DMA_FCG_ENABLE();
    TX1_DMA_FCG_ENABLE();
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* DMA1 FCG enable */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA2, ENABLE);//DMA1使能
    /* AOS FCG enable */
    /* USART1_RX_DMA 接收*/
    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn = DMA_INT_ENABLE;//DMA 中断使能
    stcDmaInit.u32BlockSize = 1UL;
    stcDmaInit.u32TransCount = 500;// 尺寸
    stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;   //数据宽度
    stcDmaInit.u32DestAddr = (uint32_t)Dbuf1;  //接收的寄存器
    stcDmaInit.u32SrcAddr = (uint32_t)(&CM_USART1->RDR);//接收的 源地址
    stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_FIX;  //源地址固定
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;//目标地址 加 1
    i32Ret = DMA_Init(CM_DMA2,DMA_CH0, &stcDmaInit);
               
    if (LL_OK == i32Ret) {
        (void)DMA_LlpStructInit(&stcDmaLlpInit);
        stcDmaLlpInit.u32State = DMA_LLP_ENABLE;
        stcDmaLlpInit.u32Mode  = DMA_LLP_WAIT;
        stcDmaLlpInit.u32Addr  = (uint32_t)&stcLlpDesc;
        (void)DMA_LlpInit(CM_DMA2, DMA_CH0, &stcDmaLlpInit);
                       
        stcLlpDesc.SARx   = stcDmaInit.u32SrcAddr;
        stcLlpDesc.DARx   = stcDmaInit.u32DestAddr;
        stcLlpDesc.DTCTLx = (stcDmaInit.u32TransCount << DMA_DTCTL_CNT_POS) | (stcDmaInit.u32BlockSize << DMA_DTCTL_BLKSIZE_POS);;
        stcLlpDesc.LLPx   = (uint32_t)&stcLlpDesc;
        stcLlpDesc.CHCTLx = stcDmaInit.u32SrcAddrInc | stcDmaInit.u32DestAddrInc | stcDmaInit.u32DataWidth |  \
                            stcDmaInit.u32IntEn      | stcDmaLlpInit.u32State    | stcDmaLlpInit.u32Mode;
        DMA_ReconfigLlpCmd(CM_DMA2, DMA_CH0, ENABLE);
        DMA_ReconfigCmd(CM_DMA2, ENABLE);
        AOS_SetTriggerEventSrc(RX1_DMA_RECONF_TRIG_SEL, RX1_DMA_RECONF_TRIG_EVT_SRC);

        stcIrqSignConfig.enIntSrc = RX1_DMA_TC_INT_SRC;
        stcIrqSignConfig.enIRQn  = RX1_DMA_TC_IRQn;
        stcIrqSignConfig.pfnCallback = &RX1_DMA_TC_IrqCallback;
        (void)INTC_IrqSignIn(&stcIrqSignConfig);
        NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
        NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
        NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);

        AOS_SetTriggerEventSrc(RX1_DMA_TRIG_SEL, RX1_DMA_TRIG_EVT_SRC);

        DMA_Cmd(CM_DMA2, ENABLE);
        DMA_TransCompleteIntCmd(CM_DMA2, RX1_DMA_TC_INT, ENABLE);
        (void)DMA_ChCmd(CM_DMA2, DMA_CH0, ENABLE);
    }

    /* USART1_TX_DMA  发送*/
               
    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn = DMA_INT_ENABLE;
    stcDmaInit.u32BlockSize = 1UL;
    stcDmaInit.u32TransCount = 1;
    stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
    stcDmaInit.u32DestAddr = (uint32_t)(&CM_USART1->TDR);
    stcDmaInit.u32SrcAddr = (uint32_t)Uar1PDMA;
    stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
    i32Ret = DMA_Init(TX1_DMA_UNIT, TX1_DMA_CH, &stcDmaInit);
               
    if (LL_OK == i32Ret) {
        stcIrqSignConfig.enIntSrc = TX1_DMA_TC_INT_SRC;
        stcIrqSignConfig.enIRQn  = TX1_DMA_TC_IRQn;
        stcIrqSignConfig.pfnCallback = &TX1_DMA_TC_IrqCallback;
        (void)INTC_IrqSignIn(&stcIrqSignConfig);
        NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
        NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
        NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);

        AOS_SetTriggerEventSrc(TX1_DMA_TRIG_SEL, TX1_DMA_TRIG_EVT_SRC);
        DMA_Cmd(TX1_DMA_UNIT, ENABLE);
        DMA_TransCompleteIntCmd(TX1_DMA_UNIT, TX1_DMA_TC_INT, ENABLE);
                         (void)DMA_ChCmd(TX1_DMA_UNIT, TX1_DMA_CH, ENABLE);
    }
    return i32Ret;
}
void UART1_DMA_REST(void)
{
    stc_dma_init_t stcDmaInit;
    /* USART1_RX_DMA */
    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn = DMA_INT_ENABLE;//DMA 中断使能
    stcDmaInit.u32BlockSize = 1UL;
    stcDmaInit.u32TransCount = 90;// 尺寸
    stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;   //数据宽度
    stcDmaInit.u32DestAddr = (uint32_t)Dbuf1;  //接收的寄存器
    stcDmaInit.u32SrcAddr = (uint32_t)(&CM_USART1->RDR);//接收的 源地址
    stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_FIX;  //源地址固定
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;//目标地址 加 1
    DMA_Init(CM_DMA2, DMA_CH0, &stcDmaInit);
}
/************初始化串口*************/
void UART1_INIT(unsigned int Bua_dat)
{
          stc_usart_uart_init_t stcUartInit;
          stc_irq_signin_config_t stcIrqSigninConfig;
       
    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_02,GPIO_FUNC_32);//USART1-TX
    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_03,GPIO_FUNC_33);//USART1-RX

     /* Enable USART1 clock */
    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USART1, ENABLE);//打开串口时钟
    /* 初始化串口 参数 */
    (void)USART_UART_StructInit(&stcUartInit);
    stcUartInit.u32ClockSrc = USART_CLK_SRC_INTERNCLK;
    stcUartInit.u32ClockDiv = USART_CLK_DIV64;
    stcUartInit.u32Baudrate = Bua_dat;//USART_BAUDRATE;
                stcUartInit.u32StopBit =  USART_STOPBIT_1BIT;
                stcUartInit.u32Parity =   USART_PARITY_NONE;
    stcUartInit.u32OverSampleBit = USART_OVER_SAMPLE_8BIT;
    USART_UART_Init(CM_USART1, &stcUartInit, NULL);
       
    /* Register TX complete IRQ handler. */
    stcIrqSigninConfig.enIRQn = INT080_IRQn;
    stcIrqSigninConfig.enIntSrc = INT_SRC_USART1_TCI;
          stcIrqSigninConfig.pfnCallback = &USART1_TxComplete_IrqCallback;//发送完成中断 中断
    (void)INTC_IrqSignIn(&stcIrqSigninConfig);
    NVIC_ClearPendingIRQ(stcIrqSigninConfig.enIRQn);
    NVIC_SetPriority(stcIrqSigninConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSigninConfig.enIRQn);
               
    /* Register RX error IRQ handler. */
    stcIrqSigninConfig.enIRQn = INT081_IRQn;
    stcIrqSigninConfig.enIntSrc = INT_SRC_USART1_EI;
    stcIrqSigninConfig.pfnCallback = &USART1_RxError_IrqCallback;//接收错误中断
    (void)INTC_IrqSignIn(&stcIrqSigninConfig);
    NVIC_ClearPendingIRQ(stcIrqSigninConfig.enIRQn);
    NVIC_SetPriority(stcIrqSigninConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSigninConfig.enIRQn);       

    /* Register RX error IRQ handler. */
    stcIrqSigninConfig.enIRQn = INT082_IRQn;
    stcIrqSigninConfig.enIntSrc = INT_SRC_USART1_RI;//INT_SRC_USART1_EI;
    stcIrqSigninConfig.pfnCallback = &USART1_RxFull_IrqCallback;//接收错误中断
    (void)INTC_IrqSignIn(&stcIrqSigninConfig);
    NVIC_ClearPendingIRQ(stcIrqSigninConfig.enIRQn);
    NVIC_SetPriority(stcIrqSigninConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSigninConfig.enIRQn);
    USART_FuncCmd(CM_USART1, (USART_TX | USART_RX ), ENABLE);//使能收发功能,并启用接收中断
}
//DMA发送数据
void TX1_DMA1_SEND(unsigned int len) //第一串口通道
{
                DMA_SetSrcAddr(TX1_DMA_UNIT, TX1_DMA_CH, (uint32_t)Uar1PDMA);
                DMA_SetTransCount(TX1_DMA_UNIT, TX1_DMA_CH, len);
                (void)DMA_ChCmd(TX1_DMA_UNIT, TX1_DMA_CH, ENABLE);
                USART_FuncCmd(CM_USART1,(USART_TX | USART_INT_TX_CPLT), ENABLE);
}

使用特权

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

本版积分规则

40

主题

162

帖子

1

粉丝