找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[NANO] NANO系列MCU,在非PWM波输出引脚上能否利用PDMA和TIMER输出PWM?

[复制链接]
跳转到指定楼层
楼主
bslxk 发表于 2023-6-26 17:21:47 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
本帖最后由 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。

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

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具 举报

6#
admin 发表于 2023-6-27 13:15:52 | 只看该作者
bslxk 发表于 2023-6-27 02:41
感谢回复!

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

谁触发的,目标地址或源地址就设置它的对应寄存器
牛卧堂
回复 支持 反对

使用道具 举报

5#
 楼主| bslxk 发表于 2023-6-27 10:41:21 | 只看该作者

感谢回复!

这样来说,这个CH1_SEL不仅仅配置了DMA传输的触发信号,也规定了DMA的传输来源或目标,是这样吗?
回复 支持 反对

使用道具 举报

地板
admin 发表于 2023-6-27 10:17:22 | 只看该作者

牛卧堂
回复 支持 反对

使用道具 举报

板凳
admin 发表于 2023-6-27 10:16:48 | 只看该作者
如果输出方波的频率不高可以用timer+GPIO来做。PDMA可以实现memory和外设的传输,但是仅包含下面几个信号
牛卧堂
回复 支持 反对

使用道具 举报

沙发
 楼主| bslxk 发表于 2023-6-26 17:28:42 | 只看该作者
本帖最后由 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. }
复制代码

回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU