问答

汇集网友智慧,解决技术难题

21ic问答首页 - GD32H759 定时器触发+DMA控制任意IO做PWM和脉冲数控制

单片机 国产芯片 嵌入式 技术交流 技术资源

GD32H759 定时器触发+DMA控制任意IO做PWM和脉冲数控制

ryan_jiang2025-03-11
在使用GD32H759的定时器出发DMA搬数据到GPIO的BOP寄存器来控制GPIO的翻转做PWM和脉冲数的控制。DMA能进入传输完成中断,但是并没有把数据搬运到GPIO的BOP寄存器使GPIO口翻转。不知道是什么原因。有没有大神解答下的,万分感谢!代码如下:
const uint32_t vPulse_Data[17] = {0x00080004,0x00040008,0x00080004,0x00040008,0x00080004,0x00040008,0x00080004,0x00040008,
                                                                                    0x00080004,0x00040008,0x00080004,0x00040008,0x00080004,0x00040008,0x00080004,0x00040008,
                                                                                    0x0000000C};/*PD2,PD3  U pluse*/
void pwm_gpio_config(void)
{
        rcu_periph_clock_enable(RCU_GPIOD);  


    /* LED0引脚模式设置 */
    gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3        \
                                  |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3        \
                                  |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11);
        gpio_port_write(GPIOD,0x0000);
}
                                                                                       

/*!
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void time2_dma_config(void)
{
    /* ADC_DMA_channel configuration */
    dma_single_data_parameter_struct dma_single_data_parameter;
       
        rcu_periph_clock_enable(RCU_DMA0);
        nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
    nvic_irq_enable(DMA0_Channel2_IRQn, 1, 0);

    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH2);
       


    /* initialize DMA single data mode */
    dma_single_data_parameter.request = DMA_REQUEST_TIMER2_UP;
    dma_single_data_parameter.periph_addr = (uint32_t)&GPIO_BOP(GPIOD);
    dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_single_data_parameter.memory0_addr = (uint32_t)(vPulse_Data);
    dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;
    dma_single_data_parameter.direction = DMA_MEMORY_TO_PERIPH;
    dma_single_data_parameter.number = 17;
    dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
        dma_single_data_parameter.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
    dma_single_data_mode_init(DMA0, DMA_CH2, &dma_single_data_parameter);

    /* enable DMA circulation mode */
    dma_circulation_disable(DMA0, DMA_CH2);
       
        dma_interrupt_enable(DMA0, DMA_CH2, DMA_INT_FTF);

    /* enable DMA channel */
//    dma_channel_enable(DMA0, DMA_CH2);
       

}


void timer2_config(uint32_t freq_hz)
{
    rcu_periph_clock_enable(RCU_TIMER2);

    timer_parameter_struct timer_initpara;
    timer_struct_para_init(&timer_initpara);

    timer_initpara.prescaler = 0; // 无分频,时钟=300MHz
    timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection = TIMER_COUNTER_UP;
       
    timer_initpara.period = (300000000 / freq_hz / 2) - 1; // 自动重载值
    timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
    timer_init(TIMER2, &timer_initpara);
       
        timer_auto_reload_shadow_enable(TIMER2);

    // 启用更新事件DMA请求
    timer_dma_enable(TIMER2, TIMER_DMA_UPD);

    timer_enable(TIMER2);
}

void DMA0_Channel2_IRQHandler(void)
{
        if(RESET != dma_interrupt_flag_get(DMA0, DMA_CH2, DMA_INT_FLAG_FTF))
        {
                dma_interrupt_flag_clear(DMA0, DMA_CH2, DMA_INT_FLAG_FTF);
                timer_disable(TIMER2);
                dma_channel_disable(DMA0, DMA_CH2);
               

    }
}



回答 +关注 0
182人浏览 1人回答问题 分享 举报
1 个回答

您需要登录后才可以回复 登录 | 注册