User Tools

Site Tools


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

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
        	}
        }

Motor Control

INDEX

teaching/ie0117/proyectos/2012/i/final/stm32f4-discovery/interrupt.txt · Last modified: 2022/09/20 00:08 (external edit)