硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1168|回复: 4
收起左侧

[DMA] 关于H743 DMA缓冲区大小设置的问题

[复制链接]
回帖奖励 6 个金币 回复本帖可获得 3 个金币奖励! 每人限 1 次

2

主题

5

回帖

11

积分

新手上路

积分
11
发表于 2022-1-13 21:14:23 | 显示全部楼层 |阅读模式
在Ucos+emwin+fatfs的基础模板上,参考二代示波器的方案,准备做一个采集系统,将多个通道采集到的数据利用graph控件显示出来,却在开启adcdma的语句上出现了问题。
        无论是使用多重模式还是普通开启adcdma(HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,1);)
        数据大小dmabuffersize只能设置为1,否则会卡死,想问下h743没有类似f4那种在结构体中调节buffsize这种方法
下载.png
上图最后一句为二代示波器中调节大小的语句。
求指点!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-1-14 09:48:33 | 显示全部楼层

回帖奖励 +3 个金币

楼主要实现什么功能,就是单纯的单个ADC的多通道采集展示,还是ADC1,ADC2,ADC3这种都开启的多通道。

方便的话,贴下你的配置代码。
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2022-1-17 14:35:29 | 显示全部楼层
eric2013 发表于 2022-1-14 09:48
楼主要实现什么功能,就是单纯的单个ADC的多通道采集展示,还是ADC1,ADC2,ADC3这种都开启的多通道。

方 ...

是采取双重模式进行采集 用到的是ADC1和ADC2 各两个通道 共四个 将采集到的数据在graph控件上显示出来,然后无论采取双重模式 还是普通的 就是俩adc 被同一个时钟的俩通道同时触发 程序都没法运行 ,只有改成1的时候可以运行
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2022-1-17 14:38:06 | 显示全部楼层
这是我adc dma配置的代码,如果不适用emwin 单独跑是可行的 也可以随意调节dmabuffersize的大小
void ADC1_Init(void)
{
    ADC_ChannelConfTypeDef ADC1_Channel_Handler;                                   //ADC2通道配置句柄
    ADC_MultiModeTypeDef MultiMode_Handler;                                        //双重模式句柄
       
          //ADC1初始化
    ADC1_Handler.Instance=ADC1;
       
          HAL_ADC_DeInit(&ADC1_Handler);
       
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_ASYNC_DIV2;                         //2分频,ADCCLK=PER_CK/2=64/2=32MHZ 异步时钟 可校准
//    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV2;                     //同步时钟 不能打开ADC2的校准
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_16B;                               //16位模式
    ADC1_Handler.Init.ScanConvMode=ENABLE;                                         //扫描模式
    ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV;                            //EOC全部转换完成进入中断
          ADC1_Handler.Init.LowPowerAutoWait=DISABLE;                                                                   //自动低功耗关闭                               
    ADC1_Handler.Init.ContinuousConvMode=DISABLE;                                  //关闭连续转换
    ADC1_Handler.Init.NbrOfConversion=2;                                           //3个转换在规则序列中
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;                               //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                                       //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIG_T3_TRGO;                    //定时器触发 TIME3-CH4
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING;        //外部上升沿触发
          ADC1_Handler.Init.BoostMode=ENABLE;                                                                                       //BOOT模式使能 时钟高于20MHz时 必须使能此位
          ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;                                               //有新的数据的后直接覆盖掉旧数据
          ADC1_Handler.Init.OversamplingMode=DISABLE;                                                                   //过采样关闭
          ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR;    //DMA循环接受数据
               
    HAL_ADC_Init(&ADC1_Handler);                                                   //初始化

    //ADC1-Channel-16
    ADC1_Channel_Handler.Channel=16;                                               //通道 PA0
    ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_1;                                  //序列1
    ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
          ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
          ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
          ADC1_Channel_Handler.Offset=0;   
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler);                    //通道配置

    //ADC1-Channel-19
                ADC1_Channel_Handler.Channel=19;                                               //通道 PA5
    ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_2;                                  //序列2
    ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
          ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
          ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
          ADC1_Channel_Handler.Offset=0;   
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler);                    //通道配置

//    //ADC1-Channel-3
//                ADC1_Channel_Handler.Channel=3;                                                //通道 PA6
//    ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_3;                                  //序列3
//    ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
//          ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
//          ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
//          ADC1_Channel_Handler.Offset=0;   
//    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler);                    //通道配置
               
                HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);  //ADC校准

          //设置ADC双重模式
                MultiMode_Handler.Mode = ADC_DUALMODE_REGSIMULT;
                MultiMode_Handler.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
                MultiMode_Handler.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
               
                HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handler,&MultiMode_Handler);
}

void ADC2_Init(void)
{       
    ADC_ChannelConfTypeDef ADC2_Channel_Handler;                                   //ADC2通道配置句柄
       
          //ADC2初始化   
    ADC2_Handler.Instance=ADC2;       
       
          ADC2_Handler.Init = ADC1_Handler.Init;
    ADC2_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;                         //双重模式的副ADC软件触发
               
    HAL_ADC_Init(&ADC2_Handler);                                                   //初始化

    //ADC2-Channel-7
                ADC2_Channel_Handler.Channel=7;                                                //通道 PA7
    ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_1;                                  //序列1
    ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
          ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
          ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
          ADC2_Channel_Handler.Offset=0;   
    HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler);                    //通道配置

    //ADC2-Channel-4
                ADC2_Channel_Handler.Channel=4;                                                //通道 PC4
    ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_2;                                  //序列2
    ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
          ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
          ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
          ADC2_Channel_Handler.Offset=0;   
    HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler);                    //通道配置

    //ADC2-Channel-8
//                ADC2_Channel_Handler.Channel=8;                                                //通道 PC5
//    ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_3;                                  //序列3
//    ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;                           //采样周期      
//          ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED;                                                       //单边采集                         
//          ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;                    
//          ADC2_Channel_Handler.Offset=0;   
//    HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler);                    //通道配置
               
                HAL_ADCEx_Calibration_Start(&ADC2_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);  //ADC校准
}

//ADC底层驱动 引脚配置、时钟使能
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;                                                                           //GPIO句柄
         RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
               
                PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
                PeriphClkInitStruct.PLL2.PLL2M = 25;
                PeriphClkInitStruct.PLL2.PLL2N = 504;
                PeriphClkInitStruct.PLL2.PLL2P = 7;
                PeriphClkInitStruct.PLL2.PLL2Q = 7;
                PeriphClkInitStruct.PLL2.PLL2R = 7;
                PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
                PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
                PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
                PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
                HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
               
          __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_PLL2);
                __HAL_RCC_ADC12_CLK_ENABLE();                                                                            //使能ADC1/2时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                                                                                               //开启GPIOA时钟
          __HAL_RCC_GPIOC_CLK_ENABLE();                                                                                               //开启GPIOC时钟
          //__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);                                                             //ADC外设时钟选择

//    GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;                       //PA
          GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_7;                                   //PA
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;                                                                      //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;                                                                           //不带上下拉
       
          HAL_GPIO_Init(GPIOA,&GPIO_Initure);
       
//          GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;                                                                 //PC
                GPIO_Initure.Pin=GPIO_PIN_4;                                                                                    //PC
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;                                                                      //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;                                                                           //不带上下拉

    HAL_GPIO_Init(GPIOC,&GPIO_Initure);       
}

void ADC_Init(void)
{       
                ADC1_Init();
                ADC2_Init();
//                HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,2);

}
void DMA1_Stream0_Init(void)
{       
    __HAL_RCC_DMA1_CLK_ENABLE();                                              //DMA1时钟使能  
       
    //DMA1-Stream0
    DMA1_Stream0_Handler.Instance=DMA1_Stream0;                               //数据流选择
          DMA1_Stream0_Handler.Init.Request=DMA_REQUEST_ADC1;                                                //ADC
    DMA1_Stream0_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;                 //外设到储存器
    DMA1_Stream0_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                     //外设非增量模式
    DMA1_Stream0_Handler.Init.MemInc=DMA_MINC_ENABLE;                         //存储器增量模式
    DMA1_Stream0_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;        //外设数据长度:16位
    DMA1_Stream0_Handler.Init.MemDataAlignment=DMA_PDATAALIGN_WORD;           //存储器数据长度:16位
    DMA1_Stream0_Handler.Init.Mode=DMA_CIRCULAR;                              //循环接受模式
    DMA1_Stream0_Handler.Init.Priority=DMA_PRIORITY_HIGH;                     //高等优先级
    DMA1_Stream0_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    DMA1_Stream0_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    DMA1_Stream0_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                     //存储器突发单次传输
    DMA1_Stream0_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;                  //外设突发单次传输

                //初始化
          HAL_DMA_DeInit(&DMA1_Stream0_Handler);
    HAL_DMA_Init(&DMA1_Stream0_Handler);
//                HAL_DMA_Start (&DMA1_Stream0_Handler,RHEOSTAT_ADC1_DR_ADDR,(uint32_t)&ADC_DMA_Buf,2);                   //开启单缓冲
       
                __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,DMA1_Stream0_Handler);             //将DMA与ADC1联系起来(发送DMA)
//                __HAL_DMA_ENABLE_IT(&DMA1_Stream0_Handler,DMA_IT_TC);        //传输完成中断
                //开启中断 设置优先级
                HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 1, 1);
    HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);                       
}

void DMA_Init(void)
{
    DMA1_Stream0_Init();       
}


void DMA1_Stream0_IRQHandler(void)
{   
                static int count=0;
    int i;       
                SCB_InvalidateDCache();  //使 D-cache 无效,即CPU读取数据时,忽略 D-cache 中的内容,去真实的物理地址读取对应的数据(DMA-SRAM)。

          if( __HAL_DMA_GET_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4)!=RESET)
          {                       
//                        HAL_TIM_PWM_Stop(&TIM3_Handler,TIM_CHANNEL_4);

                        Acceleration_Buf[1] = ADC_DMA_Buf[0];
                        Acceleration_Buf[0] = ADC_DMA_Buf[0] >> 16;               
                        Acceleration[0] = (float)Acceleration_Buf[0] * 3300 / 65536;
                        Acceleration[1] = (float)Acceleration_Buf[1] * 3300 / 65536;
                        oscilldev.buffer[count]=(int)Acceleration[1];
                        count++;
                 if(count==oscilldev.dataxsize)//一次数据采集完成
                        {
                                count=0;
                                oscilldev.adflag=1;//标记AD采集完成标志
                        }
               
                        __HAL_DMA_CLEAR_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4);
                }       
       
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-1-18 10:31:52 | 显示全部楼层
局部变量局部一定要清零。

ADC_ChannelConfTypeDef ADC1_Channel_Handler;                                   //ADC2通道配置句柄
    ADC_MultiModeTypeDef MultiMode_Handler;                                        //双重模式句柄

    ADC_ChannelConfTypeDef ADC2_Channel_Handler;     
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 18:17 , Processed in 0.173183 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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