Download - 4 Flujo de Control
SISTEMAS MICROPROCESADOS
Departamento de Automatización y Control Industrial - DACI
Temario
• Control de Flujo
Se analizara varios ejemplos de control de flujo en C y la forma de codificar en Assembler AVR.
Control de Flujo
Declaración IF Cumple con la condición se ejecuta la declaración; de lo contrario la declaración se omite. Por ejemplo, el siguiente código C.
if (n >= 3) { expr++; n = expr; }
Control de Flujo
Su equivalente en assembler .def n = r16 .def expr = r17 .equ cmp = 3 ... cpi n, cmp ; Compara valor IF: brsh EXEC ; If n <= 3 entonces salta a NEXT rjmp NEXT ; Salta a NEXT si la expresion es falsa EXEC: inc expr ; incrementa expr mov n, expr ; Setea n = expr NEXT: ... ; Continuar con el codigo
Control de Flujo
Declaración IF-ELSE Esto es muy similar a la instrucción IF, excepto que tiene una sentencia else incondicional adicional. Un ejemplo Código C.
if (n == 5) expr++; else n = expr;
Control de Flujo
Su equivalente en assembler .def n = r16 .def expr = r17 .equ cmp = 5 ... cpi n, cmp ; Comparo valor IF: brne ELSE ; Salta a ELSE si la expresion es falsa inc expr ; Ejecuta la declaración IF rjmp NEXT ; Cotinua con el código ELSE: mov n, expr ; Ejecuta la declaración ELSE NEXT: ... ; Continua con el código
Flujos de Control
Declaración IF-ELSEIF-ELSE Esto es simplemente una mezcla anidada de la IF y ELSE IF. Un ejemplo sería C: if (n < 3) expr++; else if (n == 5) n = expr; else n++;
Flujos de Control
Su equivalente en assembler .def n = r16 .def expr = r17 .equ val1 = 3 .equ val2 = 5 ... cpi n, val1 ; Comparar n con val1 IF: brsh ELIF ; If no es n < 3, luego salta ELSEIF inc expr ; Ejecuta condicion if rjmp NEXT ; Salta Next ELIF: cpi n, val2 ; Compara n con val2 brne ELSE ; If no es n == 5, luego salta condicion ELSE mov n, expr ; Ejecuta condicion Execute ELSEIF rjmp NEXT ; Salta Next ELSE: inc n ; Ejecuta condicion ELSE NEXT: ... ; Continua con el codigo
Control de Flujo
Declaración WHILE La sentencia while se utiliza comúnmente para crear bucles repetitivos. De hecho, es común utilizar un bucle infinito. while (n < 10) { sum += n; n++; }
Control de Flujo
Su equivalente en assembler .def n = r16 .def sum = r16 .equ limit = 10 ... WHILE: cpi n, limit ; Compara n con limit brsh NEXT ; Cuando n > limit, salta NEXT add sum, n ; sum += n inc n ; n++ rjmp WHILE ; Salta para compenzar el lazo WHILE NEXT: ... ; Continua el codigo
Control de Flujo
Sentencia DO La sentencia DO puede considerarse una variante de la sentencia while. En lugar de hacer su ensayo en la parte superior del bucle, se hace en la parte inferior. El siguiente es un ejemplo: do { sum += n; n--; } while (n > 0);
Control de Flujo
Su equivalente en assembler .def n = r16 .def sum = r17 .equ limit = 0 ... DO: add sum, n ; sum += n dec n ; n-- brne DO ; si n mayor a zero sigue sumando NEXT: ... ; Continua con el codigo
Control de Flujo
Sentencia FOR
La sentencia FOR, al igual que la sentencia while, se utiliza para ejecutar código de forma iterativa.
for (n = 0; n < 10; n++) sum += n;
Control de Flujo
Su equivalente en assembler .def n = r16 .def sum = r17 .equ max = 10 ... ldi n, max ; Inicializa n al max FOR: add sum, n ; sum += n dec n ; Decrementa n brne FOR ; Repita el lazo si n no es igual a 0 NEXT: ... ; Rest of code
Control de Flujo
Sentencia Switch
La sentencia switch es una sentencia condicional multivía generalizar la instrucción IF-ELSE.
switch (val) { case 1: a_cnt++; break; case 2: case 3: b_cnt++; break; default: c_cnt++; }
Control de Flujo
Su equivalente en assembler .def val = r16 .def a_cnt = r17 .def b_cnt = r18 .def c_cnt = r19 ... SWITCH: ; Comenzamos declaracion SWITCH S_1: cpi val, 1 ; Comparo val con 1 brne S_2 ; Salta a S_2 si val != 1 inc a_cnt ; Ejecuta case 1 rjmp NEXT ; Break switch S_2: cpi val, 2 ; Compara val con 2 brne S_3 ; Salta a S_3 si val != 2 rjmp NEXT ; Break switch S_3: cpi val, 3 ; Compara val con 3 brne DFLT ; Salta a DFLT si val != 3 inc b_cnt ; Ejecuta case 3 rjmp NEXT ; Break switch DFLT: inc c_cnt ; Ejecuta default NEXT: ... ; Resto de codigo
Control de Flujo
EJERCICIO
Ejercicio: Mover 10 datos de memoria flash y enviarlos a memoria SRAM (0x0100)
SOLUCION
.include "m164pdef.inc"
.def Aux=R16
.def Dato=R17
.def temp=r18 .org 0x00 rjmp inicio inicio: ldi Aux,10 ldi temp,0 ldi R26,0x00 ldi R27,0x01 salto: rcall copiar dec Aux brne salto lazo: rjmp lazo
copiar: ldi ZH,high (tabla<<1) ; inicializar el puntero parte alta ldi ZL,low (tabla<<1) ; inicializar el puntero parte baja add ZL,temp lpm Dato,Z inc temp st X+,Dato ret ; tabla de datos tabla: .db 255,10,4,127,63,31,15,7,3,1
DEBER
Ejercicio: Dados 50 datos de memoria flash, ordenar estos datos De menor a mayor en la memoria SRAM a partir de la dirección 0x0100.
Bibliografía
1. Muhammad Ali Mazidi (2011). The avr microcontroller and embedded system.
2. Yago Torroja & Jorge Portilla, “Curso de Microcontroladores”, Escuela Técnica Superior de Ingenieros Industriales, Universidad Politécnica de Madrid
SISTEMAS MICROPROCESADOS
Marco Herrera
Departamento de Automatización y Control Industrial - DACI