702U7 发表于 2021-12-26 14:58:13

双重模式ADC2没有值

使用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_HandleTypeDefDMA1_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;               //双ADC接受DMA传输的缓冲区

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

double Speed;                  //速度数组
u16 Speed_Buf;                   //速度缓冲区
u8 Speed_String;

double Displacement;             //位移数组
u16 Displacement_Buf;            //位移缓冲区
u8 Displacement_String;

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 = 0x0000FFFF & ADC_DMA_Buf;
                        Acceleration_Buf = ADC_DMA_Buf >> 16;               
                        Acceleration = (double)Acceleration_Buf * 3.3 / 65536;
                        Acceleration = (double)Acceleration_Buf * 3.3 / 65536;
                       
                        Speed_Buf = 0x0000FFFF & ADC_DMA_Buf;
                        Speed_Buf = ADC_DMA_Buf >> 16;               
                        Speed = (double)Speed_Buf * 3.3 / 65536;
                        Speed = (double)Speed_Buf * 3.3 / 65536;

                        Displacement_Buf = 0x0000FFFF & ADC_DMA_Buf;
                        Displacement_Buf = ADC_DMA_Buf >> 16;               
                        Displacement = (double)Displacement_Buf * 3.3 / 65536;
                        Displacement = (double)Displacement_Buf * 3.3 / 65536;                       
               
                        sprintf((char*)Acceleration_String,"Acceleration:%10.3lf %10.3lf ",Acceleration,Acceleration);
                        sprintf((char*)Speed_String,"Speed:%10.3lf %10.3lf ",Speed,Speed);
                        sprintf((char*)Displacement_String,"Displacement:%10.3lf %10.3lf ",Displacement,Displacement);
                       
                        __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);
        }

}



eric2013 发表于 2021-12-26 15:00:12

帮顶,没用过H7的双重模式,有机会试试。

702U7 发表于 2021-12-26 15:26:15

HAL_ADC_DeInit(&ADC2_Handler);
这一句注释掉以后,直接运行无法进入中断,但是在调式窗口进入这个函数 HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,3); 在调试窗口一步一步运行完,就可以进入中断,数据也都有,就很迷。

dufanbao 发表于 2021-12-26 15:28:14

cache问题,以前遇到过参考硬汉的ram管理方法

702U7 发表于 2021-12-26 15:34:32

dufanbao 发表于 2021-12-26 15:28
cache问题,以前遇到过参考硬汉的ram管理方法

可是adc1有数据的,如果cache问题应该都没数据才对吧?

702U7 发表于 2021-12-26 15:36:30

dufanbao 发表于 2021-12-26 15:28
cache问题,以前遇到过参考硬汉的ram管理方法

处理数据之前已经 SCB_InvalidateDCache(); 失效cache了

dufanbao 发表于 2021-12-26 15:44:26

702U7 发表于 2021-12-26 15:36
处理数据之前已经 SCB_InvalidateDCache(); 失效cache了

你关掉cache看看

702U7 发表于 2021-12-26 16:05:18

dufanbao 发表于 2021-12-26 15:44
你关掉cache看看

还是不行 失效就等于关了

风过不留痕 发表于 2023-8-9 10:05:26

解决了吗?我的是只进一次中断就hard fault

kmxm 发表于 2023-8-9 14:13:47

风过不留痕 发表于 2023-8-9 10:05
解决了吗?我的是只进一次中断就hard fault

老哥我这边有用Cube配置的H743双ADC模式的代码,你可以参考一下,我贴在之后的回答上

kmxm 发表于 2023-8-9 14:19:12

风过不留痕 发表于 2023-8-9 10:05
解决了吗?我的是只进一次中断就hard fault

论坛上传的有点慢,直接贴百度网盘的链接:https://pan.baidu.com/s/1qnvL8_B2F3h1nioxpxQb7g
提取码:erub
--来自百度网盘超级会员V3的分享

风过不留痕 发表于 2023-8-9 14:33:32

中断调用SCB_InvalidateDCache()会死机啊?

bigcatdairy 发表于 2023-9-19 01:44:16

kmxm 发表于 2023-8-9 14:19
论坛上传的有点慢,直接贴百度网盘的链接:https://pan.baidu.com/s/1qnvL8_B2F3h1nioxpxQb7g
提取码: ...

能不能再分享下? 鏈接過期了

sd-abc 发表于 2024-3-2 14:24:43

问题是如何解决的?
不用cache是否可以?
页: [1]
查看完整版本: 双重模式ADC2没有值