Ядерная плата STM32H743, использующая 3 АЦП одновременно (1 АД C за раз) в режиме опроса; не работает - PullRequest
0 голосов
/ 20 января 2020

Я работаю над проектом, в котором задействуется ядерная плата STM32H743 и используются 16 входов AD C.

Очевидно, что эти аналоговые входы используются один раз; считайте значение с помощью механизма опроса и настройте следующий вход ... настройте канал AD C, запустите AD C, прочитайте значение с помощью опроса и настройте следующий вход ... 16 раз каждые 1 мс, как Поведение в реальном времени.

Проблема, которую я обнаружил, заключается в том, что я не могу запустить ни один из 3 АЦП, он застрял в этой строке на stm32h7xx_hal_ad c .h (я думаю, что я настраиваю часы или другое что-то неправильно):

    while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)

Эта строка находится в функции:

    HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)

Это вызывается:

    HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)

Заранее спасибо за Справка, исходный код приведен ниже.

Файлы исходного кода:

MAIN. C

    #include "main.h"
    #include "hwdrvlib.h" 
    #include "test.h"

    volatile unsigned int systick_count = 0;
    static volatile int systick_active = 1;

    /** 
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
    #ifdef CPU_CACHE
     /* Enable I-Cache---------------------------------------------------------*/
     SCB_EnableICache();
     /* Enable D-Cache---------------------------------------------------------*/
     SCB_EnableDCache();
    #endif 
     /* MCU Configuration--------------------------------------------------------*/
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init(); 
     /* Configure the system clock */ 
     SystemClock_Config(); //Located on hwdrvlid.h y hwdrvlib.c
     /* SysTick is 0 at start */

     tick = (uint8_t)0;
     /* Initialize */

    ADC_Init(); /* Initialize ADC peripherals and GPIO ADC inputs as analog */
                      //Located on hwdrvlid.h y hwdrvlib.c

     /* Sample Time: 0.001 */
     while (...) {  /* Some comparison deleted for readability */
       RT_Task(); //Located on Function file
     }                                   //End of while 
    }   

hwdrvlib. c (Файл который содержит функции конфигурации)

    ADC_HandleTypeDef hadc1 __attribute__((section(".ramd2")));
    ADC_HandleTypeDef hadc2 __attribute__((section(".ramd2")));
    ADC_HandleTypeDef hadc3 __attribute__((section(".ramd2")));
    void ADC_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct; 
      /* ADC Clock Enable */
      __HAL_RCC_ADC12_CLK_ENABLE();
      __HAL_RCC_ADC3_CLK_ENABLE(); 
      /* ADC Periph interface clock configuration */
      __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);//or PLL2 
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOF_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();

      /* ADCs GPIO as analog input */
      /* System ADC Input number 1  PF9 */
      /*##-2- Configure peripheral GPIO ##########################################*/
      /* ADC Channel GPIO pin configuration */
      GPIO_InitStruct.Pin = GPIO_PIN_9;
      GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

     /* Initialization of 16 analog inputs, hidden for readability */

      /* System ADC Input number 16  PA3 */
      /*##-2- Configure peripheral GPIO ##########################################*/
      /* ADC Channel GPIO pin configuration */
      GPIO_InitStruct.Pin = GPIO_PIN_3;
      GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

      /* ADC1 Config */
      hadc1.Instance = ADC1;
      if (HAL_ADC_DeInit(&hadc1) != HAL_OK) {
        /* ADC1 de-initialization Error */
        Error_Handler();
      }

      hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
      hadc1.Init.Resolution = ADC_RESOLUTION_16B;
      hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
      hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
      hadc1.Init.LowPowerAutoWait = DISABLE;
      hadc1.Init.ContinuousConvMode = DISABLE;
      hadc1.Init.NbrOfConversion = 1;      /* Vector Support */
      hadc1.Init.DiscontinuousConvMode = DISABLE;
      hadc1.Init.NbrOfDiscConversion = 1;
      hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
      hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
      hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
      hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
      hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
      hadc1.Init.OversamplingMode = DISABLE;
      if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        Error_Handler();
      } 
     /* The same for ADC2 and ADC3 using hadc2 and hadc3 */
    }


    void ADC_Input_Select(ADC_HandleTypeDef *hadc,uint32_t Channel)
    {
      static ADC_ChannelConfTypeDef sConfig = { 0 };

      /* Configure Regular Channel */
      sConfig.Channel = Channel;
      sConfig.Rank = ADC_REGULAR_RANK_1;
      sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
      sConfig.SingleDiff = ADC_SINGLE_ENDED;
      sConfig.OffsetNumber = ADC_OFFSET_NONE;
      sConfig.Offset = 0;
      if (HAL_ADC_ConfigChannel(hadc, &sConfig) != HAL_OK) {
        Error_Handler();
      }
    }



    /**
     * @brief System Clock Configuration
     * @retval None
     *
     *
     *
     * Configure 480 MHz CPU Clock, 240 MHz APB1 and APB2 Clock
     *                                          flash latency 4
     */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };

      RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };

      RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };

      /** Supply configuration update enable
       */
      HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

      /* The voltage scaling allows optimizing the power consumption when the device is
         clocked below the maximum system frequency, to update the voltage scaling value
         regarding system frequency refer to product datasheet.  */
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
      while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
      }

      __HAL_RCC_SYSCFG_CLK_ENABLE();
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
      while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
      }

      __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);//HSE

      /* a 480 MHz config */

      /** Configure the main internal regulator output voltage
       */
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
      while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
      }

      /** Initializes the CPU, AHB and APB busses clocks
       */
    #ifdef USB_VCP_SETUP

      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 |
        RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
      RCC_OscInitStruct.PLL.PLLM = 4;
      RCC_OscInitStruct.PLL.PLLN = 60;
      RCC_OscInitStruct.PLL.PLLP = 2;
      RCC_OscInitStruct.PLL.PLLQ = 2;
      RCC_OscInitStruct.PLL.PLLR = 2;
      RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
      RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
      RCC_OscInitStruct.PLL.PLLFRACN = 0;

    #else

      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
      RCC_OscInitStruct.PLL.PLLM = 4;
      RCC_OscInitStruct.PLL.PLLN = 60;
      RCC_OscInitStruct.PLL.PLLP = 2;
      RCC_OscInitStruct.PLL.PLLQ = 2;
      RCC_OscInitStruct.PLL.PLLR = 2;
      RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
      RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
      RCC_OscInitStruct.PLL.PLLFRACN = 0;

    #endif

      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }

      /* End of old 480 MHz config */

      /** Initializes the CPU, AHB and APB busses clocks
       */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
        |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
        |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
      RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
        Error_Handler();
      }

      /* USB CLK Initialization if needed */
    #ifdef USB_VCP_SETUP

      PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
      PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;//PLL
      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
        Error_Handler();
      }

      /** Enable USB Voltage detector
       */
      HAL_PWREx_EnableUSBVoltageDetector();

    #endif

    }

ФУНКЦИЯ ФУНКЦИИ (Функция, которая содержит функцию, которая должна быть выполнена для чтения данных аналогового ввода)

    void RT_Task(void)
    {
      /* ADC3-IN2  PF9 */
      ADC_Input_Select(&hadc3,ADC_CHANNEL_2);
      HAL_ADC_Start(&hadc3); /* Execution stucks here :(  */
      if (HAL_ADC_PollForConversion(&hadc3,1000) != HAL_OK ) {
        /* ADC conversion fails */
        //Escribir aqui la salida de error
      } else {
        test2_B.VectorConcatenate[1] = HAL_ADC_GetValue(&hadc3) + 0;
      }

    /* More ADC reading hidden for readability */
    }

1 Ответ

0 голосов
/ 20 января 2020

Решение этой проблемы, помните, что вы можете столкнуться с этим с любым микроконтроллером:

Я обнаружил ошибку, это то, что я никогда раньше не представлял.

Функция инициализации занимает больше времени, необходимого IRQ SysTick для запуска первого IRQ (задача реального времени вызывается из IRQ SysTick), и из-за AD C периферийные устройства не инициализируются ... его функции не могут быть выполнены должным образом.

Я добавил переменную uint8, чтобы определить, заканчивается ли функция инициализации кодом запуска вызова RT. Также мне нужно включить ADC_ConfigureBoostMode (& hadc1); для каждого использованного AD C.

int main(void)
{

    Init_finished = (uint8_t)0;

#ifdef CPU_CACHE

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();

  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();

#endif

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* SysTick is 0 at start */
  tick = (uint8_t)0;

  /* Initialize model */
  test_initialize(1);

  Init_finished = (uint8_t)255;

и используйте эти

ADC_ConfigureBoostMode(&hadc1); /* and for hadc2 and hadc3 */
...