Estoy haciendo un robot que puede seguir líneas, evitar obstáculos y seguir flechas. Escribí código para el seguimiento de líneas y de flechas, pero no sé cómo implementar interrupciones con más de dos niveles de prioridad. ¿Alguien puede decirme cómo usar interrupciones para más de dos niveles de prioridad?
Código fuente -
unsigned short current_duty, old_duty, current_duty1, old_duty1;
void InitMain() {
ANSEL = 0; // Configure AN pins as digital
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
PORTA = 255;
TRISA = 255; // configure PORTA pins as input
PORTB = 0; // set PORTB to 0
TRISB = 0; // designate PORTB pins as output
PORTC = 0; // set PORTC to 0
TRISC = 0; // designate PORTC pins as output
PORTD = 0; // set PORTC to 0
TRISD = 0; // designate PORTC pins as output
PWM1_Init(5000); // Initialize PWM1 module at 5KHz
PWM2_Init(5000); // Initialize PWM2 module at 5KHz
}
void main() {
InitMain();
current_duty = 255; // initial value for current_duty
current_duty1 = 255; // initial value for current_duty1
PWM1_Start(); // start PWM1
PWM2_Start(); // start PWM2
PWM1_Set_Duty(current_duty); // Set current duty for PWM1
PWM2_Set_Duty(current_duty1); // Set current duty for PWM2
while (1) { // endless loop
PORTD.F4=1;
PORTD.F5=0;
PORTD.F6=1;
PORTD.F7=0;
if (PORTB.F1==1) { // turn L moter L pwm1
PWM1_Set_Duty(50);
PWM2_Set_Duty(175);
delay_ms(500);
PWM1_Set_Duty(150);
PWM2_Set_Duty(150);
}
if (PORTB.F3==1) { // turn R moter L pwm1
PWM1_Set_Duty(175);
PWM2_Set_Duty(50);
delay_ms(500);
PWM1_Set_Duty(150);
PWM2_Set_Duty(150);
}
if (PORTB.F2==1 && PORTB.F3==1) { // turn R moter L pwm1
PWM1_Set_Duty(175);
PWM2_Set_Duty(25);
delay_ms(500);
PWM1_Set_Duty(150);
PWM2_Set_Duty(150);
}
if (PORTB.F2==1 && PORTB.F1==1) { // turn R moter L pwm1
PWM1_Set_Duty(25);
PWM2_Set_Duty(175);
delay_ms(500);
PWM1_Set_Duty(150);
PWM2_Set_Duty(150);
}
}
}
Esta puede ser una respuesta un poco obvia, pero dado que no hay otras respuestas y el dispositivo es PIC16, creo que la única forma de obtener niveles es usando un bloque de if o declaraciones equivalentes.
Por ejemplo algo como esto:
interrupt()
{
if(A)
{
handle(A);
}
if(B)
{
handle(B);
}
}
Básicamente, dentro de la función de interrupción, que en mikroC tiene que ser void interupt(void)
para interrupciones normales y de alto nivel y void interrupt_low (void)
para interrupciones de bajo nivel en 18F o declaradas usando iv
una palabra clave, coloca una lista que verifica cada indicador de interrupción en el orden que desee. Dentro del si coloca el controlador que maneja la interrupción y borra la bandera y luego pasa a la bandera de red. Desafortunadamente, eso significa que no hay una manera fácil de implementar múltiples niveles de interrupciones.
Un "truco" podría ser verificar los indicadores de interrupción que desea que tengan mayor prioridad dentro de un bloque if de una interrupción de menor prioridad antes de las partes que toman mucho tiempo. Sin embargo, esto conduce a rutinas de servicio de interrupción largas y complicadas.
Por ejemplo
interrupt()
{
if(A)
{
handle(A);
}
if(B)//B takes a long time and several steps
{
init(B);
if(A)
{
handle(A);
}
handle(B);//This takes long time
}
}
Otra forma sería mover el procesamiento de interrupciones del ISR al ciclo principal, si es posible. Cree algunas variables globales (declaradas fuera de cualquier función) y utilícelas como banderas que se establecerán en el ISR y luego se procesarán dentro del bucle principal. En caso de que tenga algunas interrupciones muy críticas que no pueden esperar a que llegue el bucle principal y las procese, puede utilizar el enfoque híbrido. Coloque las rutinas de manejo para las interrupciones más importantes en el ISR y para el resto de las interrupciones use banderas que serán procesadas en el bucle principal. Incluso podría agregar algunos "niveles" más de interrupciones verificando los indicadores establecidos por el ISR para las interrupciones más importantes varias veces en el ciclo principal y para las interrupciones menos importantes solo al principio o al final del ciclo.
Por ejemplo
char a,b,c;
interrupt()
{
if(A)
{
handle(A);
}
if(B)
{
b=1;
clear_B_interrupt_Flag;
}
}
main()
{
while (1)
{
if(b)
{
handle(B);
b=0;
}
}
}
Aquí está el enlace para la documentación de mikroElektronika para interrupciones.
incrustado.kyle
Thulana Vimukti
incrustado.kyle
david tweed