找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11822|回复: 4
收起左侧

STM32F302的ADC采集,卡死在while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC)

[复制链接]
ID:96313 发表于 2018-9-4 14:22 | 显示全部楼层 |阅读模式
就是配置这个自动注入这里,没有用DMA,又要自己切换通道,一定要记得配置为使能,虽然配置失能也可以运行n次,但是总会卡死,找半天找不出来,我先后屏蔽过其他定时器,感觉又能多运行几次,但是有时候也会卡死,所以我感觉是配置的问题,把这里使能就好了。
stm32f302RBT6

原因是配置的问题:
具体如下:
  1. void ADC2_init(void)
  2. {
  3.         GPIO_InitTypeDef          GPIO_InitStructure;
  4.         ADC_InitTypeDef           ADC_InitStructure;
  5.         ADC_CommonInitTypeDef     ADC_CommonInitStructure;
  6.         
  7.         RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);

  8.   /* Enable ADC12 clock */
  9.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

  10.   /* ADC Channel configuration */
  11.   /* GPIOC Periph clock enable */
  12.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOA, ENABLE);

  13.   /* Configure ADC Channel5 as analog input */
  14.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
  15.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  16.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  17.   GPIO_Init(GPIOC, &GPIO_InitStructure);
  18.         
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  20.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  21.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  22.   GPIO_Init(GPIOA, &GPIO_InitStructure);

  23.   ADC_StructInit(&ADC_InitStructure);

  24.   /* Calibration procedure */  
  25.   ADC_VoltageRegulatorCmd(ADC2, ENABLE);

  26.   ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Single);
  27.   ADC_StartCalibration(ADC2);

  28.   while(ADC_GetCalibrationStatus(ADC2) != RESET );
  29.   calibration_value = ADC_GetCalibrationValue(ADC2);

  30.   ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
  31.   ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
  32.   ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;            
  33.   ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;                  
  34.   ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;         
  35.   ADC_CommonInit(ADC2, &ADC_CommonInitStructure);

  36.   ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
  37.   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  38.   //ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;         
  39.   ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  40.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  41.   ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
  42.   ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Enable;  //自动注入使能
  43.   ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  44.   ADC_Init(ADC2, &ADC_InitStructure);

  45.   /* Enable ADC2 */
  46.   ADC_Cmd(ADC2, ENABLE);

  47. }

  48. u16 Get_Adc2(u8 ch)
  49. {
  50.           ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_181Cycles5);
  51. /* wait for ADRDY */
  52.           while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY));
  53. /* Start ADC1 Software Conversion */
  54.           ADC_StartConversion(ADC2);   
  55. /* Test EOC flag */
  56.           while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
  57. /* Get ADC1 converted data */
  58.     return ADC_GetConversionValue(ADC2);
  59. }
复制代码



评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:96313 发表于 2018-9-4 15:18 | 显示全部楼层
在while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET)后面把这句加上,
ADC_ClearFlag(ADC2, ADC_FLAG_EOC);清除标志位

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:96313 发表于 2018-9-5 08:46 | 显示全部楼层
现在ADC1和ADC2都配置好了,把程序附上:
#include "adc.h"
/*************************************************
PA1(ADC1_IN2)     PA5(ADC2_IN2)     PC2(ADC1_IN8)
PA2(ADC1_IN3)     PA6(ADC2_IN3)     PC3(ADC1_IN9)
PA3(ADC1_IN4)     PA7(ADC2_IN4)     PC4(ADC2_IN5)
**************************************************/
__IO uint16_t  ADC1ConvertedValue = 0, ADC1ConvertedVoltage = 0, calibration_value = 0;
void ADC2_init(void)
{
        GPIO_InitTypeDef          GPIO_InitStructure;
  ADC_InitTypeDef           ADC_InitStructure;
  ADC_CommonInitTypeDef     ADC_CommonInitStructure;
       
        RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);
  
  /* Enable ADC1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

  /* ADC Channel configuration */
  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOA, ENABLE);

  /* Configure ADC Channel5 as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
       
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_StructInit(&ADC_InitStructure);

  /* Calibration procedure */  
  ADC_VoltageRegulatorCmd(ADC2, ENABLE);

  ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Single);
  ADC_StartCalibration(ADC2);
  
  while(ADC_GetCalibrationStatus(ADC2) != RESET );
  calibration_value = ADC_GetCalibrationValue(ADC2);
     
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
  ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;            
  //ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;                  
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;         
  ADC_CommonInit(ADC2, &ADC_CommonInitStructure);
  
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;//ADC continuous conversion mode disable
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  //ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;         
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Enable;  //×Ô¶ˉ×¢èëÄ£ê½
  ADC_InitStructure.ADC_NbrOfRegChannel =1;
  ADC_Init(ADC2, &ADC_InitStructure);

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);
}

u16 Get_Adc2(u8 ch)
{
          ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_601Cycles5);
                /* wait for ADRDY */
                while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY));
                /* Start ADC1 Software Conversion */
                ADC_StartConversion(ADC2);   
    /* Test EOC flag */
    while(ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC) == RESET); //|| ADC_GetCommonFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
    /*Clear ADC_FLAG_EOC*/
                ADC_ClearFlag(ADC2,ADC_FLAG_EOC);
                //ADC_ClearCommonFlag(ADC2, ADC_FLAG_EOC);
    /* Get ADC1 converted data */
    return ADC_GetConversionValue(ADC2);
}

void ADC1_init(void)
{
        GPIO_InitTypeDef          GPIO_InitStructure;
  ADC_InitTypeDef           ADC_InitStructure;
  ADC_CommonInitTypeDef     ADC_CommonInitStructure;
       
        RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);
  
  /* Enable ADC1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

  /* ADC Channel configuration */
  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOA, ENABLE);

  /* Configure ADC1 Channel8,9 as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
        /* Configure ADC1 Channel2,3,4 as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        /* Reset ADC init structure parameters values */
  ADC_StructInit(&ADC_InitStructure);

  /* Calibration procedure */  
  ADC_VoltageRegulatorCmd(ADC1, ENABLE);

  ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
  ADC_StartCalibration(ADC1);
  
  while(ADC_GetCalibrationStatus(ADC1) != RESET );
  calibration_value = ADC_GetCalibrationValue(ADC1);
     
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
  ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;            
  //ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;                  
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;         
  ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
  
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  //ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;         
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Enable;  //×Ô¶ˉ×¢èëÄ£ê½
  ADC_InitStructure.ADC_NbrOfRegChannel =1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
}

u16 Get_Adc1(u8 ch)
{
          ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_601Cycles5);
                /* wait for ADRDY */
                while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
                /* Start ADC1 Software Conversion */
                ADC_StartConversion(ADC1);   
    /* Test EOC flag */
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);// || ADC_GetCommonFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    /*Clear ADC_FLAG_EOC*/
                ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
                //ADC_ClearCommonFlag(ADC1, ADC_FLAG_EOC);
    /* Get ADC1 converted data */
    return ADC_GetConversionValue(ADC1);
}

评分

参与人数 1黑币 +30 收起 理由
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:511102 发表于 2019-6-25 10:23 | 显示全部楼层
楼主你好,我也遇到这样的问题,我是在F103的板子上做ADC的数据采集时没有问题,等我移植了RTOS系统后,就在标志位这里陷入了死循环,我加了清除标志位,但是清除标志位这里又陷入了死循环。。。。
代码
void  Adc_Init(void)
{        
        ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );          //使能ADC1通道时钟


        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

        //PA4 作为模拟通道输入引脚                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOA, &GPIO_InitStructure);       

        ADC_DeInit(ADC1);  //复位ADC1

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;        //模数转换工作在单通道模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;        //模数转换工作在单次转换模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

  
        ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1
       
        ADC_ResetCalibration(ADC1);        //使能复位校准  
         
        while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束
       
        ADC_StartCalibration(ADC1);         //开启AD校准

        while(ADC_GetCalibrationStatus(ADC1) != RESET ); //等待校准结束

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能   
}                                  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
          //设置指定ADC的规则组通道,一个序列,采样时间
        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采样时间为239.5周期                                      
  

       
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)// || ADC_GetCommonFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
   
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

    return ADC_GetConversionValue(ADC1);

}
回复

使用道具 举报

ID:961292 发表于 2023-4-3 15:21 | 显示全部楼层
过往云烟 发表于 2018-9-4 15:18
在while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET)后面把这句加上,
ADC_ClearFlag(ADC2, ADC_F ...

感谢大佬!!!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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