找回密码
立即注册
搜索
热搜: 活动 交友 discuz
发新帖

143

积分

0

好友

12

主题
发表于 2023-9-17 01:59:10 | 查看: 988| 回复: 3 IP:中国广东省 中国电信公众宽带

如题,DMA能将ADC和USART连在一起吗

发表于 2023-9-17 01:59:48 IP:中国广东省 中国电信公众宽带

DMA(直接存储器访问)可以用于将ADC和USART连接起来,这样可以在不占用CPU时间的情况下实现数据的传输。通常,使用DMA的方式是将ADC的数据存储到内存中,然后使用DMA将数据从内存传输到USART的数据寄存器中,最终通过USART将数据发送出去。在实现这个过程中,需要使用DMA控制器来设置DMA传输的参数和传输方向,并且需要配置ADC和USART的相关寄存器以启动数据的采集和发送。

发表于 2023-9-17 02:00:15 IP:中国广东省 中国电信公众宽带
DMA不支持外设到外设
发表于 2023-9-17 02:01:20 IP:中国广东省 中国电信公众宽带

可以将DMA、ADC和USART连在一起,通过DMA实现ADC采集后数据的自动传输到USART进行发送。以下是基于GD32的例程,需要使用GD32标准固件库。

首先,需要进行相关的初始化,包括DMA、ADC、USART和GPIO。

#include "gd32e10x.h"

void dma_adc_usart_init(void)
{
    /* DMA clock enable */
    rcu_periph_clock_enable(RCU_DMA);
    /* ADC clock enable */
    rcu_periph_clock_enable(RCU_ADC);
    /* USART clock enable */
    rcu_periph_clock_enable(RCU_USART0);
    /* GPIO clock enable */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* DMA configuration */
    dma_deinit(DMA_CH0);
    dma_parameter_struct dma_init_struct;
    dma_struct_para_init(&dma_init_struct);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)adc_value;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number = 1;
    dma_init_struct.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH0, dma_init_struct);

    /* ADC configuration */
    adc_parameter_struct adc_init_struct;
    adc_struct_para_init(&adc_init_struct);
    adc_init_struct.clock_sync = ADC_CLOCK_SYNC_PCLK_DIV4;
    adc_init_struct.resolution = ADC_RESOLUTION_12B;
    adc_init_struct.data_alignment = ADC_DATAALIGN_RIGHT;
    adc_init_struct.scan_mode = ADC_SCAN_MODE_SINGLE;
    adc_init_struct.continuous_mode = DISABLE;
    adc_init_struct.external_trigger = ADC_EXTERNAL_TRIGGER_DISABLE;
    adc_init_struct.channel_number = 0;
    adc_init(ADC0, &adc_init_struct);
    adc_calibration_enable(ADC0);

    /* USART configuration */
    usart_deinit(USART0);
    usart_parameter_struct usart_init_struct;
    usart_struct_para_init(&usart_init_struct);
    usart_init_struct.baud_rate = 115200;
    usart_init_struct.word_length = USART_WL_8BIT;
    usart_init_struct.stop_bits = USART_STB_1BIT;
    usart_init_struct.parity = USART_PM_NONE;
    usart_init_struct.mode = USART_MODE_TX;
    usart_init_struct.flow_restriction = USART_FLOWCONTROL_NONE;
    usart_init_struct.overrun_error_detection = USART_OEDETECT_DISABLE;
    usart_init(USART0, &usart_init_struct);
    usart_enable(USART0);

    /* GPIO configuration */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);

    /* Enable DMA channel */
    dma_channel_enable(DMA_CH0);
}

然后,在ADC采样和USART发送之间使用DMA进行数据传输。

void dma_adc_usart_transfer(void)
{
    /* Start ADC conversion */
    adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL);
    while(!adc_flag_get(ADC0, ADC_FLAG_EOC));

    /* DMA transfer */
    dma_transfer_enable(DMA_CH0);

    /* Wait for transfer to complete */
    while(dma_flag_get(DMA_CH0, DMA_FLAGF_FTF) == RESET);

    /* Clear DMA flag */
    dma_flag_clear(DMA_CH0, DMA_FLAGF_FTF);

    /* USART send data */
    usart_data_transmit(USART0, adc_value[0]);
}

完整的代码如下:

#include "gd32e10x.h"

uint16_t adc_value[1];

void dma_adc_usart_init(void)
{
    /* DMA clock enable */
    rcu_periph_clock_enable(RCU_DMA);
    /* ADC clock enable */
    rcu_periph_clock_enable(RCU_ADC);
    /* USART clock enable */
    rcu_periph_clock_enable(RCU_USART0);
    /* GPIO clock enable */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* DMA configuration */
    dma_deinit(DMA_CH0);
    dma_parameter_struct dma_init_struct;
    dma_struct_para_init(&dma_init_struct);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)adc_value;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number = 1;
    dma_init_struct.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH0, dma_init_struct);

    /* ADC configuration */
    adc_parameter_struct adc_init_struct;
    adc_struct_para_init(&adc_init_struct);
    adc_init_struct.clock_sync = ADC_CLOCK_SYNC_PCLK_DIV4;
    adc_init_struct.resolution = ADC_RESOLUTION_12B;
    adc_init_struct.data_alignment = ADC_DATAALIGN_RIGHT;
    adc_init_struct.scan_mode = ADC_SCAN_MODE_SINGLE;
    adc_init_struct.continuous_mode = DISABLE;
    adc_init_struct.external_trigger = ADC_EXTERNAL_TRIGGER_DISABLE;
    adc_init_struct.channel_number = 0;
    adc_init(ADC0, &adc_init_struct);
    adc_calibration_enable(ADC0);

    /* USART configuration */
    usart_deinit(USART0);
    usart_parameter_struct usart_init_struct;
    usart_struct_para_init(&usart_init_struct);
    usart_init_struct.baud_rate = 115200;
    usart_init_struct.word_length = USART_WL_8BIT;
    usart_init_struct.stop_bits = USART_STB_1BIT;
    usart_init_struct.parity = USART_PM_NONE;
    usart_init_struct.mode = USART_MODE_TX;
    usart_init_struct.flow_restriction = USART_FLOWCONTROL_NONE;
    usart_init_struct.overrun_error_detection = USART_OEDETECT_DISABLE;
    usart_init(USART0, &usart_init_struct);
    usart_enable(USART0);

    /* GPIO configuration */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);

    /* Enable DMA channel */
    dma_channel_enable(DMA_CH0);
}

void dma_adc_usart_transfer(void)
{
    /* Start ADC conversion */
    adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL);
    while(!adc_flag_get(ADC0, ADC_FLAG_EOC));

    /* DMA transfer */
    dma_transfer_enable(DMA_CH0);

    /* Wait for transfer to complete */
    while(dma_flag_get(DMA_CH0, DMA_FLAGF_FTF) == RESET);

    /* Clear DMA flag */
    dma_flag_clear(DMA_CH0, DMA_FLAGF_FTF);

    /* USART send data */
    usart_data_transmit(USART0, adc_value[0]);
}

int main(void)
{
    /* DMA, ADC, USART and GPIO initialization */
    dma_adc_usart_init();

    while(1)
    {
        /* DMA, ADC and USART data transfer */
        dma_adc_usart_transfer();
    }
}
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|国产电子社区 ( 沪ICP备2023018578号-1|

苏公网安备 32011102010465号


)|网站地图

GMT+8, 2024-12-9 10:07 , Processed in 0.055490 second(s), 26 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表