牛卧堂MCU技术交流

标题: NANO系列MCU,在非PWM波输出引脚上能否利用PDMA和TIMER输出PWM? [打印本页]

作者: bslxk    时间: 2023-6-26 17:21
标题: NANO系列MCU,在非PWM波输出引脚上能否利用PDMA和TIMER输出PWM?
本帖最后由 bslxk 于 2023-6-26 17:30 编辑

更进一步的疑问:1.GPIO的DOUT寄存器能否作为PDMA的目标地址?
2.如果1可行,DMASK寄存器会不会对PDMA写DOUT生效?
我尝试配置了一下,结果会传输失败,PDMA会置位TABORT_IS。

下面是我的配置,目标是在PE15上输出PWM:
const uint32_t DMA_PWM_Data[20] = {
    0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};

void configPDMA2(void)
{
   CLK_EnableModuleClock(DMA_MODULE);

   PDMAGCR->GCRCSR |= DMA_GCR_GCRCSR_CLK2_EN_Msk;
   // DMA连接TIMER2
   PDMAGCR->DSSR0 &= ~DMA_GCR_DSSR0_CH2_SEL_Msk;
   PDMAGCR->DSSR0 |= PDMA_TMR2 << DMA_GCR_DSSR0_CH2_SEL_Pos;

   // 存储到外设
   PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_MODE_SEL_Msk) | (0 << PDMA_CSR_MODE_SEL_Pos);
   // 32bit长度
   PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_APB_TWS_Msk) | PDMA_WIDTH_32;
   // 源地址循环
   PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_SAD_SEL_Msk) | PDMA_SAR_WRA;
   // 目标地址固定
   PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_DAD_SEL_Msk) | PDMA_DAR_FIX;

   //
   PE->DMASK = 0x7FFF;

   // 源地址设置
   PDMA2->SAR = (uint32_t)&DMA_PWM_Data[5]; // Duty50%
   // 目标地址设置
   PDMA2->DAR = (uint32_t)&PE->DOUT;
   // 传输字节数设置
   PDMA2->BCR = 10 * 4;

   // 使能传输完成中断
   // PDMA2->IER |= PDMA_IER_TD_IE_Msk;
   // 使能错误中断,发生错误后应复位DMA
   // PDMA2->IER |= PDMA_IER_TABORT_IE_Msk;
   // NVIC_EnableIRQ(PDMA_IRQn);

   // 打开DMA,开始接收传输请求
   PDMA2->CSR |= PDMA_CSR_TRIG_EN_Msk | PDMA_CSR_PDMACEN_Msk;
}

void configTIMER2(void)
{
   CLK_EnableModuleClock(TMR2_MODULE);
   // TMR2_CLK  12Mhz
   CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL2_TMR2_S_HXT, 0);

   TIMER2->PRECNT = 0;
   TIMER2->CMPR = 12000000 / 10 / 10000;

   // 周期模式
   TIMER2->CTL = (TIMER2->CTL & ~TIMER_CTL_MODE_SEL_Msk) | TIMER_PERIODIC_MODE;
   // TIM_IS 用于触发外设
   TIMER2->CTL &= ~TIMER_CTL_CAP_TRG_EN_Msk;
   // 使能TIMER触发PDMA
   TIMER2->CTL |= TIMER_CTL_PDMA_TEEN_Msk;
}




也尝试过把MODE_SEL改成Mem2Mem,结果也是TABORT。

请问是这种做法不可行,还是我的配置不对?


作者: bslxk    时间: 2023-6-26 17:28
本帖最后由 bslxk 于 2023-6-26 17:31 编辑

重新贴一下代码:
  1. const uint32_t DMA_PWM_Data[20] = {
  2.     0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF,
  3.     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};

  4. void configPDMA2(void)
  5. {
  6.    CLK_EnableModuleClock(DMA_MODULE);

  7.    PDMAGCR->GCRCSR |= DMA_GCR_GCRCSR_CLK2_EN_Msk;
  8.    // DMA连接TIMER2
  9.    PDMAGCR->DSSR0 &= ~DMA_GCR_DSSR0_CH2_SEL_Msk;
  10.    PDMAGCR->DSSR0 |= PDMA_TMR2 << DMA_GCR_DSSR0_CH2_SEL_Pos;

  11.    // 存储到外设
  12.    PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_MODE_SEL_Msk) | (0 << PDMA_CSR_MODE_SEL_Pos);
  13.    // 32bit长度
  14.    PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_APB_TWS_Msk) | PDMA_WIDTH_32;
  15.    // 源地址循环
  16.    PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_SAD_SEL_Msk) | PDMA_SAR_WRA;
  17.    // 目标地址固定
  18.    PDMA2->CSR = (PDMA2->CSR & ~PDMA_CSR_DAD_SEL_Msk) | PDMA_DAR_FIX;

  19.    //
  20.    PE->DMASK = 0x7FFF;

  21.    // 源地址设置
  22.    PDMA2->SAR = (uint32_t)&DMA_PWM_Data[5]; // Duty50%
  23.    // 目标地址设置
  24.    PDMA2->DAR = (uint32_t)&PE->DOUT;
  25.    // 传输字节数设置
  26.    PDMA2->BCR = 10 * 4;

  27.    // 使能传输完成中断
  28.    // PDMA2->IER |= PDMA_IER_TD_IE_Msk;
  29.    // 使能错误中断,发生错误后应复位DMA
  30.    // PDMA2->IER |= PDMA_IER_TABORT_IE_Msk;
  31.    // NVIC_EnableIRQ(PDMA_IRQn);

  32.    // 打开DMA,开始接收传输请求
  33.    PDMA2->CSR |= PDMA_CSR_TRIG_EN_Msk | PDMA_CSR_PDMACEN_Msk;
  34. }

  35. void configTIMER2(void)
  36. {
  37.    CLK_EnableModuleClock(TMR2_MODULE);
  38.    // TMR2_CLK  12Mhz
  39.    CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL2_TMR2_S_HXT, 0);

  40.    TIMER2->PRECNT = 0;
  41.    TIMER2->CMPR = 12000000 / 10 / 10000;

  42.    // 周期模式
  43.    TIMER2->CTL = (TIMER2->CTL & ~TIMER_CTL_MODE_SEL_Msk) | TIMER_PERIODIC_MODE;
  44.    // TIM_IS 用于触发外设
  45.    TIMER2->CTL &= ~TIMER_CTL_CAP_TRG_EN_Msk;
  46.    // 使能TIMER触发PDMA
  47.    TIMER2->CTL |= TIMER_CTL_PDMA_TEEN_Msk;
  48. }
复制代码


作者: admin    时间: 2023-6-27 10:16
如果输出方波的频率不高可以用timer+GPIO来做。PDMA可以实现memory和外设的传输,但是仅包含下面几个信号
作者: admin    时间: 2023-6-27 10:17


作者: bslxk    时间: 2023-6-27 10:41
admin 发表于 2023-6-27 10:17

感谢回复!

这样来说,这个CH1_SEL不仅仅配置了DMA传输的触发信号,也规定了DMA的传输来源或目标,是这样吗?
作者: admin    时间: 2023-6-27 13:15
bslxk 发表于 2023-6-27 02:41
感谢回复!

这样来说,这个CH1_SEL不仅仅配置了DMA传输的触发信号,也规定了DMA的传输来源或目标,是这 ...

谁触发的,目标地址或源地址就设置它的对应寄存器




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2