打印
[通用ARM系列]

HC32F10x 系列单片机的 DMA(直接内存访问)模块来实现 ADC 数据的自动传输

[复制链接]
25|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
734774645|  楼主 | 2025-2-27 11:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AD, ADC, DM, DMA, HC
代码功能概述
ADC 配置:配置 ADC1 和 ADC2 为规则同步模式,采集两个通道的模拟信号。
DMA 配置:配置 DMA1 通道 1,将 ADC1 的转换结果自动传输到内存数组 ADC_DualConvertedValueTab 中。
中断处理:当 DMA 传输完成时,触发中断,用户可以在中断中处理采集到的数据。

(1) 系统时钟配置 (RCC_Configuration)
void RCC_Configuration(void)
{
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  // 使能 DMA1 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);  // 使能 ADC1、ADC2、AFIO 和 GPIOA 时钟
}
功能:使能 DMA1、ADC1、ADC2、AFIO 和 GPIOA 的时钟。

关键点:
DMA1 挂载在 AHB 总线上,因此需要使能 RCC_AHBPeriph_DMA1。
ADC1 和 ADC2 挂载在 APB2 总线上。

GPIO 配置 (GPIO_Configuration)
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
       
    // 配置 PA1 和 PA2 为模拟输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // 浮空输入模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 速度 50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);  // 初始化 GPIOA
}
功能:配置 PA1 和 PA2 为模拟输入模式,用于 ADC 采样。

关键点:
ADC 通道 1 对应 PA1,通道 2 对应 PA2。

ADC 配置 (ADC_Configuration)
void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;
       
    ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;  // 规则同步模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 禁用扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 使能连续转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 无外部触发
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;  // 1 个通道
    ADC_Init(ADC1, &ADC_InitStructure);  // 初始化 ADC1
    ADC_Init(ADC2, &ADC_InitStructure);  // 初始化 ADC2

    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);  // 配置 ADC1 通道 1
    ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5);  // 配置 ADC2 通道 2
       
    ADC_ExternalTrigConvCmd(ADC2, ENABLE);  // 使能 ADC2 外部触发
    ADC_DMACmd(ADC1, ENABLE);  // 使能 ADC1 的 DMA 请求
       
    ADC_Cmd(ADC1, ENABLE);  // 使能 ADC1
    ADC_Cmd(ADC2, ENABLE);  // 使能 ADC2
       
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 软件启动 ADC1 转换
}
功能:配置 ADC1 和 ADC2 为规则同步模式,并启动 ADC1 的转换。

关键点:
ADC_Mode_RegSimult:ADC1 和 ADC2 同时转换。
ADC_DMACmd:使能 ADC1 的 DMA 请求,将转换结果通过 DMA 传输到内存。

DMA 配置 (DMA_Configuration)
void DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
       
    DMA_DeInit(DMA1, DMA_Channel1);  // 复位 DMA1 通道 1
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;  // 外设地址(ADC1 数据寄存器)
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;  // 内存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  // 传输方向:外设到内存
    DMA_InitStructure.DMA_BufferSize = 4;  // 缓冲区大小(4 个数据)
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  // 外设地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  // 内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  // 外设数据宽度:32 位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;  // 内存数据宽度:32 位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;  // 高优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  // 禁用内存到内存模式
    DMA_Init(DMA1, DMA_Channel1, &DMA_InitStructure);  // 初始化 DMA1 通道 1
       
    DMA_ITConfig(DMA1, DMA_Channel1, DMA_IT_TC, ENABLE);  // 使能 DMA 传输完成中断
    DMA_Cmd(DMA1, DMA_Channel1, ENABLE);  // 使能 DMA1 通道 1
}
功能:配置 DMA1 通道 1,将 ADC1 的转换结果自动传输到内存数组 ADC_DualConvertedValueTab 中。

关键点:
DMA_Mode_Circular:循环模式,传输完成后自动重新开始。
DMA_IT_TC:使能传输完成中断。

NVIC 配置 (NVIC_Configuration)
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
  
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;  // DMA1 通道 1 中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;  // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;  // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能中断
    NVIC_Init(&NVIC_InitStructure);
}
功能:配置 DMA1 通道 1 的中断优先级并使能中断。


DMA 中断处理 (DMA1_Channel1_IRQHandler)
void DMA1_Channel1_IRQHandler(void)
{
    DMA_ClearITPendingBit(DMA1_IT_TC1);  // 清除 DMA 传输完成中断标志

    // 当进入 DMA 完成中断,意味数据采集完成
    // 此处可直接对 ADC_DualConvertedValueTab 数据进行分析
}
功能:在 DMA 传输完成时触发中断,用户可以在中断中处理采集到的数据。

关键点:
DMA_ClearITPendingBit:清除中断标志。

主函数 (main)
int main()
{
    RCC_Configuration();  // 配置时钟
    GPIO_Configuration();  // 配置 GPIO
    DMA_Configuration();  // 配置 DMA
    ADC_Configuration();  // 配置 ADC
    NVIC_Configuration();  // 配置 NVIC

    while (1) {}
}
功能:初始化系统并启动 ADC 和 DMA。


使用特权

评论回复
沙发
734774645|  楼主 | 2025-2-27 11:11 | 只看该作者
该代码通过 DMA 实现了 ADC 数据的自动传输,减少了 CPU 的负担。通过配置 ADC、DMA 和 NVIC,可以高效地采集和处理模拟信号。

使用特权

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

本版积分规则

205

主题

3506

帖子

14

粉丝