本帖最后由 Paprika 于 2019-3-12 22:50 编辑
一直在调STM32H7的ADC,发现一个奇怪的现象,根据数据手册可以得知每个ADC有都有三个看门狗。但是在配置的过程中发现ADC12的看门狗可以实现中断但是ADC3的一直实现不了。不知道是我配置的问题还是硬件bug,希望得到各位的指导。先贴出ADC1可以正常触发的程序:
void ADC1_Config(void){//配置ADC、ADC通道、看门狗
ADC_ChannelConfTypeDef ADC1_ChanConf;
//ADC1配置
ADC1_Handler.Instance =ADC1;
ADC1_Handler.Init.ClockPrescaler =ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PER_CK/4=64/4=16MHZ
ADC1_Handler.Init.Resolution =ADC_RESOLUTION_12B; //16位模式
ADC1_Handler.Init.ScanConvMode =ADC_SCAN_DISABLE; //非扫描模式
ADC1_Handler.Init.EOCSelection =ADC_EOC_SINGLE_CONV; //关闭EOC中断
ADC1_Handler.Init.LowPowerAutoWait =DISABLE; //自动低功耗关闭
ADC1_Handler.Init.ContinuousConvMode =DISABLE; //关闭连续转换
ADC1_Handler.Init.NbrOfConversion =1; //1个转换在规则序列中 也就是只转换规则序列1
ADC1_Handler.Init.DiscontinuousConvMode =DISABLE; //禁止不连续采样模式
ADC1_Handler.Init.NbrOfDiscConversion =1; //不连续采样通道数为0
ADC1_Handler.Init.ExternalTrigConv =ADC_EXTERNALTRIG_T3_TRGO; //T3触发
ADC1_Handler.Init.ExternalTrigConvEdge =ADC_EXTERNALTRIGCONVEDGE_RISING;//上升沿
ADC1_Handler.Init.ConversionDataManagement =ADC_CONVERSIONDATA_DMA_CIRCULAR; //规则通道的数据仅仅保存在DR寄存器里面
ADC1_Handler.Init.BoostMode =ENABLE; //BOOT模式关闭
ADC1_Handler.Init.Overrun =ADC_OVR_DATA_OVERWRITTEN; //有新的数据的死后直接覆盖掉旧数据
ADC1_Handler.Init.OversamplingMode =DISABLE; //过采样关闭
HAL_ADC_Init(&ADC1_Handler); //初始化
//配置通道
ADC1_ChanConf.Channel = ADC_CHANNEL_19; //通道
ADC1_ChanConf.Rank = ADC_REGULAR_RANK_1; //1个序列
ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_8CYCLES_5; //采样时间
ADC1_ChanConf.SingleDiff = ADC_SINGLE_ENDED; //单边采集
ADC1_ChanConf.OffsetNumber = ADC_OFFSET_NONE;
ADC1_ChanConf.Offset = 0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ADC的通道19
//看门狗配置
AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_2;
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
AnalogWDGConfig.Channel = ADC_CHANNEL_19;
AnalogWDGConfig.ITMode = ENABLE;
AnalogWDGConfig.HighThreshold = 2000;
AnalogWDGConfig.LowThreshold = 0;
HAL_ADC_AnalogWDGConfig(&ADC1_Handler, &AnalogWDGConfig);
}
ADC是用定时器触发的,在HAL_ADC_MspInit();函数中配置使用DMA传输,以及对应的时钟使能。
下面是ADC3是不能进入中断的,问题代码:
void ADC3_Config(void){//配置ADC3、ADC3通道
ADC_ChannelConfTypeDef ADC3_ChanConf;
//ADC3配置
ADC3_Handler.Instance = ADC3;
ADC3_Handler.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
ADC3_Handler.Init.Resolution = ADC_RESOLUTION_12B;
ADC3_Handler.Init.ScanConvMode = ADC_SCAN_DISABLE; //非扫描模式
ADC3_Handler.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭EOC中断
ADC3_Handler.Init.LowPowerAutoWait = DISABLE; //自动低功耗关闭
ADC3_Handler.Init.ContinuousConvMode = DISABLE; //关闭连续转换
ADC3_Handler.Init.NbrOfConversion = 1; //1个转换在规则序列中 也就是只转换规则序列1
ADC3_Handler.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式
ADC3_Handler.Init.NbrOfDiscConversion = 1; //不连续采样通道数为0
ADC3_Handler.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO; //T3触发
ADC3_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;//上升沿
ADC3_Handler.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; //规则通道的数据仅仅保存在DR寄存器里面
ADC3_Handler.Init.BoostMode = ENABLE; //BOOT模式关闭
ADC3_Handler.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; //有新的数据的死后直接覆盖掉旧数据
ADC3_Handler.Init.OversamplingMode = DISABLE; //过采样关闭
HAL_ADC_Init(&ADC3_Handler); //初始化
//配置通道PH4 ADC3_INP15
ADC3_ChanConf.Channel = ADC_CHANNEL_3; //通道
ADC3_ChanConf.Rank = ADC_REGULAR_RANK_1; //1个序列
ADC3_ChanConf.SamplingTime = ADC_SAMPLETIME_8CYCLES_5; //采样时间
ADC3_ChanConf.SingleDiff = ADC_SINGLE_ENDED; //单边采集
ADC3_ChanConf.OffsetNumber = ADC_OFFSET_NONE;
ADC3_ChanConf.Offset = 0;
HAL_ADC_ConfigChannel(&ADC3_Handler,&ADC3_ChanConf); //ADC的通道 15
//看门狗配置
AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
AnalogWDGConfig.Channel = ADC_CHANNEL_3;
AnalogWDGConfig.ITMode = ENABLE;
AnalogWDGConfig.HighThreshold = 2000;
AnalogWDGConfig.LowThreshold = 0;
HAL_ADC_AnalogWDGConfig(&ADC1_Handler, &AnalogWDGConfig);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc){
//*##- 1- Configure CLK###########/
__HAL_RCC_GPIOF_CLK_ENABLE(); //开启GPIOH时钟
__HAL_RCC_ADC3_CLK_ENABLE(); //使能ADC3时钟
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择
__HAL_RCC_DMA2_CLK_ENABLE();
/*##- 2- Configure peripheral GPIO ############*/
/* ADC3 Channel GPIO pin configuration */
GPIO_Initure.Pin=GPIO_PIN_7; //PH4
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOF,&GPIO_Initure);
/*##- 3- Configure DMA ####################*/
/*********************** Configure DMA parameters link ADC3 with DMA1_Stream2 ***/
DmaHandle2.Instance = DMA2_Stream1;
DmaHandle2.Init.Request = DMA_REQUEST_ADC3;
DmaHandle2.Init.Direction = DMA_PERIPH_TO_MEMORY;
DmaHandle2.Init.PeriphInc = DMA_PINC_DISABLE;
DmaHandle2.Init.MemInc = DMA_MINC_ENABLE;
DmaHandle2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
DmaHandle2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DmaHandle2.Init.Mode = DMA_CIRCULAR;
DmaHandle2.Init.Priority = DMA_PRIORITY_MEDIUM;
/* Deinitialize & Initialize the DMA for new transfer */
HAL_DMA_DeInit(&DmaHandle2);
HAL_DMA_Init(&DmaHandle2);
/* Associate the DMA handle 把结构体中的两个连到一起*/
__HAL_LINKDMA(hadc, DMA_Handle, DmaHandle2);
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
}
将道理应该这个俩个ADC配置没什么区别,但是实际实验就是不好用。不知道是我哪里疏忽了。再就是有一个非常诡异的问题,假如先配置ADC3之后再配置ADC1的话ADC3还会不工作很诡异。。。。
希望能得到各位的指导十分感谢
adc.c
2019-3-12 22:49 上传
点击文件名下载附件 |