while循环进不去

img


为什么这一句不执行呢,另一句却能执行,不知道为什么,不光是ADC,数字读取在while(flag)里也不执行,但是随便写一条语句,在里面就能执行,为什么?

到底哪句执行哪句没执行说清楚点啊

看看flag是不是1,因为它是静态变量

flag被你设置成0之后,再也没有设置回1,所以就只能执行一次,就再也不执行了
不要乱定义静态变量
还有,既然只执行一次就跳出循环,那为什么还要写循环呢
感觉这代码相当冗余

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7778782
  • 这篇博客你也可以参考下:基于单片机内部的ADC知识系统总结
  • 除此之外, 这篇博客: 蓝桥杯嵌入式快速通关篇,ADC读取电位器电压值中的 官方库中的标准例程 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    意法半导体的标准外设库,在赛点资源包的位置
    在这里插入图片描述

    官方给的例程在如下路径

    6-STM32固件库代码V3.5版\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples
    

    在这里插入图片描述

    打开文件夹ADC,因为只使用一个adc通道,我们选择修改第二个文件 ADC1_DMA

    由于是在源代码的基础上修改,所以同学们甚至可以不用明白原理,直接修改,原版完整代码如下:

    
    #include "stm32f10x.h"
    
    /** @addtogroup STM32F10x_StdPeriph_Examples
      * @{
      */
    
    /** @addtogroup ADC_ADC1_DMA
      * @{
      */ 
    
    
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    #define ADC1_DR_Address    ((uint32_t)0x4001244C)
    
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    __IO uint16_t ADCConvertedValue;
    
    /* Private function prototypes -----------------------------------------------*/
    void RCC_Configuration(void);
    void GPIO_Configuration(void);
    
    /* Private functions ---------------------------------------------------------*/
    
    /**
      * @brief   Main program
      * @param  None
      * @retval None
      */
    int main(void)
    {
      /*!< At this stage the microcontroller clock setting is already configured, 
           this is done through SystemInit() function which is called from startup
           file (startup_stm32f10x_xx.s) before to branch to application main.
           To reconfigure the default setting of SystemInit() function, refer to
           system_stm32f10x.c file
         */     
           
      /* System clocks configuration ---------------------------------------------*/
      RCC_Configuration();
    
      /* GPIO configuration ------------------------------------------------------*/
      GPIO_Configuration();
    
      /* DMA1 channel1 configuration ----------------------------------------------*/
      DMA_DeInit(DMA1_Channel1);
      DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
      DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
      DMA_InitStructure.DMA_BufferSize = 1;
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
      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);
      
      /* Enable DMA1 channel1 */
      DMA_Cmd(DMA1_Channel1, ENABLE);
      
      /* ADC1 configuration ------------------------------------------------------*/
      ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfChannel = 1;
      ADC_Init(ADC1, &ADC_InitStructure);
    
      /* ADC1 regular channel14 configuration */ 
      ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);
    
      /* Enable ADC1 DMA */
      ADC_DMACmd(ADC1, ENABLE);
      
      /* Enable ADC1 */
      ADC_Cmd(ADC1, ENABLE);
    
      /* Enable ADC1 reset calibration register */   
      ADC_ResetCalibration(ADC1);
      /* Check the end of ADC1 reset calibration register */
      while(ADC_GetResetCalibrationStatus(ADC1));
    
      /* Start ADC1 calibration */
      ADC_StartCalibration(ADC1);
      /* Check the end of ADC1 calibration */
      while(ADC_GetCalibrationStatus(ADC1));
         
      /* Start ADC1 Software Conversion */ 
      ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    
      while (1)
      {
      }
    }
    
    /**
      * @brief  Configures the different system clocks.
      * @param  None
      * @retval None
      */
    void RCC_Configuration(void)
    {
    #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
      /* ADCCLK = PCLK2/2 */
      RCC_ADCCLKConfig(RCC_PCLK2_Div2); 
    #else
      /* ADCCLK = PCLK2/4 */
      RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
    #endif
      /* Enable peripheral clocks ------------------------------------------------*/
      /* Enable DMA1 clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
      /* Enable ADC1 and GPIOC clock */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
    }
    
    /**
      * @brief  Configures the different GPIO ports.
      * @param  None
      * @retval None
      */
    void GPIO_Configuration(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    
      /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    
    #ifdef  USE_FULL_ASSERT
    
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t* file, uint32_t line)
    { 
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    
      /* Infinite loop */
      while (1)
      {
      }
    }
    
    #endif
    
    /**
      * @}
      */ 
    
    /**
      * @}
      */ 
    
    /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
    
    

    大家看过的大多数蓝桥杯adc例程里面估计都没有用dma方法实现的,简单介绍下dma,

    DMA,全称Direct Memory Access,即直接存储器访问。

    DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存>>储器之间或者存储器和存储器之间的高速数据传输。
    即DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

    形象地说,不需要cpu的参与,信息从一块地方传输到另一块地方,在adc这里,不需要你调用读取函数,其值也会在某个变量里被自动更新。

    所以要重点关注的代码有

    __IO uint16_t ADCConvertedValue;
    

    找到__IO的定义,发现他实际是volatile,说明ADCConvertedValue这个变量可以自己变更值。实际上其储存的值就是0-4095的adc读取值
    在这里插入图片描述


    然后关注到时钟和IO口的设置,在官方开发板里,分压电阻R37连接的io口是PB0,所以时钟和引脚要有相应的修改,如下:

    void RCC_Configuration(void)
    {
    #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
      /* ADCCLK = PCLK2/2 */
      RCC_ADCCLKConfig(RCC_PCLK2_Div2); 
    #else
      /* ADCCLK = PCLK2/4 */
      RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
    #endif
      /* Enable peripheral clocks ------------------------------------------------*/
      /* Enable DMA1 clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
      /* Enable ADC1 and GPIOC clock */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
    }
    
    /**
      * @brief  Configures the different GPIO ports.
      * @param  None
      * @retval None
      */
    void GPIO_Configuration(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    
      /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
    }
    

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    对应代码修改这两处即可


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^