Writing /var/lib/dokuwiki/data/meta/teaching/ie0117/proyectos/2012/i/final/stm32f4-discovery/interrupt.meta failed
teaching:ie0117:proyectos:2012:i:final:stm32f4-discovery:interrupt
This is an old revision of the document!
Interrupt_handler.c
void exti0_isr(void)//EXTI, or external interruption function, this one would be called if the interruption was generated by external means, in our case, the User Button { exti_reset_request(EXTI0);//resets the EXTI interruption so it can be called again gpio_toggle(GPIOD, GPIO13);//this toggles the orange led on or off upon entering the EXTI interruption if (direction==UP) //this checks if the interruption should increment or decrement the the frequency, i.e the speed of the motor. { if (current_freq < max_sine_freq) //this checks if the speed has reached the upper limit { current_freq+=sine_freq_increment;//then increments the frequency } else{ direction=DOWN; //if top have been reached, changes direction current_freq-=sine_freq_increment;//and then starts decrementing the frequency } } else { if (current_freq > min_sine_freq)//this checks if the speed has reached the lower limit { current_freq-=sine_freq_increment;//then decrement the frequency } else { direction=UP; //if bottom have been reached, then changes direction current_freq+=sine_freq_increment;//and starts incrementing the frequency } } } void tim1_cc_isr (void)//TIM1 CC interruption, (Timer 1, capture and compare interruption) this will be called if the CCR has been reached by the timer { /* Clear the update interrupt flag. */ timer_clear_flag(TIM1, TIM_SR_CC1IF); static float ticks=0.0f; //cicle counter static float //this command lets you declare and initialize a value for a variable that will only be taken in consideration the first time you run your program. //this does not change upon calling this funtion again, this means that the last value for this variable will be the one kept the next time you use this function. duty_a=0.0f, //this inits the duty cicle for the first PWM duty_b=0.0f, //this inits the duty cicle for the second PWM duty_c=0.0f; //this inits the duty cicle for the third PWM float attenuation=attenuation_value; //an attenuation value that let's you have better control over the CCR value, meaning you can change the sinusoidal frecuency faster or slower with the same frecuency change float angle;//angle variable declaration float max_ticks=pwmfreq_f/current_freq; //defines how many PWM cicles we require to generate a sinusoidal wave of certain frecuency angle=2.0f*PI*ticks/max_ticks;//current angle calculation duty_a=sinf(angle);//new duty cycle for the first PWM, that will generate the first Sinusoidal Wave duty_b=sinf(angle+2.0f*PI/3.0f);//new duty cycle for the second PWM, that will generate the second Sinusoidal Wave duty_c=sinf(angle+4.0f*PI/3.0f);//new duty cycle for the third PWM, that will generate the third Sinusoidal Wave if (duty_a < 0.0f)//if my duty is negative, { timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1); //set's my timer mode in comparison mode timer_disable_oc_output(TIM1,TIM_OC1); // then disables the forward channel timer_enable_oc_output (TIM1, TIM_OC1N);// and enables the reverse channel, this will send the current on the reverse direction, then generating oposite voltage, so my lower part of the sinusoidal wave. duty_a=-duty_a;//re-sets the value of mu duty to positive, so my CCR is calculated to a positive value, this prevents errors on the comparison. } else //else if it's positive { timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1); //set's my timer mode in comparison mode timer_enable_oc_output(TIM1, TIM_OC1 ); // then enables the forward channel, to generate positive tension and so my upper side of the sinusoidal wave timer_disable_oc_output (TIM1, TIM_OC1N);// and disables the reverse channel, so there is only one channel enabled at a time } if (duty_b < 0.0f)//same logic as for the duty_a { timer_set_oc_mode(TIM1, TIM_OC2, TIM_OCM_PWM1); timer_disable_oc_output(TIM1, TIM_OC2 ); timer_enable_oc_output (TIM1, TIM_OC2N); duty_b=-duty_b; } else { timer_set_oc_mode(TIM1, TIM_OC2, TIM_OCM_PWM1); timer_enable_oc_output(TIM1, TIM_OC2 ); timer_disable_oc_output (TIM1, TIM_OC2N); } if (duty_c < 0.0f)//same logic as for the duty_a and b { timer_set_oc_mode(TIM1, TIM_OC3, TIM_OCM_PWM1); timer_disable_oc_output(TIM1, TIM_OC3 ); timer_enable_oc_output (TIM1, TIM_OC3N); duty_c=-duty_c; } else { timer_set_oc_mode(TIM1, TIM_OC3, TIM_OCM_PWM1); timer_enable_oc_output(TIM1, TIM_OC3 ); timer_disable_oc_output (TIM1, TIM_OC3N); } /* Set the capture compare value for OC1. */ timer_set_oc_value(TIM1, TIM_OC1, duty_a*attenuation*pwm_period_ARR); /* Set the capture compare value for OC2. */ timer_set_oc_value(TIM1, TIM_OC2, duty_b*attenuation*pwm_period_ARR); /* Set the capture compare value for OC3. */ timer_set_oc_value(TIM1, TIM_OC3, duty_c*attenuation*pwm_period_ARR); if (ticks<max_ticks)//if we haven't finished a period of the sinusoidal wave { ticks+=1.0f;//then we continue counting } else //if we have reached the max value of cicles, then we have succesffully generated one full period of the sinusoidal wave { ticks=0.0f; //then we need to reset the value to start over a new period gpio_toggle(GPIOD, GPIO15);// this will toggle the blue led ON/OFF each time a full sinusoidal period has passed } }
teaching/ie0117/proyectos/2012/i/final/stm32f4-discovery/interrupt.1457364316.txt.gz · Last modified: 2022/09/20 00:08 (external edit)