嵌入式学习小组
直播中

李晓鹏

7年用户 1290经验值
私信 关注

如何在ML的低功耗模式下使用PDMA?

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2019 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

//***********************************************************************************************************
//  Website: http://www.nuvoton.com
//  E-Mail : MicroC-8bit@nuvoton.com
//***********************************************************************************************************

//***********************************************************************************************************
//  File Function: ML51 simple GPIO toggle out demo code
//***********************************************************************************************************

#include "ML51.h"


/**
* @brief       Low power run mode Memory to memory function demo
* @param       None
* @return      None
* @Details     
*/

unsigned char xdata RxDatabuffer[100] _at_ 0x100;
unsigned char xdata finalbuffer _at_ 0x263;
unsigned char i;

void PDMA1_ISR(void) interrupt 21          // Vector @  0xAB
{
  PDMA_Close(PDMA1);
  clr_DMA1TSR_FDONE;
  clr_DMA1TSR_HDONE;
}

void main (void)
{
    ALL_GPIO_QUASI_MODE;

    for(i=0;i<100;i++)
    {
      RxDatabuffer=i;
    }
/* Define PMDA function as memory to memory, and setting base address */   
    PDMA_Open(PDMA1,XRAM_XRAM,0x100,0x80);
/* Define destination memory address */   
    PDMA_MTM_DestinationAddress(PDMA1,0x200);
/* Define interrupt after full transfer */   
    PDMA_Interrupt_Enable(PDMA1,PDMAFULLINT);
    ENABLE_GLOBAL_INTERRUPT;
   
    FsysSelect(FSYS_LIRC);
    set_PCON_LPR;
    PDMA_Run(PDMA1);

    while(1);
}









/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2019 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

//***********************************************************************************************************
//  Website: http://www.nuvoton.com
//  E-Mail : MicroC-8bit@nuvoton.com
//***********************************************************************************************************

//***********************************************************************************************************
//  File Function: ML51 simple GPIO toggle out demo code
//***********************************************************************************************************

#include "ML51.h"

    unsigned char xdata RxDatabuffer[100] _at_ 0x100;
    unsigned char ct;
/**
* @brief       Low power run mode UART TX or receive demo
* @param       None
* @return      None
* @details     
*/

void PDMA0_ISR(void) interrupt 20          // Vector @  0xA3
{  
/* if need check with XRAM PDMA value, should enable following part */
//  clr_PCON_LPR;
//  FsysSelect(FSYS_HIRC);
/* ******************** */
  PDMA_Close(PDMA0);
  SFRS=0;DMA0TSR=0;
/*only for check PDMA reciverd */
//  while(1)
//  {
//    P14=0;
//    P14=1;
//  }
//  printf (" \n PDMA receiv UART2 RX finish! " );
/* ****** */
}
   
   
void main (void)
{

#if 1  
    MFP_P46_CLKO;
    P46_QUASI_MODE;
    set_CKCON_CLOEN;
  
    MFP_P54_UART2_TXD;
    P54_QUASI_MODE;
    LowPower_LIRC_UART2_4800_init();
  
/*Enable Low power run mode */  
    FsysSelect(FSYS_LIRC);
    set_PCON_LPR;
  
    while(1)
    {
      LowPower_UART2_Send_Data(0x55);
      _delay_();
    }
#else
    All_GPIO_QUASI_MODE;
    MFP_P14_GPIO;
   
/* Enable UART2 RX */      
    MFP_P55_UART2_RXD;
    P55_INPUT_MODE;
    LowPower_LIRC_UART2_4800_init();
  
/* Clear XRAM base address area to 00h */
    for(ct=0;ct<10;ct++)
    {
      RxDatabuffer[ct]=0;
    }
/* Define PMDA function as UART RX to memory, define base address and PDMA receive length */   
    PDMA_Open(PDMA0,SMCRX,0x100,5);
/* Define interrupt after full transfer */
    PDMA_Interrupt_Enable(PDMA0,PDMAFULLINT);
/* Global interrupt enable */
    ENABLE_GLOBAL_INTERRUPT;
/* Start PDMA transfer */
    PDMA_Run(PDMA0);
   
/*Enable Low power run mode */  
    FsysSelect(FSYS_LIRC);
    set_PCON_LPR;
  
    while(1);
#endif   

}






ML51 run in low power run mode with enable PDMA function to execute memory to memory function

ML51 run in low power run mode and enable UART2 receive data storage in XRAM with PDMA enable.



回帖(1)

陈敏

2024-3-29 14:45:08
sp;                             *//*----------------------------------------------------------------------------------------------------------*/

1. 使用PDMA的低功耗模式
PDMA低功耗模式是将DMA控制器放入睡眠模式,减少功耗和中断响应的时间。
在低功耗模式下,DMA控制器只需在传输数据时被唤醒,传输完成后再进入睡眠模式。可以通过在配置寄存器中设置相应的位来启用PDMA的低功耗模式:

PDMA->CSR |= PDMA_CSR_PWRDWN_Msk;

2. 使用PDMA传输数据
使用PDMA传输数据需要进行以下步骤:

(1)设置源地址和目的地址

PDMA->SAR[x] = (uint32_t)src_addr;

PDMA->DAR[x] = (uint32_t)dst_addr;

其中x表示PDMA通道号,src_addr和dst_addr分别为源地址和目的地址的指针。

(2)设置传输量

PDMA->DSCT[x].CTL = PDMA_WIDTH_8 | PDMA_SAR_INC | PDMA_DAR_INC | (transfer_size - 1);

其中x表示PDMA通道号,transfer_size表示需要传输的数据量,PDMA_WIDTH_8表示数据宽度为8位,PDMA_SAR_INC和PDMA_DAR_INC表示源地址和目的地址按照指针自动增加。

(3)启动传输

PDMA->DSCT[x].CTL |= PDMA_OP_SCATTER;

PDMA->CSR |= PDMA_CSR_TRIG_EN_Msk;

其中x表示PDMA通道号,PDMA_OP_SCATTER表示采用散布/聚集(scatter-gather)模式,PDMA_CSR_TRIG_EN_Msk表示启动传输。

3. 中断处理函数

当传输完成时,PDMA控制器会产生中断。可以在中断处理函数中获取传输结果并进行相应的处理:

void PDMA_IRQHandler(void)
{
    uint32_t status = PDMA_GET_INT_STATUS();

    if (status & (1 << x))
    {
        if (PDMA_GET_TD_STS() & (1 << x))
        {
            /* transmission succeed */
        }
        else
        {
            /* transmission failed */
        }

        PDMA_CLR_TD_FLAG(1 << x);
    }
}

其中x表示PDMA通道号,PDMA_GET_INT_STATUS()用于获取PDMA中断状态,PDMA_GET_TD_STS()用于获取传输完成的通道号,PDMA_CLR_TD_FLAG()用于清除传输完成的通道的中断标志位。

总结:

使用PDMA的低功耗模式可以有效降低功耗,适用于一些低功耗要求较高的场景。需要注意的是,PDMA只能用于DMA传输,无法用于其他类型的传输。在使用PDMA时应该仔细设置传输量和传输方式,避免传输错误和效率低下的问题。
举报

更多回帖

×
20
完善资料,
赚取积分