Embedded 通过直接写入寄存器正确使用ADC?

Embedded 通过直接写入寄存器正确使用ADC?,embedded,stm32,adc,stm32f0,Embedded,Stm32,Adc,Stm32f0,我试图使用cubeIDE在STM32F031K6上使用ADC而不使用HAL(设置中除外)。我在不连续模式下使用ADC-据我所知,事件的顺序应该是 ADC已设置,然后使用ADEN启用 ADC通过设置ADSTART开始转换 检查EOC标志以查看转换何时完成 从DR寄存器读取数据时,EOC标志被清除 这就是我困惑的地方——我是否需要再次设置ADSTART?在连续模式下,参考手册似乎指示下一次转换将自动进行,但在不连续模式状态下,下一次转换需要手动启动-Im假设这是由ADSTART完成的?在模拟中,

我试图使用cubeIDE在STM32F031K6上使用ADC而不使用HAL(设置中除外)。我在不连续模式下使用ADC-据我所知,事件的顺序应该是

  • ADC已设置,然后使用ADEN启用
  • ADC通过设置ADSTART开始转换
  • 检查EOC标志以查看转换何时完成
  • 从DR寄存器读取数据时,EOC标志被清除
这就是我困惑的地方——我是否需要再次设置ADSTART?在连续模式下,参考手册似乎指示下一次转换将自动进行,但在不连续模式状态下,下一次转换需要手动启动-Im假设这是由ADSTART完成的?在模拟中,这似乎不起作用。数据表上说ADSTART是由软件设置的,这是否意味着您不能直接编写它

我的代码如下所示,如果我一步一步地点击它,它似乎无法正常工作,如果我将它设置为运行,我可以看到ADC1_数据变量随着我更改板上的pot而变化,但它会间歇性地工作,在0和正确值之间变化

HAL设置是

static void MX_ADC_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;     
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure for the selected ADC regular channel to be converted. */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure for the selected ADC regular channel to be converted. */
  sConfig.Channel = ADC_CHANNEL_1;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}
程序中的代码读取

ADC1->CR |= ADC_CR_ADEN; // enable ADC
ADC1 ->SMPR = 0b11;// speed divider select
ADC1 ->CHSELR |= 1<<0 | 1<<1; // set sequence to adc0, adc1
ADC1 ->CFGR1 |= ADC_CFGR1_DISCEN; //discontinuous mode
ADC1 ->CR |= 1<<2; // start conversion

while (1)
{
  if((ADC1->ISR) & 0b00000100) //if EOC flag is on
  {
    ADC1_data = ADC1->DR;
    ADC1 ->CR |= 1<<2; // start conversion
  }
}
ADC1->CR |=ADC_CR_ADEN;//启用ADC
ADC1->SMPR=0b11;//速度分配器选择
ADC1->CHSELR |=1“ADSTART由软件设置”表示软件开发人员必须按照数据表在适当的位置注意代码,“ADSTART由软件设置”表示软件开发人员必须按照数据表在适当的位置注意代码,。