程序里配置了两个ADC进行采样,ADC1:采集输出电流、输出电压的值;ADC2:采集NTC电压、设置旋钮等电压。一共5个采样通道,ADC1:Channel_4、Channel_5;ADC2:Channel_2、Channel_8、Channel_9。 ADC1通过
tiM2_CC2事件触发单次采样,用DMA搬运完成后在完成中断里处理数据,ADC2在循环中进行采样取值,在板子上都可以正常运行,但是上到整机使用的时候,会在有输出的时候突然卡死被看门狗重启,卡死的时机不定,但都是在带负载有输出的情况下重启的;输出电流是由TIM1的100kHz PWM控制的。 我在排查过程中,把Channel_5的输出电压采样去掉,再到整机上测试的时候就没有这个现象了。我就把Channel_5采样到的值涉及的程序屏蔽掉,但是Channel_5正常采样,同样运行,还是会重启,再次把Channel_5采样关掉,就没有问题了。我再把ADC1_channel_5换成用ADC2_channel_5,在循环里面采样,还是会出现这个问题。想问一下有大佬遇见过类似的问题吗,这种情况是否是Channel_5被外部干扰了不能正常采样,导致芯片不能正常工作了,有什么解决办法吗?配置如下:void ADC1_DMA_Config(void){ DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* DMA channel1 configuration */ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; //内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; //数据长度为5 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址固定 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig (DMA1_Channel1,DMA_IT_TC,ENABLE ); /* Enable DMA channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); ADC_DeInit(ADC1); //复位ADC1,将外设ADC1的所有寄存器重设为缺省值。 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE ; //扫描模式,扫描模式用于多通道采集 /* ADC1 configuration */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //开启连续转换模式,即不停地进行ADC转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; //不使用外部触发转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目5 ADC_Init(ADC1, &ADC_InitStructure); /*配置ADC时钟,为PCLK2的6分频,即12MHz*/ RCC_ADCCLKConfig(RCC_PCLK2_Div6); /*配置ADC1的通道6为7.5个采样周期,序列为1 */// ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_28Cycles5);//PA5 VOL_OUT ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5);//PA4 CUR_OUT ADC_ExternalTrigConvCmd(ADC1, ENABLE); //设置外部触发使能 /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /*复位校准寄存器 */ ADC_ResetCalibration(ADC1); /*等待校准寄存器复位完成 */ while(ADC_GetResetCalibrationStatus(ADC1)); /* ADC校准 */ ADC_StartCalibration(ADC1); /* 等待校准完成*/ while(ADC_GetCalibrationStatus(ADC1));}void ADC2_Config(void){ ADC_InitTypeDef ADC_InitStructure; //复位ADC1,将外设ADC1的所有寄存器重设为缺省值? RCC_HSICmd(ENABLE);// while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); ADC_DeInit(ADC2); ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //扫描模式,扫描模式用于多通道采集 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //开启连续转换模式,即不停地进行ADC转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目5 ADC_Init(ADC2, &ADC_InitStructure); /* Enable ADC1 */ ADC_Cmd(ADC2, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); /*复位校准寄存器 */ ADC_ResetCalibration(ADC2); /*等待校准寄存器复位完成 */ while(ADC_GetResetCalibrationStatus(ADC2)); /* ADC校准 */ ADC_StartCalibration(ADC2); /* 等待校准完成*/ while(ADC_GetCalibrationStatus(ADC2)) {};}void TIM1_PWM_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // TIM_BDTRInitTypeDef TIM_BDTRInitStructure; /* GPIOB clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* 时基结构体初始化 */ TIM_TimeBaseStructure.TIM_Period =1931; //当定时器从0计数到1931,即为1932次,为一个定时周期 TIM_TimeBaseStructure.TIM_Prescaler = 0; //设置预分 频:不预分频,即为72MHz TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; //设置时钟分频系数:不分频(这里用不到) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; //设置中心对称 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* 输出比较结构体初始化 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse =350; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse =1582; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_ClearITPendingBit(TIM1, TIM_IT_CC3 | TIM_IT_CC2 ); TIM_ITConfig(TIM1, TIM_IT_CC3 | TIM_IT_CC2, DISABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能外设的主输出}void TIM2_PWM_Config(){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* 时基结构体初始化 */ TIM_TimeBaseStructure.TIM_Period =1931; //当定时器从0计数到1931,即为1932次,为一个定时周期 TIM_TimeBaseStructure.TIM_Prescaler = 0; //设置预分 频:不预分频,即为72MHz TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; //设置时钟分频系数:不分频(这里用不到) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; //设置中心对称 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse =1930 - 54; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC2Ref); TIM_ARRPreloadConfig(TIM2, ENABLE);}循环里的采样用的是下面几个函数:uint16_t Read_ADC_data(uint8_t ch){ uint16_t AD_Value; ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_55Cycles5); //PA5 SET_CUR ADC_Cmd(ADC2, ENABLE); ADC_SoftwareStartConvCmd(ADC2, ENABLE); while(!ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC)); AD_Value = ADC_GetConversionValue(ADC2); ADC_ClearFlag(ADC2, ADC_FLAG_EOC); ADC_SoftwareStartConvCmd(ADC2, DISABLE); ADC_Cmd(ADC2, DISABLE); return AD_Value;}uint16_t Read_ADC_data(uint8_t ch){ uint16_t AD_Value; ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_55Cycles5); //PA5 SET_CUR ADC_Cmd(ADC2, ENABLE); ADC_SoftwareStartConvCmd(ADC2, ENABLE); while(!ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC)); AD_Value = ADC_GetConversionValue(ADC2); ADC_ClearFlag(ADC2, ADC_FLAG_EOC); ADC_SoftwareStartConvCmd(ADC2, DISABLE); ADC_Cmd(ADC2, DISABLE); return AD_Value;}