/* * @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); }
void tim_state(int dev, uint8_t state) { TIM_Cmd(tim_devs[dev], state); }
/** * @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_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* DMA Configuration */ DMA_Configuration(); /* TIM1 DMA Transfer example ------------------------------------------------- TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices and to 24 MHz for Low-Density Value line and Medium-Density Value line devices. The objective is to configure TIM1 channel 3 to generate complementary PWM signal with a frequency equal to 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 and a variable duty cycle that is changed by the DMA after a specific number of Update DMA request. The number of this repetitive requests is defined by the TIM1 Repetion counter, each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new value defined by the SRC_Buffer . -----------------------------------------------------------------------------*/ /* Compute the value to be set in ARR regiter to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570 ) - 1; /* Compute CCR1 value to generate a duty cycle at 50% */ SRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR1 value to generate a duty cycle at 37.5% */ SRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000); /* Compute CCR1 value to generate a duty cycle at 25% */ SRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* TIM1 Peripheral Configuration --------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 2; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = SRC_Buffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* TIM1 Update DMA Request enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); 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 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 */ /* TIM1 Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock (168MHz). The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to (11/SystemCoreClock) ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. 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 value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) { } }
void ADC_StopConver(void) { TIM_Cmd(TIM2, DISABLE); ADC_DMACmd(ADC1, DISABLE); }
//------------------------------------------------------------------------------ void TIM2_IRQHandler(void) { if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) { uiTime_AlarmLevel = uiTime_AlarmLevel + 1; uiRespond_time = uiRespond_time + 1; STM_EVAL_LEDOff(LED5); if (uiCurrent_Status == STATUS_SpO2_BELOW_L1 | uiCurrent_Status == STATUS_SpO2_BEHIGH_L1) { if (uiTime_AlarmLevel > SProfile.uiAlarm_Level1) { uiTime_AlarmLevel = 0; // Reset Time_AlarmLevel uiRespond_time = 0; /* If Time alarm more than alarm level 1 set */ if (uiCurrent_Status == STATUS_SpO2_BELOW_L1) { uiCurrent_Status = STATUS_SpO2_BELOW_ALARM_L1; uiPurpose_FiO2 = uiPurpose_FiO2 + 6; if (uiPurpose_FiO2 > SProfile.uiFiO2_Maximum) { /* if uiPurpose_FiO2 more than uiFiO2_Maximum */ uiPurpose_FiO2 = SProfile.uiFiO2_Maximum; } FiO2_Range(uiPurpose_FiO2); /* Update LCD */ lcdString(1,5,"Status: Below "); lcdString(1,6,"Alarm Level 2"); } else if (uiCurrent_Status == STATUS_SpO2_BEHIGH_L1) { uiCurrent_Status = STATUS_SpO2_BEHIGH_ALARM_L1; uiPurpose_FiO2 = uiPurpose_FiO2 - 6; if (uiPurpose_FiO2 < SProfile.uiFiO2_Minimum) { /* if uiPurpose_FiO2 more than uiFiO2_Minimum */ uiPurpose_FiO2 = SProfile.uiFiO2_Minimum; } FiO2_Range(uiPurpose_FiO2); /* Update LCD */ lcdString(1,5,"Status: Behigh "); lcdString(1,6,"Alarm Level 2"); } } else if( uiRespond_time > SProfile.uiRespondsTime) { if( uiCurrent_Status == STATUS_SpO2_BELOW_L1) { /* Check Current SpO2. if SpO2 is lower than last time, the system will increase FiO2 */ if (uiCurrent_SpO2 <= uiInitial_SpO2) { uiPurpose_FiO2 = uiPurpose_FiO2 + 4; // Increase FiO2 4 percent } uiRespond_time = 0; // clear Respond time /* Check Limit of FiO2 */ if (uiPurpose_FiO2 > SProfile.uiFiO2_Maximum) { uiPurpose_FiO2 = SProfile.uiFiO2_Maximum; } uiInitial_SpO2 = uiCurrent_SpO2; // save current SpO2 at initial } else if(uiCurrent_Status == STATUS_SpO2_BEHIGH_L1) { /* if SpO2 is higher than last time, the system will decrease FiO2*/ if(uiCurrent_SpO2 >= uiInitial_SpO2) { uiPurpose_FiO2 = uiPurpose_FiO2 - 4; // Decrease FiO2 4 percent } uiRespond_time = 0; // Clear Respond time /* Check Limit of FiO2 */ if (uiPurpose_FiO2 < SProfile.uiFiO2_Minimum) { uiPurpose_FiO2 = SProfile.uiFiO2_Minimum; } } uiInitial_SpO2 = uiCurrent_SpO2; // save new Current SpO2 FiO2_Range(uiPurpose_FiO2); } } else if (uiCurrent_Status == STATUS_SpO2_BEHIGH_L2 | uiCurrent_Status == STATUS_SpO2_BELOW_L2) { /* Alarm Level 2 */ if (uiTime_AlarmLevel >= SProfile.uiAlarm_Level2) { GPIO_SetBits(Alarm_Set_GPIO_Port, Alarm_Set_Pin); uiCurrent_Status = STATUS_ALARM; USART_Cmd(OPM_USART, ENABLE); // ENABLE Oxygen Pulse Meter USART TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE); TIM_Cmd(TIM3, DISABLE); // NVIC_InitTypeDef NVIC_InitStructure; /* Enable and set Alarm_Button_EXTI Line Interrupt to the lowest priority */ // NVIC_InitStructure.NVIC_IRQChannel = Alarm_Button_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); //Time_AlarmLevel = 0; /* Notification Alarm Board (Toggle Pin to Alarm Circuit) */ lcdClear(); lcdUpdate(); lcdString(3,1,"ALARM !!!"); lcdString(2,2,"PLEASE PUSH"); lcdString(2,3,"ALARM BUTTON"); alarm_timer(TIMER_DISABLE); } else if (uiRespond_time >= SProfile.uiRespondsTime) { if(uiCurrent_Status == STATUS_SpO2_BEHIGH_L2) { /* Is SpO2 higher than last SpO2 ?*/ if(uiCurrent_SpO2 >= uiInitial_SpO2) { uiPurpose_FiO2 = uiPurpose_FiO2 - 6; // Decrease FiO2 6 percent } uiRespond_time = 0; // Clear Respond time /* Check Limit of FiO2 range */ if (uiPurpose_FiO2 < SProfile.uiFiO2_Minimum) { uiPurpose_FiO2 = SProfile.uiFiO2_Minimum; } uiInitial_SpO2 = uiCurrent_SpO2; // save current SpO2 } else if(uiCurrent_Status == STATUS_SpO2_BELOW_L2) { /* Is SpO2 lower than last SpO2 ? */ if(uiCurrent_SpO2 <= uiInitial_SpO2) { uiPurpose_FiO2 = uiPurpose_FiO2 + 6; } uiRespond_time = 0; // clear respond time /* Check Limit of FiO2 range */ if(uiPurpose_FiO2 > SProfile.uiSpO2_Maximum) { uiPurpose_FiO2 = SProfile.uiSpO2_Maximum; } uiInitial_SpO2 = uiCurrent_SpO2; // save Current SpO2 } FiO2_Range(uiPurpose_FiO2); } } else if ((uiCurrent_Status == STATUS_MIDDLE_SpO2_BELOW) | (uiCurrent_Status == STATUS_MIDDLE_SpO2_BEHIGH)) { if (uiRespond_time >= SProfile.uiRespondsTime) { /* if time over than Responds time, FiO2 will increse or decrease 2 percent */ uiTime_AlarmLevel = 0; // clear Time_AlarmLevel uiRespond_time = 0; // clear respond time if (uiCurrent_SpO2 < SProfile.uiSpO2_middleRange) { uiPurpose_FiO2 = uiPurpose_FiO2 + 2; // increase FiO2 more than present 2 percent if (uiPurpose_FiO2 > SProfile.uiFiO2_Maximum) { uiPurpose_FiO2 = SProfile.uiFiO2_Maximum; } uiInitial_SpO2 = uiCurrent_SpO2; } else if (uiCurrent_SpO2 > SProfile.uiSpO2_middleRange) { uiPurpose_FiO2 = uiPurpose_FiO2 - 2; // decrease FiO2 more than present 2 percent if (uiPurpose_FiO2 < SProfile.uiFiO2_Minimum) { uiPurpose_FiO2 = SProfile.uiFiO2_Minimum; } uiInitial_SpO2 = uiCurrent_SpO2; } } uiInitial_SpO2 = uiCurrent_SpO2; FiO2_Range(uiPurpose_FiO2); } TIM_ClearITPendingBit (TIM2, TIM_IT_Update); } }
bool Servo::attach(uint16_t pin, uint16_t minPW, uint16_t maxPW, int16_t minAngle, int16_t maxAngle) { if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { return false; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return false; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return false; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return false; } if (this->attached()) { this->detach(); } this->pin = pin; this->minPW = minPW; this->maxPW = maxPW; this->minAngle = minAngle; this->maxAngle = maxAngle; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 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 = SERVO_TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = SERVO_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 = 0x0000; if(PIN_MAP[this->pin].timer_ch == TIM_Channel_1) { // PWM1 Mode configuration: Channel1 TIM_OC1Init(PIN_MAP[this->pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC1PreloadConfig(PIN_MAP[this->pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[this->pin].timer_ch == TIM_Channel_2) { // PWM1 Mode configuration: Channel2 TIM_OC2Init(PIN_MAP[this->pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC2PreloadConfig(PIN_MAP[this->pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[this->pin].timer_ch == TIM_Channel_3) { // PWM1 Mode configuration: Channel3 TIM_OC3Init(PIN_MAP[this->pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC3PreloadConfig(PIN_MAP[this->pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[this->pin].timer_ch == TIM_Channel_4) { // PWM1 Mode configuration: Channel4 TIM_OC4Init(PIN_MAP[this->pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC4PreloadConfig(PIN_MAP[this->pin].timer_peripheral, TIM_OCPreload_Enable); } TIM_ARRPreloadConfig(PIN_MAP[this->pin].timer_peripheral, ENABLE); // TIM enable counter TIM_Cmd(PIN_MAP[this->pin].timer_peripheral, ENABLE); // Main Output Enable TIM_CtrlPWMOutputs(PIN_MAP[this->pin].timer_peripheral, ENABLE); return true; }
/** * @brief Configures the TIM Peripheral. * @param None * @retval None */ static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* --------------------------- System Clocks Configuration -----------------*/ /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* GPIOD clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /*-------------------------- GPIO Configuration ----------------------------*/ /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Connect TIM4 pins to AF2 */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); /* ----------------------------------------------------------------------- TIM4 Configuration: Output Compare Timing Mode: In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1 (APB1 Prescaler = 4, see system_stm32f4xx.c file). TIM4CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM4CLK = 2*(HCLK / 4) = HCLK/2 = SystemCoreClock/2 To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows: Prescaler = (TIM4CLK / TIM1 counter clock) - 1 Prescaler = (168 MHz/(2 * 2 KHz)) - 1 = 41999 To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows: ARR = (TIM4 counter clock / TIM4 output clock) - 1 = 1999 TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50% TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 50% TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 50% TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 50% ==> TIM4_CCRx = TIM4_ARR/2 = 1000 (where x = 1, 2, 3 and 4). 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) / 2000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Enable TIM4 Preload register on ARR */ TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM PWM1 Mode configuration: Channel */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = TIM_CCR; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /* Output Compare PWM1 Mode configuration: Channel1 */ TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); /* Output Compare PWM1 Mode configuration: Channel2 */ TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); /* Output Compare PWM1 Mode configuration: Channel3 */ TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); /* Output Compare PWM1 Mode configuration: Channel4 */ TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); /* TIM4 enable counter */ TIM_Cmd(TIM4, 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_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* Timers synchronisation in cascade mode ---------------------------- 1/TIM2 is configured as Master Timer: - PWM Mode is used - The TIM2 Update event is used as Trigger Output 2/TIM3 is slave for TIM2 and Master for TIM4, - PWM Mode is used - The ITR1(TIM2) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM2 update event). - The TIM3 Update event is used as Trigger Output. 3/TIM4 is slave for TIM3, - PWM Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 update event). * For Low-density, Medium-density, High-density and Connectivity line devices: The TIMxCLK is fixed to 72 MHz, the TIM2 counter clock is 72 MHz. The Master Timer TIM2 is running at TIM2 frequency : TIM2 frequency = (TIM2 counter clock)/ (TIM2 period + 1) = 281.250 KHz and the duty cycle = TIM2_CCR1/(TIM2_ARR + 1) = 25%. The TIM3 is running: - At (TIM2 frequency)/ (TIM3 period + 1) = 70.312 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 25% The TIM4 is running: - At (TIM3 frequency)/ (TIM4 period + 1) = 17.578 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 25% * For Low-Density Value line and Medium-Density Value line devices: The TIMxCLK is fixed to 24 MHz, the TIM2 counter clock is 24 MHz. So TIM2 frequency = 93.750 KHz, TIM3 is running at 23.437 KHz, and TIM4 is running at 5.85 KHz -------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* Slaves Configuration: PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM4, ENABLE); 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 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(); /* --------------------------------------------------------------------------- TIM10 Configuration: generate 1 PWM signal: In this example TIM10 input clock (TIM10CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM10CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM10CLK = HCLK = SystemCoreClock To get TIM10 counter clock at 21 MHz, the prescaler is computed as follows: Prescaler = (TIM10CLK / TIM10 counter clock) - 1 Prescaler = (SystemCoreClock /21 MHz) - 1 To get TIM10 output clock at 31.530 KHz, the period (TIM10_ARR) is computed as follows: ARR = (TIM10 counter clock / TIM10 output clock) - 1 = 665 TIM10 Channel1 duty cycle = (TIM10_CCR1/ TIM10_ARR)* 100 = 50% 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 / 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(TIM10, &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(TIM10, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM10, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM10, ENABLE); /* TIM10 enable counter */ TIM_Cmd(TIM10, ENABLE); while (1) {} }
void boardInit() { SysTick_Config(SystemCoreClock/1000 - 1); /* A note about interrupt priorities A smaller numeric priority means that the priority is higher, thus the most important interrupt has priority 0, the least import 31. If an interrupt arrives while servicing an interrupt with a lower priority, then the lesser interrupt is interrupted to service the high priority one, if the high priority interrupt is of a different preemption priority group. IOW: an IRQ in PP group 3 will be interrupted if an IRQ arrives with PP group 2,1 or 0. The sub priority is only used to order the interrupts at the same PE level. NVIC_SetPriorityGrouping is used here to divide the 32 levels of IRQ priorities into 8 preemption groups and 4 sub priorities. */ NVIC_SetPriorityGrouping(4); for (int i=0;i<35;i++) { NVIC_SetPriority(i, GROUP_PRIORITY_DEFAULT); } NVIC_SetPriority(TIMER2_IRQn, GROUP_PRIORITY_STEPPER); NVIC_SetPriority(SysTick_IRQn, GROUP_PRIORITY_1000HZ); NVIC_SetPriority(TIMER3_IRQn, GROUP_PRIORITY_100HZ); NVIC_SetPriority(USB_IRQn, GROUP_PRIORITY_USB); initUARTs(); initADC(); initPWM(); // Motor drivers are active low, so let's disable all of them, until the drivers turn them on: GPIO_SET(IO_X_ENABLE); GPIO_SET(IO_Y_ENABLE); GPIO_SET(IO_Z_ENABLE); GPIO_SET(IO_A_ENABLE); /* Set the simple I/O configuration for all the pins we use, this will ensure that all pins have had its function selected */ for (int i=0;i<ALL_PINS_SIZE;i++) { configPin(ALL_PINS[i]); } /* Set up timer3 to poke the "slow" 100Hz maintainance routine */ TIM_TIMERCFG_Type timerCfg; timerCfg.PrescaleOption = TIM_PRESCALE_USVAL; timerCfg.PrescaleValue = 1000; // 1 ms interval TIM_Init(LPC_TIM3, TIM_TIMER_MODE, &timerCfg); TIM_MATCHCFG_Type timerMatch; timerMatch.MatchChannel = 0; timerMatch.IntOnMatch = TRUE; timerMatch.ResetOnMatch = TRUE; timerMatch.StopOnMatch = FALSE; timerMatch.ExtMatchOutputType = TIM_EXTMATCH_NOTHING; timerMatch.MatchValue = 10-1; TIM_ConfigMatch(LPC_TIM3,&timerMatch); NVIC_EnableIRQ(TIMER3_IRQn); TIM_Cmd(LPC_TIM3,ENABLE); initAPI(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* Timers synchronisation in cascade mode with an external trigger ----- 1/TIM1 is configured as Master Timer: - Toggle Mode is used - The TIM1 Enable event is used as Trigger Output 2/TIM1 is configured as Slave Timer for an external Trigger connected to TIM1 TI2 pin (TIM1 CH2 configured as input pin): - The TIM1 TI2FP2 is used as Trigger Input - Rising edge is used to start and stop the TIM1: Gated Mode. 3/TIM3 is slave for TIM1 and Master for TIM4, - Toggle Mode is used - The ITR1(TIM1) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM1 enable event). - The TIM3 enable event is used as Trigger Output. 4/TIM4 is slave for TIM3, - Toggle Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 enable event). The TIMxCLK is fixed to 72 MHZ, the Prescaler is equal to 2 so the TIMx clock counter is equal to 24 MHz. The Three Timers are running at: TIMx frequency = TIMx clock counter/ 2*(TIMx_Period + 1) = 162.1 KHz. The starts and stops of the TIM1 counters are controlled by the external trigger. The TIM3 starts and stops are controlled by the TIM1, and the TIM4 starts and stops are controlled by the TIM3. -------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseStructure.TIM_Prescaler = 2; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 Input Capture Configuration */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM1, &TIM_ICInitStructure); /* TIM1 Input trigger configuration: External Trigger connected to TI2 */ TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2); TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM1 */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable); /* Slaves Configuration: Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Enable); /* Slave Mode selection: TIM4 */ TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM1, ENABLE); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); while (1) {} }
/*This function initializes the pins that are used in pwm, assigns them to their alternate functions, *and then initializes the TIM(ers) for those pins. For parameters, it takes the frequency of the pwm *and the prescaler for the clock. The frequency will work fine for anything bellow 525000, but it is *not guaranteed to work above that. The prescaler divides into the stm boards own internal clock to *get a clock speed for the timer. The prescaler works good at 1, but it can take any multiple of two *as its input. The function will return the period of the pwm which is used to calculate the duty cycle *when setting the pwm for each pin */ int32_t initialize_timers(uint32_t frequency, uint16_t preScaler) { // Enable TIM3 and GPIOC clocks RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; //structure used by stm in initializing pins. // Configure PC6-PC9 pins as AF, Pull-Down GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //specifies which pins are used GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //assigns the pins to use their alternate functions GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); //initializes the structure // Since each pin has multiple extra functions, this part of the code makes the alternate functions the TIM3 functions. GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3); // Compute prescaler value for timebase uint32_t PrescalerValue = (uint32_t) ((SystemCoreClock /2) / (84000000 / preScaler)) - 1; //To figure out what the numbers do //second value in the divide is the frequency uint32_t PreCalPeriod = ((84000000 * preScaler) / frequency) - 1; //To figure out what the numbers do TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //structure used by stm in initializing the pwm TIM_OCInitTypeDef TIM_OCInitStructure; // Setup timebase for TIM3 TIM_TimeBaseStructure.TIM_Period = PreCalPeriod; //sets the period of the timer TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; //sets the prescaller which is divided into the cpu clock to get a clock speed that is small enough to use for timers TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //initializes this part of the code // Initialize TIM3 for 4 channels TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //sets the time to be pulse width TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC1Init(TIM3, &TIM_OCInitStructure); //initiates this part of the pulse width modulation TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC4Init(TIM3, &TIM_OCInitStructure); // Enable TIM3 peripheral Preload register on CCR1 for 4 channels TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); // Enable TIM3 peripheral Preload register on ARR. TIM_ARRPreloadConfig(TIM3, ENABLE); // Enable TIM3 counter TIM_Cmd(TIM3, ENABLE); return(PreCalPeriod); }
void hold(uint16_t T){ //Timer up to 1 seconds. (currently) TIM5->ARR=T*15000; TIM5->CNT=0; TIM_Cmd(TIM5, ENABLE); }
void SweepRobot_WheelFloatCtrlMoveToDownPos(void) { TIM_SetCompare1(WHEEL_FLOAT_TEST_CTRL_TIM, WHEEL_FLOAT_TEST_STEERING_ENGINE_DOWN_POS); TIM_Cmd(WHEEL_FLOAT_TEST_CTRL_TIM, 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_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* ----------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock. * SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices. For Low-Density Value line and Medium-Density Value line devices, SystemCoreClock is set to 24 MHz. The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to 11/SystemCoreClock ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. ----------------------------------------------------------------------- */ /* Compute the value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); 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_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM1 Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode. 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). In this example TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = HCLK = SystemCoreClock The TIM1 counter clock is equal to SystemCoreClock = 168 Mhz. The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 656 KHz TIM1_Period = (TIM1 counter clock / TIM1 frequency) - 1 = 255 and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running at: (TIM1 frequency)/ ((TIM3 period +1)* (Repetition_Counter+1)) = 43.730 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running at: (TIM1 frequency)/ ((TIM4 period +1)* (Repetition_Counter+1)) = 65.600 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% 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. --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Configures TIM1: channels in PWM mode * @param None * @retval None */ static void TIM_Config(void) { TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* TIM1 channels pin configuration: TIM1_CH1 -> PA8 */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Enable Alternate function on PA8 to be controlled by TIM1 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 100; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 50; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); }
DAC_TIM6Class::DAC_TIM6Class(){ waveBuffer = malloc(sizeof(uint16_t) * WAVE_MEMORY_LENGTH); if(waveBuffer==NULL){ while(1){} } for(int i=0;i<WAVE_MEMORY_LENGTH;i++){ waveBuffer[i] = 2048+1024*sinf(2*M_PI*i/WAVE_MEMORY_LENGTH); } RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); ///////////////////////////////////// //GPIO ///////////////////////////////////// GPIO_InitTypeDef gpioa4_5; GPIO_StructInit(&gpioa4_5); gpioa4_5.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; gpioa4_5.GPIO_Mode = GPIO_Mode_AN; gpioa4_5.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA,&gpioa4_5); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE); ///////////////////////////////////// //DAC ///////////////////////////////////// DAC_InitTypeDef dac1; DAC_StructInit(&dac1); dac1.DAC_LFSRUnmask_TriangleAmplitude =DAC_LFSRUnmask_Bits11_0; dac1.DAC_OutputBuffer = DAC_OutputBuffer_Enable; dac1.DAC_Trigger = DAC_Trigger_T6_TRGO; dac1.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_Init(DAC_Channel_1,&dac1); DAC_SetDualChannelData(DAC_Align_12b_R,0,0); DAC_Cmd(DAC_Channel_1,ENABLE); DAC_DMACmd(DAC_Channel_1,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); TIM_TimeBaseInitTypeDef timebase; timebase.TIM_ClockDivision = TIM_CKD_DIV1; timebase.TIM_CounterMode = TIM_CounterMode_Up; timebase.TIM_Prescaler = 168-1; timebase.TIM_Period = 1; TIM_TimeBaseInit(TIM6,&timebase); TIM6->CR2 = 0x20; //MasterModeSelection TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE); DMA_InitTypeDef dma1_5; DMA_StructInit(&dma1_5); dma1_5.DMA_PeripheralBaseAddr = (uint32_t)&(DAC->DHR12R1); dma1_5.DMA_Memory0BaseAddr = (uint32_t)waveBuffer; dma1_5.DMA_DIR = DMA_DIR_MemoryToPeripheral; dma1_5.DMA_BufferSize = WAVE_MEMORY_LENGTH; dma1_5.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma1_5.DMA_MemoryInc = DMA_MemoryInc_Enable; dma1_5.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma1_5.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dma1_5.DMA_Mode = DMA_Mode_Circular; dma1_5.DMA_Priority = DMA_Priority_VeryHigh; dma1_5.DMA_Channel = DMA_Channel_7; DMA_Init(DMA1_Stream5,&dma1_5); DMA_Cmd(DMA1_Stream5,ENABLE); TIM_Cmd(TIM6,ENABLE); }
void PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM config */ GPIO_InitTypeDef GPIO_InitStructure; /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* LEDs are on GPIOD */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;// | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOD, &GPIO_InitStructure); // GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); // GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); // GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); /* pwm set up */ /* Compute the prescaler value */ uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 52500; TIM_TimeBaseStructure.TIM_Prescaler = 31; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM4 enable counter */ TIM_Cmd(TIM4, ENABLE); TIM4->CCR3 = 0; // set brightness }
int main(void) { NVIC_InitTypeDef NVIC_InitStruct; /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE); LEDS_OFF(); /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles: TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1) TIM3 Frequency = 36 KHz. 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% ----------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 19999; //4999 TIM_TimeBaseStructure.TIM_Prescaler = 8;//17 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = Pulse_value; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, 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(TIM2, ENABLE); TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE ); /* TIM3 enable counter */ TIM_Cmd(TIM2, ENABLE); // NVIC_InitTypeDef NVIC_InitStructure; // // /* Configure one bit for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); ////// //// /* Enable the EXTI9_5 Interrupt */ NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); while (1) {} }
/** * @brief Initialise the stick scanning. * @note Starts the ADC continuous sampling. * @param None * @retval None */ void sticks_init(void) { ADC_InitTypeDef adcInit; DMA_InitTypeDef dmaInit; GPIO_InitTypeDef gpioInit; NVIC_InitTypeDef nvicInit; TIM_TimeBaseInitTypeDef timInit; TIM_OCInitTypeDef timOC; int i; // Enable the ADC and DMA clocks RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); gpioInit.GPIO_Speed = GPIO_Speed_50MHz; gpioInit.GPIO_Pin = 0x7F; gpioInit.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &gpioInit); ADC_DeInit(ADC1); // Setup the ADC init structure ADC_StructInit(&adcInit); adcInit.ADC_ContinuousConvMode = DISABLE; adcInit.ADC_ScanConvMode = ENABLE; adcInit.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; adcInit.ADC_NbrOfChannel = STICK_ADC_CHANNELS; ADC_Init(ADC1, &adcInit); // Setup the regular channel cycle for (i = 0; i < STICK_ADC_CHANNELS; ++i) { ADC_RegularChannelConfig(ADC1, ADC_Channel_0 + i, i + 1, ADC_SampleTime_239Cycles5); } // Enable ADC1 + DMA ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); // Calibrate ADC1 ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)) ; ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)) ; nvicInit.NVIC_IRQChannel = DMA1_Channel1_IRQn; nvicInit.NVIC_IRQChannelSubPriority = 1; nvicInit.NVIC_IRQChannelPreemptionPriority = 1; nvicInit.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvicInit); // DMA Configuration DMA_DeInit(DMA1_Channel1); DMA_StructInit(&dmaInit); dmaInit.DMA_PeripheralBaseAddr = (uint32_t) &ADC1->DR; dmaInit.DMA_MemoryBaseAddr = (uint32_t) &adc_data[0]; dmaInit.DMA_DIR = DMA_DIR_PeripheralSRC; dmaInit.DMA_BufferSize = STICK_ADC_CHANNELS; dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable; dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dmaInit.DMA_Mode = DMA_Mode_Circular; dmaInit.DMA_Priority = DMA_Priority_VeryHigh; dmaInit.DMA_M2M = DMA_M2M_Disable; // Configure and enable the DMA DMA_Init(DMA1_Channel1, &dmaInit); DMA_Cmd(DMA1_Channel1, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // TIM4 OC4 is ADC conversion trigger RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_DeInit(TIM4); /* TIM4 init */ TIM_TimeBaseStructInit(&timInit); timInit.TIM_Period = 20-1; /* 20 ms */ timInit.TIM_Prescaler = SystemCoreClock/1000 - 1; /* 1ms */ timInit.TIM_ClockDivision = 0x0; timInit.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &timInit); /* TIM4 OC4 configuration in PWM mode to generate ADC_ExternalTrigConv_T4_CC4 */ TIM_OCStructInit(&timOC); timOC.TIM_OCMode = TIM_OCMode_PWM1; timOC.TIM_OutputState = TIM_OutputState_Enable; timOC.TIM_Pulse = 1; timOC.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC4Init(TIM4, &timOC); /* TIM2 enable counter */ TIM_Cmd(TIM4, ENABLE); /* enable ADC triggering */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); task_register(TASK_PROCESS_STICKS, sticks_process); task_schedule(TASK_PROCESS_STICKS, 0, 20); }
/** * @brief Configures the used Timers. * @param None * @retval None */ static void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable TIM2, TIM3 and TIM4 clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE); /* TIM2 configuration */ TIM_TimeBaseStructure.TIM_Period = 0x4AF; TIM_TimeBaseStructure.TIM_Prescaler = ((SystemCoreClock/1680) - 1); TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_Pulse = 0x0; TIM_OC1Init(TIM2, &TIM_OCInitStructure); /* TIM3 configuration */ TIM_TimeBaseStructure.TIM_Period = 0x95F; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* TIM4 configuration */ TIM_TimeBaseStructure.TIM_Period = 0xE0F; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Immediate load of TIM2,TIM3 and TIM4 Precaler values */ TIM_PrescalerConfig(TIM2, ((SystemCoreClock/1680) - 1), TIM_PSCReloadMode_Immediate); TIM_PrescalerConfig(TIM3, ((SystemCoreClock/1680) - 1), TIM_PSCReloadMode_Immediate); TIM_PrescalerConfig(TIM4, ((SystemCoreClock/1680) - 1), TIM_PSCReloadMode_Immediate); /* Clear TIM2, TIM3 and TIM4 update pending flags */ TIM_ClearFlag(TIM2, TIM_FLAG_Update); TIM_ClearFlag(TIM3, TIM_FLAG_Update); TIM_ClearFlag(TIM4, TIM_FLAG_Update); /* Configure two bits for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable the TIM2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the TIM3 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_Init(&NVIC_InitStructure); /* Enable the TIM4 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_Init(&NVIC_InitStructure); /* Enable TIM2, TIM3 and TIM4 Update interrupts */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); /* TIM2, TIM3 and TIM4 enable counters */ TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); }
void spindle_init() { // #ifdef VARIABLE_SPINDLE // // // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are // // combined unless configured otherwise. // SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT); // Configure as PWM output pin. // TCCRA_REGISTER = TCCRA_INIT_MASK; // Configure PWM output compare timer // TCCRB_REGISTER = TCCRB_INIT_MASK; // #ifdef CPU_MAP_ATMEGA2560 // OCRA_REGISTER = OCRA_TOP_VALUE; // Set the top value for 16-bit fast PWM mode // SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin. // SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin. // #else // Otherwise 328p // #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN // SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin. // #else // SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin. // #endif // #endif // // #else // // // Configure no variable spindle and only enable pin. // SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin. // SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin. // // #endif #ifdef VARIABLE_SPINDLE //setup to control RC ESC, 20ms period, 0.5-1.5ms pulsewidth RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); #ifdef STANDARD_GRBL GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); //Reset init structure GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructInit( &TIM_TimeBaseStructure ); // Reset init structure TIM_TimeBaseStructure.TIM_Prescaler = 100 - 1; // 100 MHz / 100 = 1 MHz TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms) TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_Pulse = 1000; TIM_OC1Init(TIM3, &TIM_OCInitStructure); #else GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); //Reset init structure GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructInit( &TIM_TimeBaseStructure ); // Reset init structure TIM_TimeBaseStructure.TIM_Prescaler = 100 - 1; // 100 MHz / 100 = 1 MHz TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms) TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_Pulse = 1000; TIM_OC3Init(TIM3, &TIM_OCInitStructure); #endif TIM_Cmd( TIM3, ENABLE ); #else set_as_output(SPINDLE_DIR); set_as_output(SPINDLE_EN); #endif spindle_stop(); }
/*=====================================================================================================*/ void PWM_Config( void ) { GPIO_InitTypeDef GPIO_Struct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); /* TIM2 PWM1 PA1 */ /* TIM2 PWM2 PA2 */ /* TIM2 PWM3 PA3 */ /* TIM3 PWM4 PA6 */ /* TIM3 PWM5 PA7 */ GPIO_Struct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Struct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_Struct); /* TIM3 PWM6 PB0 */ /* TIM3 PWM7 PB1 */ /* TIM4 PWM8 PB6 */ /* TIM4 PWM9 PB7 */ /* TIM4 PWM10 PB8 */ /* TIM4 PWM11 PB9 */ GPIO_Struct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Struct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_Struct); TIM_DeInit(TIM2); TIM_DeInit(TIM3); TIM_DeInit(TIM4); /************************** PWM Output **************************************/ /* 設定 TIM2 TIM3 TIM4 Time Base */ TIM_TimeBaseStruct.TIM_Period = (int16_t)(2500-1); // 週期 = 2.5ms, 400Hz TIM_TimeBaseStruct.TIM_Prescaler = (int16_t)(72-1); // 除頻72 = 1M ( 1us ) TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; // 上數 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct); TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct); /* 設定 TIM2 TIM3 TIM4 OC */ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // 配置為 PWM1 模式 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; // 致能 OC TIM_OCInitStruct.TIM_Pulse = PWM_MOTOR_MIN; // 設置跳變值 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; // 當計數值小於 PWM_MOTOR_MIN 時為高電平 TIM_OC2Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC2 TIM_OC3Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC3 TIM_OC4Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC4 TIM_OC1Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC1 TIM_OC2Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC2 TIM_OC3Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC3 TIM_OC4Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC4 TIM_OC1Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC1 TIM_OC2Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC2 TIM_OC3Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC3 TIM_OC4Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC4 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC2 預裝載 TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC3 預裝載 TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC4 預裝載 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC1 預裝載 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC2 預裝載 TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC3 預裝載 TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC4 預裝載 TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC1 預裝載 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC2 預裝載 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC3 預裝載 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC4 預裝載 /* 啟動 */ TIM_ARRPreloadConfig(TIM2, ENABLE); // 致能 TIM2 重載寄存器ARR TIM_ARRPreloadConfig(TIM3, ENABLE); // 致能 TIM3 重載寄存器ARR TIM_ARRPreloadConfig(TIM4, ENABLE); // 致能 TIM4 重載寄存器ARR TIM_Cmd(TIM2, ENABLE); // 致能 TIM2 TIM_Cmd(TIM3, ENABLE); // 致能 TIM3 TIM_Cmd(TIM4, ENABLE); // 致能 TIM4 }
/** * @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_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------- TIM2 Configuration: Output Compare Timing Mode: TIM2 counter clock at 6 MHz CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz --------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 12000000) - 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(TIM2, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM2, 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(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1); }
/* Инициализация таймера и ШИМ */ extern "C" void hal_TIM2_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure; TIM_OCInitTypeDef TIM_OC_InitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //Initialize clocks for TIM2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Initialize clocks for GPIOA, AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* //Configure pin TIM2 CH1 = PA0 as alternative function push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; */ //GPIO_Init(GPIOA, &GPIO_InitStructure); //Configure TIM2 time base TIM_DeInit(TIM2); TIM_TimeBaseStructInit( &TIM_TimeBase_InitStructure ); TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBase_InitStructure.TIM_Period = 65000; TIM_TimeBase_InitStructure.TIM_Prescaler = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure); TIM_OCStructInit( &TIM_OC_InitStructure ); TIM_OC_InitStructure.TIM_Pulse = 130; TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //TIM_OC1Init(TIM2, &TIM_OC_InitStructure); // Automatic Output enable, Break, dead time and lock configuration TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //TIM_BDTRConfig(TIM2, &TIM_BDTRInitStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* Enable the TIM Update Interrupt */ /* 1 bit for pre-emption priority, 3 bits for subpriority */ NVIC_SetPriorityGrouping(1); /* Enable the TIM2 Interrupt */ NVIC_SetPriority(TIM2_IRQn, 0x01); /* 0x00 = 0x01 << 3 | (0x00 & 0x7*/ NVIC_EnableIRQ(TIM2_IRQn); /* Enable TIM2 interrupt */ TIM_Cmd(TIM2, ENABLE); /* TIM counter enable */ return; }
/* COLLISION TEST GPIO INIT */ void SweepRobot_CollisionTestGPIOInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(COLLISION_FRONT_TEST_CTRL_GPIO_PERIPH_ID, ENABLE); RCC_AHB1PeriphClockCmd(COLLISION_SIDE_TEST_CTRL_GPIO_PERIPH_ID, ENABLE); RCC_APB2PeriphClockCmd(COLLISION_TEST_STEER_MOTOR_CTRL_TIM_PERIPH_ID, ENABLE); GPIO_InitStructure.GPIO_Pin = COLLISION_SIDE_TEST_CTRL_L_PIN |\ COLLISION_SIDE_TEST_CTRL_R_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(COLLISION_SIDE_TEST_CTRL_GPIO, &GPIO_InitStructure); GPIO_WriteBit(COLLISION_SIDE_TEST_CTRL_GPIO, COLLISION_SIDE_TEST_CTRL_L_PIN, Bit_SET); GPIO_WriteBit(COLLISION_SIDE_TEST_CTRL_GPIO, COLLISION_SIDE_TEST_CTRL_R_PIN, Bit_SET); GPIO_InitStructure.GPIO_Pin = COLLISION_FRONT_TEST_CTRL_L_PIN |\ COLLISION_FRONT_TEST_CTRL_R_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(COLLISION_FRONT_TEST_CTRL_GPIO, &GPIO_InitStructure); GPIO_WriteBit(COLLISION_FRONT_TEST_CTRL_GPIO, COLLISION_FRONT_TEST_CTRL_L_PIN, Bit_SET); GPIO_WriteBit(COLLISION_FRONT_TEST_CTRL_GPIO, COLLISION_FRONT_TEST_CTRL_R_PIN, Bit_SET); GPIO_InitStructure.GPIO_Pin = COLLISION_TEST_LEFT_STEER_MOTOR_CTRL_PIN |\ COLLISION_TEST_RIGHT_STEER_MOTOR_CTRL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(COLLISION_TEST_STEER_MOTOR_CTRL_GPIO, &GPIO_InitStructure); GPIO_PinAFConfig(COLLISION_TEST_STEER_MOTOR_CTRL_GPIO, COLLISION_TEST_LEFT_STEER_MOTOR_CTRL_PIN_SOURCE, COLLISION_TEST_STEER_MOTOR_CTRL_GPIO_AF_PPP); GPIO_PinAFConfig(COLLISION_TEST_STEER_MOTOR_CTRL_GPIO, COLLISION_TEST_RIGHT_STEER_MOTOR_CTRL_PIN_SOURCE, COLLISION_TEST_STEER_MOTOR_CTRL_GPIO_AF_PPP); TIM_DeInit(COLLISION_TEST_STEER_MOTOR_CTRL_TIM); TIM_TimeBaseInitStructure.TIM_Period = 20000-1; TIM_TimeBaseInitStructure.TIM_Prescaler = 168-1; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, &TIM_TimeBaseInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC1Init(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, &TIM_OCInitStructure); TIM_OC2Init(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, ENABLE); TIM_SetCompare1(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, COLLISION_TEST_LEFT_STEERING_MOTOR_IDLE_POS); TIM_SetCompare2(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, COLLISION_TEST_RIGHT_STEERING_MOTOR_IDLE_POS); TIM_Cmd(COLLISION_TEST_STEER_MOTOR_CTRL_TIM, ENABLE); }
/** * @brief Configures TIM14 to measure the LSI oscillator frequency. * @param None * @retval None */ static void TIM14_ConfigForLSI(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Enable peripheral clocks ------------------------------------------------*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Allow access to the RTC */ PWR_BackupAccessCmd(ENABLE); /* Reset RTC Domain */ RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE); /*!< LSI Enable */ RCC_LSICmd(ENABLE); /*!< Wait till LSI is ready */ while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} /* Select the RTC Clock Source */ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* Enable the RTC Clock */ RCC_RTCCLKCmd(ENABLE); /* Wait for RTC APB registers synchronisation */ RTC_WaitForSynchro(); /* Enable TIM14 clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); /* Enable the TIM14 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure TIM14 prescaler */ TIM_PrescalerConfig(TIM14, 0, TIM_PSCReloadMode_Immediate); /* Connect internally the TM14_CH1 Input Capture to the LSI clock output */ TIM_RemapConfig(TIM14, TIM14_RTC_CLK); /* TIM14 configuration: Input Capture mode --------------------- The LSI oscillator is connected to TIM14 CH1 The Rising edge is used as active edge, The TIM14 CCR1 is used to compute the frequency value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM14, &TIM_ICInitStructure); /* TIM14 Counter Enable */ TIM_Cmd(TIM14, ENABLE); /* Reset the flags */ TIM14->SR = 0; /* Enable the CC1 Interrupt Request */ TIM_ITConfig(TIM14, TIM_IT_CC1, ENABLE); }
/*=====================================================================================================*/ void PWM_Config( void ) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3); /* TIM2 PWM1 PA0 */ /* TIM2 PWM2 PA1 */ /* TIM2 PWM3 PA2 */ /* TIM2 PWM4 PA3 */ /* TIM3 PWM5 PA7 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStruct); /* TIM3 PWM6 PB0 */ /* TIM3 PWM7 PB1 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStruct); TIM_DeInit(TIM2); TIM_DeInit(TIM3); /************************** PWM Output **************************************/ /* 設定 TIM2 TIM3 Time Base */ TIM_TimeBaseStruct.TIM_Period = (2500-1); // 週期 = 2.5ms, 400kHz TIM_TimeBaseStruct.TIM_Prescaler = (84-1); // 除頻84 = 1M ( 1us ) TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; // 上數 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct); /* 設定 TIM2 TIM3 OC */ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // 配置為 PWM1 模式 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; // 致能 OC TIM_OCInitStruct.TIM_Pulse = PWM_MOTOR_MAX; // 設置跳變值 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; // 當計數值小於 PWM_MOTOR_MIN 時為高電平 TIM_OC1Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC1 TIM_OC2Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC2 TIM_OC3Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC3 TIM_OC4Init(TIM2, &TIM_OCInitStruct); // 初始化 TIM2 OC4 TIM_OC2Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC2 TIM_OC3Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC3 TIM_OC4Init(TIM3, &TIM_OCInitStruct); // 初始化 TIM3 OC4 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC1 預裝載 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC2 預裝載 TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC3 預裝載 TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // 致能 TIM2 OC4 預裝載 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC2 預裝載 TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC3 預裝載 TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); // 致能 TIM3 OC4 預裝載 /* 啟動 */ TIM_ARRPreloadConfig(TIM2, ENABLE); // 致能 TIM2 重載寄存器ARR TIM_ARRPreloadConfig(TIM3, ENABLE); // 致能 TIM3 重載寄存器ARR TIM_Cmd(TIM2, ENABLE); // 致能 TIM2 TIM_Cmd(TIM3, ENABLE); // 致能 TIM3 }