打印
[活动专区]

【AutoChips MCU评测报告】+ADC+DMA多通道采样

[复制链接]
6505|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
caizhiwei|  楼主 | 2020-6-7 17:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      Ac7811这里用dma确实比较节省cpu资源,特别是多通道多路AD采样。
驱动代码如下:
#include "ac78xx_adc.h"
#include "ac78xx_gpio.h"
#include "ac78xx.h"
#include "ac78xx_dma.h"

_Bool g_dmaFinish = 0;

/**
* ADCDMACallback
*
* @param[in]  DMAx:DMA Channel Pointer
* @param[in]  wparam:DMA Channel status
* @param[in]  lparam:DMA Channel status
* [url=home.php?mod=space&uid=266161]@return[/url] no
*
* [url=home.php?mod=space&uid=247401]@brief[/url]  ADC DMA channel Complete Interrupt
*/
int32_t ADCDMACallback(DMA_Type *DMAx, uint32_t wparam, uint32_t lparam)
{
    g_dmaFinish = 1;
    return 0;
}

/**
* DMA_Config
*
* @param[in]  no
* @return no
*
* ADC0_Value = *(uint32_t *)0x20006000;
* ADC1_Value = *(uint32_t *)0x20006004;
* ADC2_Value = *(uint32_t *)0x20006008;
* ADC3_Value = *(uint32_t *)0x2000600C;
* ADC4_Value = *(uint32_t *)0x20006010;
* ADC5_Value = *(uint32_t *)0x20006014;
*
* @brief  Setting DMA always work
*/
void DMA_Config(void)
{
    uint32_t tmpMemStartAddr = 0x20006000;
    uint32_t tmpMemEndAddr = 0x2000ff00;                    ///<Setting memory DMA address
    DMA_ConfigType tmpDMAConfig = {0};

    *(uint32_t *)(tmpMemStartAddr) = 0x44332211;
    *(uint32_t *)(tmpMemStartAddr + 0x4) = 0xDDCCBBAA;
    *(uint32_t *)(tmpMemStartAddr + 0x8) = 0x88776655;      ///<Just test address write

    tmpDMAConfig.memStartAddr = tmpMemStartAddr;
    tmpDMAConfig.memEndAddr = tmpMemEndAddr;
    tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC->RDR)); ///<Move ADC DR to memory
    tmpDMAConfig.setting.channelEn = 1;                     ///<Enable DMAx channel
    tmpDMAConfig.setting.finishIntEn = 1;                   ///<Enable DMA transfer complete interrupt
    tmpDMAConfig.setting.halfFinishIntEn = 0;               ///<Disable DMA transfer half complete interrupt
    tmpDMAConfig.setting.errorIntEn = 1;
    tmpDMAConfig.setting.channelPriority = 3;               ///<3: Very high priority
    tmpDMAConfig.setting.circular = 1;                      ///<Circular mode enable,If want work one time disable
    tmpDMAConfig.setting.direction = 0;                     ///<1: Read from peripheral
    tmpDMAConfig.setting.MEM2MEM = 0;                       ///<Peripheral to memory
    tmpDMAConfig.setting.memByteMode = 0;                   ///<1:16-bit[15:0]; 2:[23:16],[7:0]
    tmpDMAConfig.setting.memIncrement = 1;                  ///<Memory address increment
    tmpDMAConfig.setting.periphIncrement = 0;               ///<Peripheral address fixed
    tmpDMAConfig.setting.memSize = 2;                       ///<2:32-bit
    tmpDMAConfig.setting.periphSize = 1;                    ///<Fixed 1:16-bit
    tmpDMAConfig.setting.transferNum = 6;               ///<As request

    DMA_Initialize(DMA1, &tmpDMAConfig);                    ///<Use DMA1 channel
    DMA_SetEventCallback(DMA1, ADCDMACallback);
    NVIC_EnableIRQ(DMA1_IRQn);
    ADC_DMACmd(ADC, ADC_ENABLE);
}

/**
* ADC_Config
*
* @param[in]  no
* @return no
*
* @brief  Setting ADC
*/
void ADC_Config(void)
{
    ADC_InitType tempAdcConfig = {0, 0, 0, 0, 0, 0, 1};
    ADC_TrigSourceType tempAdcTrigSource = {0, 0};
    ADC_InitType* adcConfig;
    ADC_TrigSourceType* adcTrigSource;
    adcConfig = &tempAdcConfig;
    adcTrigSource = &tempAdcTrigSource;
    adcConfig->scanMode = 1;                       ///<ADC mode 5
    adcConfig->continousMode = 1;
    adcConfig->disContinousModeOnRegularGroup = 0;
    adcConfig->disContinousModeOnInjectGroup = 0;
    adcConfig->injectAutoMode = 0;

    GPIO_SetFunc(7, 1);                            ///<ADC_IN0 Analog function enable
    GPIO_SetFunc(8, 1);                            ///<ADC_IN1 Analog function enable
    GPIO_SetFunc(9, 1);                            ///<ADC_IN2 Analog function enable
    GPIO_SetFunc(10, 1);                           ///<ADC_IN3 Analog function enable
    GPIO_SetFunc(11, 1);                           ///<ADC_IN4 Analog function enable
    GPIO_SetFunc(12, 1);                           ///<ADC_IN5 Analog function enable

    ADC_Init(ADC, adcConfig);                      ///<ADC works Mode Config
    ADC_SetClockPrescaler(ADC, 4);                 ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_TrigSourceInit(ADC, adcTrigSource);
    ADC_SetRegularGroupLength(ADC, 6);             //setting 6 ADC channel sample

    ADC_SetRegularGroupSequence(ADC, 1, ADC_CHANNEL_AD0); //set ADC_CHANNEL0 for AD Sample
    ADC_SetRegularGroupSequence(ADC, 2, ADC_CHANNEL_AD1); //set ADC_CHANNEL1 for AD Sample
    ADC_SetRegularGroupSequence(ADC, 3, ADC_CHANNEL_AD2); //set ADC_CHANNEL2 for AD Sample
    ADC_SetRegularGroupSequence(ADC, 4, ADC_CHANNEL_AD3); //set ADC_CHANNEL3 for AD Sample
    ADC_SetRegularGroupSequence(ADC, 5, ADC_CHANNEL_AD4); //set ADC_CHANNEL4 for AD Sample
    ADC_SetRegularGroupSequence(ADC, 6, ADC_CHANNEL_AD5); //set ADC_CHANNEL5 for AD Sample
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD0, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD1, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD2, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD3, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD4, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD5, ADC_SampleTime_14Cycle); ///<Set ADC Sample Rate 369K = 96M/2/(4+1)/(14+12)
    ADC_Cmd(ADC, ENABLE);
}


如何调用呢?
只要在主循环之前初始化即可。
ADC_Config();
    DMA_Config();
    ADC_SoftwareStartRegularConvCmd(ADC, ADC_ENABLE);
到这里就OK了,历程还是非常给力的!

使用特权

评论回复

相关帖子

沙发
WJY19950827| | 2021-8-19 14:21 | 只看该作者
本帖最后由 WJY19950827 于 2021-8-19 14:23 编辑

;;

使用特权

评论回复
板凳
duo点| | 2021-10-3 10:17 | 只看该作者
给力

使用特权

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

本版积分规则

100

主题

857

帖子

14

粉丝