Преобразование АЦП, вызванное таймером 1 мс, не работает, STM32F4

Я использую плату STM32F429, и моя конечная цель - получить преобразование АЦП (настроено на доставку 2,7 Кбит / с или 2,7 выборки каждые 1 мс) с использованием триггера TIM8, собрать 1000 выборок в буфере и выполнять передачу DMA каждую секунду. Мне удалось запустить таймер, но по какой-то причине преобразование АЦП не сработало. Без таймера АЦП работает хорошо, а DMA работает (только не каждые 1 мс, но быстрее).

Часы таймеров APB2 имеют частоту 168 МГц. Периферийные часы APB2 имеют частоту 84 МГц.

Функция инициализации TIM8:


    void MX_TIM8_Init(void)
    {

    TIM_ClockConfigTypeDef sClockSourceConfig;
    TIM_MasterConfigTypeDef sMasterConfig;
    TIM_SlaveConfigTypeDef sSlaveConfig;
    TIM_OC_InitTypeDef sConfigOC;
    TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;

    __HAL_RCC_TIM8_CLK_ENABLE();

    htim8.Instance = TIM8;
    htim8.Init.Prescaler = TIM_CLOCKPRESCALER_DIV8; // 1/(168MHz / 2^8) = 1.5238us
    htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim8.Init.Period = 655;                        // 1.5238us * 656 = 0.999ms ~ 1ms
    htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim8.Init.RepetitionCounter = 0;
    if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }
    HAL_TIM_Base_Start(&htim8);

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
    sSlaveConfig.InputTrigger = TIM_TS_ITR1;
    if (HAL_TIM_SlaveConfigSynchronization(&htim8, &sSlaveConfig) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    if (HAL_TIM_OC_Init(&htim8) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    sConfigOC.OCMode = TIM_OCMODE_TIMING;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
    sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    if (HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
    sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
    sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
    sBreakDeadTimeConfig.DeadTime = 0;
    sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
    sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
    sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
    if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

}

Функция инициализации АЦП:


    void MX_ADC1_Init(void)
    {

    ADC_ChannelConfTypeDef sConfig;
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; // 84MHz / 2^6 = 1312.5 KHz
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = ENABLE;
    hadc1.Init.ContinuousConvMode = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
    hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 2;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
    sConfig.Channel = ADC_CHANNEL_5;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; // 1312.5KHz / 480cyc per sample = 2.7Ksps
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
    sConfig.Channel = ADC_CHANNEL_7;
    sConfig.Rank = 2;
    sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }

}

Основной код:


    int main(void)
    {
        //MCU Configuration----------------------------------------------------------

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

        // Configure the system clock
        SystemClock_Config();

        // Initialize all configured peripherals

        MX_DMA_Init();
        MX_ADC1_Init();
        MX_TIM8_Init();

        HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_buf, ADC_BUFFER_LENGTH);

        DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM8_STOP); //Stop timer if code hit a breakpoint

     int timerValue = 0;
        while (1)
        {
            timerValue = __HAL_TIM_GET_COUNTER(&htim8);
            if (halfConvFlag != false)
            {
                println ("Half Conversion callback");
                halfConvFlag = false;
            }
           else if (fullConvFlag != false)
            {
                println ("Full Conversion callback");
                fullConvFlag = false;
            }

        }

    }

При отладке, __HAL_TIM_GET_COUNTER дает мне счет, который доказывает, что это работает, но ADC_buf не собирает никаких ценностей. Что мне не хватает, конфигурации часов должны быть правильными, 2 канала, 2 выборки в мс, а таймер близок к 1 мс. Я сгенерировал конфигурацию таймера, используя STM32CubeMX.

0 ответов

Другие вопросы по тегам