硬汉嵌入式论坛

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

[ADC] 双重模式ADC2没有值

[复制链接]

32

主题

64

回帖

160

积分

初级会员

积分
160
发表于 2021-12-26 14:58:13 | 显示全部楼层 |阅读模式
使用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);
        }

}



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2021-12-26 15:00:12 | 显示全部楼层
帮顶,没用过H7的双重模式,有机会试试。
回复

使用道具 举报

32

主题

64

回帖

160

积分

初级会员

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

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2021-12-26 15:28:14 | 显示全部楼层
cache问题,以前遇到过  参考硬汉的ram管理方法
回复

使用道具 举报

32

主题

64

回帖

160

积分

初级会员

积分
160
 楼主| 发表于 2021-12-26 15:34:32 | 显示全部楼层
dufanbao 发表于 2021-12-26 15:28
cache问题,以前遇到过  参考硬汉的ram管理方法

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

使用道具 举报

32

主题

64

回帖

160

积分

初级会员

积分
160
 楼主| 发表于 2021-12-26 15:36:30 | 显示全部楼层
dufanbao 发表于 2021-12-26 15:28
cache问题,以前遇到过  参考硬汉的ram管理方法

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

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2021-12-26 15:44:26 | 显示全部楼层
702U7 发表于 2021-12-26 15:36
处理数据之前已经 SCB_InvalidateDCache(); 失效cache了

你关掉cache看看
回复

使用道具 举报

32

主题

64

回帖

160

积分

初级会员

积分
160
 楼主| 发表于 2021-12-26 16:05:18 | 显示全部楼层

还是不行 失效就等于关了
回复

使用道具 举报

2

主题

37

回帖

43

积分

新手上路

积分
43
发表于 2023-8-9 10:05:26 | 显示全部楼层
解决了吗?我的是只进一次中断就hard fault
回复

使用道具 举报

10

主题

40

回帖

70

积分

初级会员

积分
70
发表于 2023-8-9 14:13:47 | 显示全部楼层
风过不留痕 发表于 2023-8-9 10:05
解决了吗?我的是只进一次中断就hard fault

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

使用道具 举报

10

主题

40

回帖

70

积分

初级会员

积分
70
发表于 2023-8-9 14:19:12 | 显示全部楼层
风过不留痕 发表于 2023-8-9 10:05
解决了吗?我的是只进一次中断就hard fault

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

使用道具 举报

2

主题

37

回帖

43

积分

新手上路

积分
43
发表于 2023-8-9 14:33:32 | 显示全部楼层
中断调用SCB_InvalidateDCache()会死机啊?
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2023-9-19 01:44:16 | 显示全部楼层
kmxm 发表于 2023-8-9 14:19
论坛上传的有点慢,直接贴百度网盘的链接:https://pan.baidu.com/s/1qnvL8_B2F3h1nioxpxQb7g
提取码: ...

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

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-3-2 14:24:43 | 显示全部楼层
问题是如何解决的?
不用cache是否可以?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 09:51 , Processed in 0.203900 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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