/** * @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 files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles. In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 21 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /21 MHz) - 1 To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows: ARR = (TIM3 counter clock / TIM3 output clock) - 1 = 665 TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50% TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5% TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25% TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 665; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); while (1) {} }
/******** 功能:配置PWM_TIMER 为PWM模式输出 计数频率为TIM_FREQ,PWM周期为PWM_PERIOD,初始占空比为0 ********/ void Servo_TIM_PWM_Init(void) { uint16_t CCR_Val = 1500; int PrescalerValue=1; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; //TIM clock enable //根据TIM选择使能不同的时钟 if((PWM_TIMER == TIM2) || (PWM_TIMER == TIM3)||(PWM_TIMER == TIM4) || (PWM_TIMER == TIM5)||(PWM_TIMER == TIM6) || (PWM_TIMER == TIM7)) { RCC_APB1PeriphClockCmd(PWM_TIMER_CLK, ENABLE); } if((PWM_TIMER != TIM1) && (PWM_TIMER != TIM8)) { RCC_APB2PeriphClockCmd(PWM_TIMER_CLK, ENABLE); } //enable GPIO clocks RCC_APB2PeriphClockCmd( PWM_OUT_PORT_CLK | RCC_APB2Periph_AFIO,ENABLE); //配置相应的GPIO输出 GPIO_InitStructure.GPIO_Pin=PWM_OUT_PIN1|PWM_OUT_PIN2|PWM_OUT_PIN3|PWM_OUT_PIN4; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(PWM_OUT_PORT,&GPIO_InitStructure); //配置TIMER 分频系数 计数周期 工作模式 PrescalerValue= (uint16_t)(SystemCoreClock/TIM_FREQ-1); TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD-1; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(PWM_TIMER , &TIM_TimeBaseStructure); //PWM模式配置 通道1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(PWM_TIMER , &TIM_OCInitStructure); TIM_OC1PreloadConfig(PWM_TIMER , TIM_OCPreload_Enable); //通道2 TIM_OCInitStructure.TIM_Pulse = CCR_Val; TIM_OC2Init(PWM_TIMER , &TIM_OCInitStructure); TIM_OC2PreloadConfig(PWM_TIMER , TIM_OCPreload_Enable); //通道3 TIM_OCInitStructure.TIM_Pulse = CCR_Val; TIM_OC3Init(PWM_TIMER , &TIM_OCInitStructure); TIM_OC3PreloadConfig(PWM_TIMER , TIM_OCPreload_Enable); //通道4 TIM_OCInitStructure.TIM_Pulse = CCR_Val; TIM_OC4Init(PWM_TIMER , &TIM_OCInitStructure); TIM_OC4PreloadConfig(PWM_TIMER , TIM_OCPreload_Enable); TIM_ARRPreloadConfig(PWM_TIMER , ENABLE); /* TIM enable counter */ TIM_Cmd(PWM_TIMER , ENABLE); }
/** * @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_stm32f2xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f2xx.c file */ /* TIM Configuration */ TIM_Config(); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); /* --------------------------------------------------------------------------- TIM3 Configuration: Output Compare Active Mode: In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 1 KHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /1 KHz) - 1 Generate 4 signals with 4 different delays: TIM3_CH1 delay = CCR1_Val/TIM3 counter clock = 1000 ms TIM3_CH2 delay = CCR2_Val/TIM3 counter clock = 500 ms TIM3_CH3 delay = CCR3_Val/TIM3 counter clock = 250 ms TIM3_CH4 delay = CCR4_Val/TIM3 counter clock = 125 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f2xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /*Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 1000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM3, DISABLE); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_GenerateEvent(TIM3, TIM_EventSource_Update); /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); while (1) {} }
/** * @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_stm32f40xx.s/startup_stm32f427x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* ----------------------------------------------------------------------- TIM3 Configuration: Output Compare Timing Mode: In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 6 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /6 MHz) - 1 CC1 update rate = TIM3 counter clock / CCR1_Val = 146.48 Hz ==> Toggling frequency = 73.24 Hz C2 update rate = TIM3 counter clock / CCR2_Val = 219.7 Hz ==> Toggling frequency = 109.8 Hz CC3 update rate = TIM3 counter clock / CCR3_Val = 439.4 Hz ==> Toggling frequency = 219.7 Hz CC4 update rate = TIM3 counter clock / CCR4_Val = 878.9 Hz ==> Toggling frequency = 439.4 Hz Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 6000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM Interrupts enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); while (1); }
/* * @brief Should take an integer 0-255 and create a PWM signal with a duty cycle from 0-100%. * TIM_PWM_FREQ is set at 500 Hz */ void analogWrite(uint16_t pin, uint8_t value) { if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { return; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return; } if(PIN_MAP[pin].pin_mode != OUTPUT && PIN_MAP[pin].pin_mode != AF_OUTPUT_PUSHPULL) { return; } TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; //PWM Frequency : 500 Hz uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1;//TIM Counter clock = 24MHz uint16_t TIM_ARR = (uint16_t)(24000000 / TIM_PWM_FREQ) - 1; // TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255); // AFIO clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); pinMode(pin, AF_OUTPUT_PUSHPULL); // TIM clock enable if(PIN_MAP[pin].timer_peripheral == TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); else if(PIN_MAP[pin].timer_peripheral == TIM3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); else if(PIN_MAP[pin].timer_peripheral == TIM4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time base configuration TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, &TIM_TimeBaseStructure); // PWM1 Mode configuration TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = TIM_CCR; if(PIN_MAP[pin].timer_ch == TIM_Channel_1) { // PWM1 Mode configuration: Channel1 TIM_OC1Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_2) { // PWM1 Mode configuration: Channel2 TIM_OC2Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_3) { // PWM1 Mode configuration: Channel3 TIM_OC3Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_4) { // PWM1 Mode configuration: Channel4 TIM_OC4Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE); // TIM enable counter TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE); }