打印

GD32F405RET6的DMA+GPIO问题

[复制链接]
1091|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
alexz2008|  楼主 | 2022-5-15 23:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想通过DMA向GPIO引脚写入数据,在GD32F105RBT6下测试成功,但是在F405下一直没效果,求教大佬们!


代码如下:
测试功能:通过修改dma_buffer中数据来点亮PA8引脚上的LED灯

#define TRANSFER_NUM            1
uint32_t dma_buffer[TRANSFER_NUM] = {0};

void dma_test_gpio_config(void);
void dma_test_timer_config(void);
void dma_test_dma_config(void);

void dma_test_gpio_config(void)
{       
        rcu_periph_clock_enable(RCU_GPIOA);

    /*configure PA8(TIMER0 CH0) as alternate function*/
        gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
        gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
        gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_8);
}

void dma_test_dma_config(void)
{
    dma_single_data_parameter_struct dma_init_struct;

    rcu_periph_clock_enable(RCU_DMA1);

    dma_deinit(DMA1, DMA_CH5);

    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;
    dma_init_struct.memory0_addr  = (uint32_t)dma_buffer;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_32BIT;
    dma_init_struct.number       = TRANSFER_NUM;
    dma_init_struct.periph_addr  = (uint32_t)&GPIO_OCTL(GPIOA);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
                dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
    dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);
    dma_channel_subperipheral_select(DMA1,DMA_CH5,DMA_SUBPERI6);
       
    /* enable DMA1 transfer */
    dma_channel_enable(DMA1, DMA_CH5);
}

void dma_test_timer_config(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER0);
    timer_deinit(TIMER0);

    /* TIMER0 configuration */
    timer_initpara.prescaler         = 1680-1;//0;//107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 10000;//135;//999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0,&timer_initpara);

    /* CH0 configuration in PWM1 mode */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_HIGH;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,0);
//    timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_ACTIVE);
    timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
    timer_primary_output_config(TIMER0,ENABLE);

    timer_dma_enable(TIMER0,TIMER_DMA_UPD);

    timer_auto_reload_shadow_enable(TIMER0);
               
    timer_enable(TIMER0);
}

void dma_test_init(void)
{
    dma_test_gpio_config();
    dma_test_dma_config();
    dma_test_timer_config();
       
                GPIO_OCTL(GPIOA) = 0;//0xFFFF;
}

void dma_test_loop(void){
        int n = 0;
        while(1){
                if(n == 0){
                        dma_buffer[0] = 0x0000;
                        n = 1;
                }else{
                        dma_buffer[0] = 0xffff;
                        n = 0;
                }
                delay_1ms(500);
        }
}

使用特权

评论回复
沙发
sonicll| | 2022-5-16 09:11 | 只看该作者
你如果是想用TIMER的更新事件触发DMA,然后往GPIOA的输出寄存器传数,那需要把PA8配置成推挽输出模式,而不是AF模式,TIMER的输出比较功能也不需要配置。
如果是想用TIMER的输出比较模式直接输出,那就不需要配DMA

使用特权

评论回复
板凳
alexz2008|  楼主 | 2022-5-16 09:51 | 只看该作者
找到问题了,是地址配置的问题,F105下使用DMA_MEMORY_TO_PERIPH可以写GPIO,但是F405下不行,改成DMA_MEMORY_TO_MEMORY,就可以了

    dma_init_struct.direction    = DMA_MEMORY_TO_MEMORY;
    dma_init_struct.memory0_addr  = (uint32_t)&GPIO_OCTL(GPIOA);
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_32BIT;
    dma_init_struct.number       = 4;//TRANSFER_NUM;
    dma_init_struct.periph_addr  = (uint32_t)dma_buffer;
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_ENABLE;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
                dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;

使用特权

评论回复
地板
alexz2008|  楼主 | 2022-5-16 09:54 | 只看该作者
sonicll 发表于 2022-5-16 09:11
你如果是想用TIMER的更新事件触发DMA,然后往GPIOA的输出寄存器传数,那需要把PA8配置成推挽输出模式,而不 ...

是的,之前是设置成OUTPUT_PP的,因为其它问题导致一直不成功,所以试了各种修改,谢谢的回复!

使用特权

评论回复
5
sonicll| | 2022-5-16 10:11 | 只看该作者
alexz2008 发表于 2022-5-16 09:51
找到问题了,是地址配置的问题,F105下使用DMA_MEMORY_TO_PERIPH可以写GPIO,但是F405下不行,改成DMA_MEMO ...

改成MEMORY_TO_MEMORY模式,逻辑应该和你想要的不一样,MEMORY_TO_MEMORY是不需要硬件信号触发DMA的,也就是你即使不配置TIMER,应该也能传输。

使用特权

评论回复
6
alexz2008|  楼主 | 2022-5-16 12:57 | 只看该作者
sonicll 发表于 2022-5-16 10:11
改成MEMORY_TO_MEMORY模式,逻辑应该和你想要的不一样,MEMORY_TO_MEMORY是不需要硬件信号触发DMA的,也 ...

嗯,就是我希望的模式,多谢

使用特权

评论回复
7
alexz2008|  楼主 | 2022-5-17 15:39 | 只看该作者
本帖最后由 alexz2008 于 2022-5-17 15:41 编辑

还是搞错了,DMA_MEMORY_TO_PERIPH是能用的,还是我配置问题:

        /* DMA channel 4 initialize */
        dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;
        dma_init_struct.memory0_addr  = (uint32_t)_matrix_dma_buffer;
        dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
        dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_16BIT;

        dma_init_struct.number       = MATRIX_BUFFER_SIZE;


        dma_init_struct.periph_addr  = (uint32_t)&GPIO_OCTL(GPIOC);
        dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;

        dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
        dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
        
        dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);
    dma_channel_subperipheral_select(DMA1,DMA_CH5,DMA_SUBPERI6);

dma_channel_enable(DMA1, DMA_CH5);

只是数据传输还是有点错误,继续填坑去了

使用特权

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

本版积分规则

4

主题

14

帖子

0

粉丝