CH32V208CBU6的单片机使用多通道ADC配合DMA怎么样让内存中的数据自动更新。

我使用ADC开启DMA功能,把ADC采集到的数据存入数组中,数组中确实有数据,但是不会刷新,相似只运行了一次。有没有大佬指导一下,是什么原因.

Snipaste_2024-08-14_13-37-43.png会不会把这个连续转换功能打开就可以了


image.pngADC这里的转换模式都已经设置了,


这个是DMA的配置代码image.png


数组里面的数据不会变化image.png


你好。这个是我的使用的工程代码,是成功检测2路ADC电压的。

#include "adc.h"


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


//ADC对应GPIO初始化配置以及ADC初始化配置

void adc_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure={0};

    ADC_InitTypeDef  ADC_InitStructure={0};


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); //使能GPIOA时钟和ADC

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


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;  //配置2个检测脚

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;           //GPIO模式为模拟输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //配置ADC为独立模式

    ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //多通道模式下开启扫描模式

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //设置开启连续转换模式

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //设置转换不是由外部触发启动,软件触发启动

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //设置ADC数据右对齐

    ADC_InitStructure.ADC_NbrOfChannel = 2;                //规则转换的ADC通道的数目

    ADC_Init(ADC1, &ADC_InitStructure);                    //根据ADC_InitStructure中指定的参数初始化ADC1寄存器

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


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

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


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

while(ADC_GetCalibrationStatus(ADC1));  //等待校准结束

}


//ADC DMA模式配置

void DMA_Tx_Init( void )

{

    DMA_InitTypeDef DMA_InitStructure={0};

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

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


    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->RDATAR;  //配置外设地址为ADC数据寄存器地址

    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; //配置存储器地址为读取ADC值地址

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              //配置数据源为外设,即DMA传输方式为外设到存储器

    DMA_InitStructure.DMA_BufferSize = 2;                      //设置DMA数据缓冲区大小,此处设置为length

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA外设递增模式关闭

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //设置DMA存储器递增模式开启

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //设置外设数据大小为半字,即两个字节

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //设置存储器数据大小为半字,即两个字节

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     //设置DMA模式为循环传输模式

    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA传输通道优先级为高,当使用一 DMA通道时,优先级设置不影响

    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        //因为此DMA传输方式为外设到存储器,因此禁用存储器到存储器传输方式

    DMA_Init(DMA1_Channel1, &DMA_InitStructure );       //初始化DMA

    DMA_Cmd(DMA1_Channel1 , ENABLE);  //使能DMA

}


void ADC_CONF(void)

{

    adc_Init();

    DMA_Tx_Init();


    // 配置 ADC 通道转换顺序为1,第一个转换,采样时间为55.5个时钟周期

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);


    // 使能ADC DMA 请求

    ADC_DMACmd(ADC1, ENABLE);


    // 由于没有采用外部触发,所以使用软件触发ADC转换

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

--------------------------
main.c 里面 

头引用声明:
extern u16 ADC_ConvertedValue[2];

main函里里面
上电后 初始化 ADC_CONF();
使用就可以直接使用 ADC_ConvertedValue


感谢楼上的大佬,出来的结果还是和我先前写的代码一样image.png只有前几次数据有略微的波动,后续数据就不会更新了


image.png在这里添加启动函数,因为使用LSI,蓝牙库中会启用ADC测量温度进行校准LSI,导致ADC的启动被暂停。


感谢大佬,这个ADC被暂停的问题解决了,但是DMA数据错位的问题有没有什么好的解决办法 


image.png这边关闭DMA使能,重新写内存地址与传输数量,然后再使能DMA即可。


这里安装图上的写法进行更改后,DMA依然会出现数据错位的问题,  例如  temp = buf【0】  实际打印出来的有 buf 【1】 和 buf【2】的数据


那你直接在这里重新对DMA与ADC初始化。然后先开DMA使能 ,再开ADC软件启动喽,这里蓝牙的库处理有点不完善,因为有的寄存器写后会由硬件清除。


只有登录才能回复,可以选择微信账号登录