OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3824|回复: 2

[STM32H7] 双重模式ADC2没有值

[复制链接]

10

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2021-4-8
在线时间
26 小时
发表于 2021-12-26 15:54:08 | 显示全部楼层 |阅读模式
2金钱
使用ADC双重模式的时候,能进入中断,ADC1有数据,但是ADC2没有数据,代码如下:

ADC:

ADC_HandleTypeDef ADC1_Handler;                                                    //ADC1句柄
ADC_HandleTypeDef ADC2_Handler;                                                    //ADC2句柄
               
//初始化ADC
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_SYNC_PCLK_DIV2;                     //2分频,ADCCLK=PER_CK/2=64/2=32MHZ
    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=3;                                           //3个转换在规则序列中
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;                               //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                                       //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIG_T3_CC4;                    //定时器触发 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;      
      
          HAL_ADC_DeInit(&ADC2_Handler);
      
          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句柄
      
    __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.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.Mode=GPIO_MODE_ANALOG;                                                                      //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;                                                                           //不带上下拉

    HAL_GPIO_Init(GPIOC,&GPIO_Initure);      
}

void ADC_Init(void)
{      
                ADC1_Init();
                ADC2_Init();
}


DMA:

DMA_HandleTypeDef  DMA1_Stream0_Handler;                                      //DMA句柄

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_LINKDMA(&ADC1_Handler,DMA_Handle,DMA1_Stream0_Handler);             //将DMA与ADC1联系起来(发送DMA)
      
                //开启中断 设置优先级
                HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);                       
}

void DMA_Init(void)
{
    DMA1_Stream0_Init();      
}


main:

//定义变量
u32 ADC_DMA_Buf[3];                 //双ADC接受DMA传输的缓冲区

double Acceleration[2];             //加速度数组
u16 Acceleration_Buf[2];            //加速度缓冲区
u8 Acceleration_String[64];  

double Speed[2];                    //速度数组
u16 Speed_Buf[2];                   //速度缓冲区
u8 Speed_String[64];

double Displacement[2];             //位移数组
u16 Displacement_Buf[2];            //位移缓冲区
u8 Displacement_String[64];

void DMA1_Stream0_IRQHandler(void)
{
                SCB_InvalidateDCache();  //使 D-cache 无效,即CPU读取数据时,忽略 D-cache 中的内容,去真实的物理地址读取对应的数据(DMA-SRAM)。
      
          if( __HAL_DMA_GET_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4)!=RESET)
          {                       
                        Acceleration_Buf[0] = 0x0000FFFF & ADC_DMA_Buf[0];
                        Acceleration_Buf[1] = ADC_DMA_Buf[0] >> 16;               
                        Acceleration[0] = (double)Acceleration_Buf[0] * 3.3 / 65536;
                        Acceleration[1] = (double)Acceleration_Buf[1] * 3.3 / 65536;
                       
                        Speed_Buf[0] = 0x0000FFFF & ADC_DMA_Buf[1];
                        Speed_Buf[1] = ADC_DMA_Buf[1] >> 16;               
                        Speed[0] = (double)Speed_Buf[0] * 3.3 / 65536;
                        Speed[1] = (double)Speed_Buf[1] * 3.3 / 65536;

                        Displacement_Buf[0] = 0x0000FFFF & ADC_DMA_Buf[2];
                        Displacement_Buf[1] = ADC_DMA_Buf[2] >> 16;               
                        Displacement[0] = (double)Displacement_Buf[0] * 3.3 / 65536;
                        Displacement[1] = (double)Displacement_Buf[1] * 3.3 / 65536;                       
               
                        sprintf((char*)Acceleration_String,"Acceleration:%10.3lf %10.3lf ",Acceleration[0],Acceleration[1]);
                        sprintf((char*)Speed_String,"Speed:%10.3lf %10.3lf ",Speed[0],Speed[1]);
                        sprintf((char*)Displacement_String,"Displacement:%10.3lf %10.3lf ",Displacement[0],Displacement[1]);
                       
                        __HAL_DMA_CLEAR_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4);
                }                                               
}

int main(void)
{      
        Cache_Enable();                                          //打开Cache
        HAL_Init();                                                                //初始化HAL库
        Stm32_Clock_Init(160,5,2,4);                      //设置时钟 400MHZ
        SDRAM_Init();                                     //初始化SDRAM
        delay_init(400);                                                          //延时初始化
        uart_init(115200);                                                        //串口初始化
        LED_Init();
        KEY_Init();                                                                            //初始化按键
      
        //显示屏初始化
        LCD_Init();         
        LCD_Clear(BLACK);
        POINT_COLOR=RED;
      
        //ADC、DMA、TIMER初始化
        DMA_Init();
        ADC_Init();      
        TIM3_PWM_Init(19999,9999);
  HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,3);               
      
  while(1)
  {                       
                        LCD_ShowString(10,40,1024,32,32,Acceleration_String);
                        LCD_ShowString(10,80,1024,32,32,Speed_String);
                        LCD_ShowString(10,120,1024,32,32,Displacement_String);
        }

}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2021-4-8
在线时间
26 小时
 楼主| 发表于 2021-12-26 15:54:33 | 显示全部楼层
HAL_ADC_DeInit(&ADC2_Handler);
这一句注释掉以后,直接运行无法进入中断,但是在调式窗口进入这个函数 HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,3); 在调试窗口一步一步运行完,就可以进入中断,数据也都有,就很迷。
回复

使用道具 举报

13

主题

644

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1976
金钱
1976
注册时间
2021-4-16
在线时间
505 小时
发表于 2021-12-27 10:47:51 | 显示全部楼层
帮顶。。。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 10:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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