查看: 1283|回复: 0
收起左侧

第三十章:CH32V103应用教程——ADC(多通道DMA读取方式)

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-4-25 23:24:13 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 17:14 编辑

    本章主要在上一章第二十九章ADC单通道DMA读取方式的基础上进行ADC多通道DMA读取方式的应用。


    1、ADC简介及相关函数介绍

    关于ADC DMA功能,前面章节已做过介绍,在此不再赘述。本章主要进行ADC多通道DMA读取方式应用,ADC多个通道的转换结果数据使用DMA方式传输至指定的存储区,更加高效方便。

    关于ADC具体信息,可参考CH32V103应用手册.关于ADC库函数,在第十章节已进行过介绍,在此不再赘述。


    2、硬件设计

    本章教程通过ADC1通道1~5读取开发板3.3V引脚和GND引脚ADC值,并通过串口调试助手打印显示出来。其中ADC1通道1~5对应PA1~5引脚,在进行使用测试时只需用杜邦线将PA1~5引脚与3.3V 引脚和GND引脚一一连接即可。


    3、软件设计

    本章主要进行ADC多通道DMA读取方式的应用,DMA的数据传输方式为外设到存储器,本章教程在ADC单通道DMA读取方式基础上进行,可参考前面相关章节。ADC多通道DMA读取方式应用程序具体如下:

    adc.h文件
    1. #ifndef __ADC_H
    2. #define __ADC_H

    3. #include "ch32v10x_conf.h"

    4. #define  length  5

    5. void adc_Init(void);

    6. void DMA_Tx_Init(void);

    7. void ADC_DMA_CONF(void);

    8. #endif
    复制代码
    adc.h文件主要进行宏定义和函数的声明;
    adc.c文件
    1. #include "adc.h"

    2. u16 ADC_ConvertedValue[length]={0,0,0};

    3. //ADC对应GPIO初始化配置以及ADC初始化配置
    4. void adc_Init(void)
    5. {
    6.     GPIO_InitTypeDef GPIO_InitStructure;
    7.     ADC_InitTypeDef ADC_InitStructure;

    8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能GPIOA时钟和ADC

    9.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; //PA1~5对应ADC通道1~5
    10.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //GPIO模式为模拟输入
    11.     GPIO_Init(GPIOA, &GPIO_InitStructure);

    12.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //配置ADC为独立模式
    13.     ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //多通道模式下开启扫描模式
    14.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //设置开启连续转换模式
    15.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //设置转换不是由外部触发启动,软件触发启动
    16.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //设置ADC数据右对齐
    17.     ADC_InitStructure.ADC_NbrOfChannel = length;           //规则转换的ADC通道的数目
    18.     ADC_Init(ADC1, &ADC_InitStructure);                    //根据ADC_InitStructure中指定的参数初始化ADC1寄存器

    19.     RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC时钟分频为6分频

    20.     ADC_Cmd(ADC1, ENABLE);      //使能ADC1

    21.     ADC_ResetCalibration(ADC1); //重置ADC1校准寄存器。

    22.     while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束

    23.     ADC_StartCalibration(ADC1); //开启AD校准

    24.     while(ADC_GetCalibrationStatus(ADC1));      //等待校准结束
    25. }

    26. //ADC DMA模式配置
    27. void DMA_Tx_Init( void )
    28. {
    29.     DMA_InitTypeDef DMA_InitStructure;

    30.     RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); //使能开启DMA时钟

    31.     DMA_DeInit(DMA1_Channel1); //复位DMA控制器

    32.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->RDATAR;  //配置外设地址为ADC数据寄存器地址
    33.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; //配置存储器地址为读取ADC值地址
    34.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              //配置数据源为外设,即DMA传输方式为外设到存储器
    35.     DMA_InitStructure.DMA_BufferSize = length;                      //设置DMA数据缓冲区大小,此处设置为length
    36.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA外设递增模式关闭
    37.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //设置DMA存储器递增模式开启
    38.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //设置外设数据大小为半字,即两个字节
    39.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //设置存储器数据大小为半字,即两个字节
    40.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     //设置DMA模式为循环传输模式
    41.     DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA传输通道优先级为高,当使用一 DMA通道时,优先级设置不影响
    42.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        //因为此DMA传输方式为外设到存储器,因此禁用存储器到存储器传输方式
    43.     DMA_Init( DMA1_Channel1, &DMA_InitStructure );      //初始化DMA

    44.     DMA_Cmd(DMA1_Channel1 , ENABLE);  //使能DMA
    45. }

    46. void ADC_DMA_CONF(void)
    47. {
    48.     adc_Init();

    49.     DMA_Tx_Init();

    50.     // 配置 ADC 通道转换顺序为1,第一个转换,采样时间为55.5个时钟周期
    51.     ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
    52.     ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
    53.     ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);
    54.     ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);
    55.     ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_55Cycles5);

    56.     // 使能ADC DMA 请求
    57.     ADC_DMACmd(ADC1, ENABLE);

    58.     // 由于没有采用外部触发,所以使用软件触发ADC转换
    59.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    60. }
    复制代码

    adc.c文件内容与上一章类似,只是在某些配置上进行了一些修改,具体如下:

    关于GPIO引脚配置,因为多通道,因此需要对多个引脚进行配置,具体如下:
    1. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; //PA1~5对应ADC通道1~5
    2. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //GPIO模式为模拟输入
    3. GPIO_Init(GPIOA, &GPIO_InitStructure);
    复制代码

    关于ADC初始化配置,由于多通道,需要开启扫描模式,具体如下:
    1. ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //多通道模式下开启扫描模式
    复制代码

    ADC转换通道的数目,改为相应数目:
    1. ADC_InitStructure.ADC_NbrOfChannel = length;           //规则转换的ADC通道的数目
    复制代码

    关于DMA初始化配置,因为多通道,需将DMA数据缓冲区大小作修改,具体修改如下:
    1. DMA_InitStructure.DMA_BufferSize = length;                      //设置DMA数据缓冲区大小,此处设置为length
    复制代码

    此外,需要开启DMA存储器递增模式:
    1. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //设置DMA存储器递增模式开启
    复制代码

    关于ADC_DMA_CONF配置函数,因为多个通道,因此需要对其采样周期进行一一配置,具体如下:
    1.     // 配置 ADC 通道转换顺序为1,第一个转换,采样时间为55.5个时钟周期
    2.     ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
    3.     ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
    4.     ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);
    5.     ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);
    6.     ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_55Cycles5);
    复制代码

    main.c文件
    1. int main(void)
    2. {
    3.     Delay_Init();
    4.         USART_Printf_Init(115200);
    5.     ADC_DMA_CONF();

    6.         printf("SystemClk:%d\r\n",SystemCoreClock);


    7.     printf("\r\n ADC多通道DMA读取测试 \r\n");

    8.     while (1)
    9.     {

    10.         printf("\r\n The current ADCH1 value = %d \r\n", ADC_ConvertedValue[0]);
    11.         printf("\r\n The current ADCH2 value = %d \r\n", ADC_ConvertedValue[1]);
    12.         printf("\r\n The current ADCH3 value = %d \r\n", ADC_ConvertedValue[2]);
    13.         printf("\r\n The current ADCH4 value = %d \r\n", ADC_ConvertedValue[3]);
    14.         printf("\r\n The current ADCH5 value = %d \r\n", ADC_ConvertedValue[4]);

    15.         Delay_Ms(500);
    16.     }
    17. }
    复制代码
    main.c文件主要进行函数初始化和ADC值打印输出。


    4、下载验证

    将编译好的程序下载到开发板并复位,使用杜邦线将PA1-5引脚与3.3V引脚和GND引脚连接起来,其中,PA1-3接GND引脚,PA4-5接3.3V引脚,串口显示如下:
    CH32V CH573单片机芯片-第三十章:CH32V103应用教程——ADC(多通道DMA读取方式)risc-v单片机中文社区(1)

    ADC-DMA读取多通道.rar附件下载
    CH32V CH573单片机芯片-第三十章:CH32V103应用教程——ADC(多通道DMA读取方式)risc-v单片机中文社区(2) 29、ADC-DMA读取多通道.rar (482.54 KB, 下载次数: 11)
    链接:https://pan.baidu.com/s/1QLdBHUs_R-MlVcqPiEzdFg
    提取码:4xb2
    复制这段内容后打开百度网盘手机App,操作更方便哦








    上一篇:第二十九章:CH32V103应用教程——ADC(单通道DMA读取方式)
    下一篇:第三十一章:CH32V103应用教程——ADC-单通道中断读取方式
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-4-18 16:33 , Processed in 2.247712 second(s), 48 queries .

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