【问题标题】:Let a LED blink by using the PWM - STM32F429 Discovery Board使用 PWM 让 LED 闪烁 - STM32F429 探索板
【发布时间】:2022-06-11 06:33:07
【问题描述】:

我有以下代码让一个点在 8 段显示器上闪烁并使用电位计调整其频率。我正在使用 STM32F429 发现板,我现在要添加的功能是使用输出比较单元/PWM 来控制亮度。以下宏用于在比较寄存器中设置一个新值,但我不确定如何使用它:

"__HAL_TIM_SET_COMPARE(&timer_handle_struct, TIM_CHANNEL_2, 3000);"

例如,当电位计的值介于 0 和 329 之间时,我希望点以 100% 的亮度闪烁,当它的值介于 330 和 659 之间时,以 90% 的亮度闪烁,依此类推。 如果您需要更多信息,请告诉我。我希望你能帮助我。提前致谢!


timer.c

#include "stm32f4xx.h"
#include <timer/timer.h>

TIM_HandleTypeDef tim_handle_struct;
TIM_OC_InitTypeDef tim_oc_handle_struct;
uint16_t time = 0;

/**
 * @brief Function initializes Timer
 * @param None
 * @return None
 */
void timer_init(void) {
    __HAL_RCC_TIM1_CLK_ENABLE();

    tim_handle_struct.Instance = TIM1;
    tim_handle_struct.Init.Prescaler = (SystemCoreClock / 10000) - 1;
    tim_handle_struct.Init.Period = 10000 - 1;
    tim_handle_struct.Init.CounterMode = TIM_COUNTERMODE_UP;
    tim_handle_struct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    tim_handle_struct.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    tim_handle_struct.Init.RepetitionCounter = 0;

    HAL_TIM_Base_Init(&tim_handle_struct);

    HAL_TIM_Base_Start(&tim_handle_struct);
}

/**
 * @brief Function initializes OC Unit
 * @param None
 * @return None
 */
void timer_init_OC(void) {
    tim_oc_handle_struct.OCMode = TIM_OCMODE_PWM1;
    tim_oc_handle_struct.Pulse = 5000;
    tim_oc_handle_struct.OCIdleState = TIM_OCIDLESTATE_SET;
    tim_oc_handle_struct.OCPolarity = TIM_OCPOLARITY_HIGH;
    tim_oc_handle_struct.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    tim_oc_handle_struct.OCNPolarity = TIM_OCNPOLARITY_LOW;
    tim_oc_handle_struct.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&tim_handle_struct, &tim_oc_handle_struct,
    TIM_CHANNEL_2);

    HAL_TIM_OC_Start(&tim_handle_struct, TIM_CHANNEL_2);
}

/**
 * @brief Function initializes Port E
 * @param None
 * @return None
 */
void timer_init_GPIO(void) {
    __HAL_RCC_GPIOE_CLK_ENABLE(); // activating GPIO tact for port E

    GPIO_InitTypeDef GPIO_init_struct; // creating structure to configure port settings

    GPIO_init_struct.Pin = GPIO_PIN_11;
    GPIO_init_struct.Mode = GPIO_MODE_AF_PP;
    GPIO_init_struct.Alternate = GPIO_AF1_TIM1;
    GPIO_init_struct.Pull = GPIO_NOPULL;
    GPIO_init_struct.Speed = GPIO_SPEED_MEDIUM;

    HAL_GPIO_Init(GPIOE, &GPIO_init_struct); // initializing port E
}

/**
 * @brief Function initializes Port D
 * @param None
 * @return None
 */
void dot_init(void){
    __HAL_RCC_GPIOD_CLK_ENABLE(); // activating GPIO tact for port D

    GPIO_InitTypeDef gpio_initD; // creating structure to configure port settings

    gpio_initD.Pin = GPIO_PIN_1 | GPIO_PIN_11;
    gpio_initD.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_initD.Pull = GPIO_NOPULL;
    gpio_initD.Speed = GPIO_SPEED_MEDIUM;

    HAL_GPIO_Init(GPIOD, &gpio_initD); // initializing port D

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_11);
}

/**
 * @brief Function sets blink-frequency by using the potentiometer
 * @param value is the current potentiometer value
 * @return None
 */
void timer_setFrequency(uint32_t value) {
    if(value > 0 && value < 329){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1);
    }
    if(value > 330 && value < 659){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -1000);
    }
    if(value > 660 && value < 989){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -2000);
    }
    if(value > 990 && value < 1319){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -3000);
    }
    if(value > 1320 && value < 1649){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -4000);
    }
    if(value > 1650 && value < 1979){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -5000);
    }
    if(value > 1980 && value < 2309){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -6000);
    }
    if(value > 2310 && value < 2639){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -7000);
    }
    if(value > 2640 && value < 2969){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -8000);
    }
    if(value > 2970 && value < 3300){
        time = __HAL_TIM_SET_PRESCALER(&tim_handle_struct, (SystemCoreClock/10000)-1 -9000);
    }
}

主要

#include "stm32f4xx.h"
#include <timer/timer.h>
#include "stdio.h"
#include <potentiometer/potis.h>

uint32_t res = 0;

int main(void)
{
    HAL_Init();
    potis_init();

    timer_init_GPIO();
    timer_init();
    timer_init_OC();
    dot_init();

    while(1){
        res = potis_getVal(1);
        timer_setFrequency(res);
    }
}

potis.c

#include "stm32f4xx.h"
#include <potentiometer/potis.h>

/**
 * @brief Function initializes Port A and ADC1 with channel 1 & 2
 * @param None
 * @return None
 */
ADC_HandleTypeDef ADC_handle_structure;
ADC_ChannelConfTypeDef ADC_channel_structure_poti_1;
ADC_ChannelConfTypeDef ADC_channel_structure_poti_2;

void potis_init(void) {

    __HAL_RCC_GPIOA_CLK_ENABLE(); // activating GPIO tact for port A

    GPIO_InitTypeDef gpio_initA; // creating structure to configure port settings

    gpio_initA.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    gpio_initA.Mode = GPIO_MODE_ANALOG;
    gpio_initA.Pull = GPIO_NOPULL; // not necessary because the analog values get manipulated by the resistors
    gpio_initA.Speed = GPIO_SPEED_MEDIUM;

    HAL_GPIO_Init(GPIOA, &gpio_initA); // initializing port A

    //Configuration of ADC
    // ADC_handle_structure
    __HAL_RCC_ADC1_CLK_ENABLE();
    ADC_handle_structure.Instance = ADC1;
    ADC_handle_structure.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 84 MHz / 4 = 21 MHZ < 36 MHZ <-- ADC fmax
    ADC_handle_structure.Init.Resolution = ADC_RESOLUTION_12B;
    ADC_handle_structure.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    ADC_handle_structure.Init.ScanConvMode = DISABLE;
    ADC_handle_structure.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    ADC_handle_structure.Init.ContinuousConvMode = DISABLE;
    ADC_handle_structure.Init.NbrOfConversion = 1;
    ADC_handle_structure.Init.ExternalTrigConv = ADC_SOFTWARE_START;

    HAL_ADC_Init(&ADC_handle_structure);

    ADC_channel_structure_poti_1.Channel = ADC_CHANNEL_6;
    ADC_channel_structure_poti_1.Rank = 1;
    ADC_channel_structure_poti_1.SamplingTime = ADC_SAMPLETIME_84CYCLES; // 84 MHz / 21 MHz = 0,004 ms

    ADC_channel_structure_poti_2.Channel = ADC_CHANNEL_7;
    ADC_channel_structure_poti_2.Rank = 1;
    ADC_channel_structure_poti_2.SamplingTime = ADC_SAMPLETIME_84CYCLES; // 84 MHz / 21 MHz = 0,004 ms
}
/**
 * @brief Function chooses & configures the selected potentiometer channel for conversion
 * @param poti_num number of the converted potentiometer values: 1,2
 * @return None
 */
void select_ADC_channel(uint8_t poti_num) {
    if(poti_num == 1)
    {
        HAL_ADC_ConfigChannel(&ADC_handle_structure, &ADC_channel_structure_poti_1);
    }
    else if(poti_num == 2)
    {
        HAL_ADC_ConfigChannel(&ADC_handle_structure, &ADC_channel_structure_poti_2);
    }
}

/**
 * @brief Function computes the AD Conversion of the selected potentiometer
 * @param poti_num number of the converted potentiometer  values: 1,2
 * @return
 */
uint32_t potis_getVal(uint8_t poti_num) {

    uint32_t ret;
    uint32_t poti_voltage;

    select_ADC_channel(poti_num);
    HAL_ADC_Start(&ADC_handle_structure);

    ret = HAL_ADC_PollForConversion(&ADC_handle_structure, 1000);
    if(ret != HAL_TIMEOUT)
    {
        uint32_t ADC_val = HAL_ADC_GetValue(&ADC_handle_structure);
        poti_voltage = 3300 * ADC_val / 4095;
        return poti_voltage;
    }
    return 1;
}

【问题讨论】:

  • 你的问题是什么?读电位器?配置脉宽调制?有些不同?请准确并专注于您的描述。在缩小您的问题范围后,您不妨相应地缩小您的代码范围。

标签: c timer stm32 pwm


猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多