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.
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; }
Su equivalente en assembler .def n = r16 .def expr = r17 .equ cmp = 3 ... cpi n, cmp IF: brsh EXEC rjmp NEXT EXEC: inc expr mov n, expr NEXT: ...
; Compara valor ; If n <= 3 entonces salta a NEXT ; Salta a NEXT si la expresion es falsa ; incrementa expr ; Setea n = expr ; Continuar con el codigo
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;
Su equivalente en assembler .def .def .equ ...
n = r16 expr = r17 cmp = 5
cpi n, cmp IF: brne ELSE inc expr rjmp NEXT ELSE: mov n, expr NEXT: ...
; Comparo valor ; Salta a ELSE si la expresion es falsa ; Ejecuta la declaración IF ; Cotinua con el código ; Ejecuta la declaración ELSE ; Continua con el código
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++;
Su equivalente en assembler .def n = r16 .def expr = r17 .equ val1 = 3 .equ val2 = 5 ... cpi n, val1 IF: brsh ELIF inc expr rjmp NEXT ELIF: cpi n, val2 brne ELSE mov n, expr rjmp NEXT ELSE: inc n NEXT: ...
; Comparar n con val1 ; If no es n < 3, luego salta ELSEIF ; Ejecuta condicion if ; Salta Next ; Compara n con val2 ; If no es n == 5, luego salta condicion ELSE ; Ejecuta condicion Execute ELSEIF ; Salta Next ; Ejecuta condicion ELSE ; Continua con el codigo
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++; }
Su equivalente en assembler .def n = r16 .def sum = r16 .equ limit = 10 ... WHILE: cpi n, limit brsh NEXT add sum, n inc n rjmp WHILE NEXT: ...
; Compara n con limit ; Cuando n > limit, salta NEXT ; sum += n ; n++ ; Salta para compenzar el lazo WHILE ; Continua el codigo
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);
Su equivalente en assembler .def n = r16 .def sum = r17 .equ limit = 0 ... DO: add sum, n dec n brne DO NEXT: ...
; sum += n ; n-; si n mayor a zero sigue sumando ; Continua con el codigo
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;
Su equivalente en assembler .def n = r16 .def sum = r17 .equ max = 10 ... ldi n, max FOR: add sum, n dec n brne FOR NEXT: ...
; Inicializa n al max ; sum += n ; Decrementa n ; Repita el lazo si n no es igual a 0 ; Rest of code
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++; }
Su equivalente en assembler .def val = r16 .def a_cnt = r17 .def b_cnt = r18 .def c_cnt = r19 ... SWITCH: S_1: cpi val, 1 brne S_2 inc a_cnt rjmp NEXT S_2: cpi val, 2 brne S_3 rjmp NEXT S_3: cpi val, 3 brne DFLT inc b_cnt rjmp NEXT DFLT: inc c_cnt NEXT: ...
; Comenzamos declaracion SWITCH ; Comparo val con 1 ; Salta a S_2 si val != 1 ; Ejecuta case 1 ; Break switch ; Compara val con 2 ; Salta a S_3 si val != 2 ; Break switch ; Compara val con 3 ; Salta a DFLT si val != 3 ; Ejecuta case 3 ; Break switch ; Ejecuta default ; Resto de codigo
Ejercicio: Mover 10 datos de memoria flash y enviarlos a memoria SRAM (0x0100)
.include "m164pdef.inc" .def Aux=R16 .def Dato=R17 .def temp=r18
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
.org 0x00 rjmp inicio ret inicio: ldi Aux,10 ldi temp,0 ldi R26,0x00 ldi R27,0x01 salto: rcall copiar dec Aux brne salto lazo: rjmp lazo
; tabla de datos tabla: .db 255,10,4,127,63,31,15,7,3,1
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
Departamento de Automatización y Control Industrial - DACI
[email protected]