Anda di halaman 1dari 9

Periféricos e Interfaces Industriales

Práctica 1:
Periféricos e Interfaces industriales

 ¿Cuántos µs tarda el microcontrolador en ejecutar la instrucción DNJZ


(suponer reloj de 12 MHz)?.

1 1
f = 12 MHz → T = =
f 12 MHz

1
1 ciclo máquina = 12T = = 1µs
1MHz

Como en las hojas de características del microcontrolador especifica que tiene un


periodo de oscilación de 24, poseerá 2 ciclos máquina:

2 ciclos máquina = 2 x 1µs = 2µs

 Calcula el valor del Contador para que el siguiente código genere un retardo de
1/8 s.
retardo:
DJNZ CONTADOR, retardo

Para realizar la “operación” DJNZ tarda 2µs, por tanto en 1/8 s tardará:

1
= 62.500 veces
8x2 µ

 Si utilizamos la siguiente estructura para generar el retardo anterior, indica dos


valores adecuados para ValorCONTH y ValorCONTL:

MOV CONTH,#ValorContH
buclealto:
MOV CONTL,#ValorContL
buclebajo:
DJNZ CONTL,buclebajo
DJNZ CONTH,buclealto

1 registro tiene 8 bits → 28 = 256


→ 216 = 65.536 (nos pasamos)
2 registros tienen 16 bits 

1
Periféricos e Interfaces Industriales

Cogemos un registro entero 


→ ValorContL = 256

62.500
≈ 244 
→ ValorContH = 244
256

También se puede calcular mediante la fórmula:

ValorContH x (2µs + BI + 2µs) = ttotal = 125.000µs

BE (bucle externo)
Donde BI (bucle interno) = 2µs x ValorContL

Por tanto si consideramos que ValorContl = 256, y según la fórmula anterior


obtendremos que ValorContH = 242,24 ≈ 244.

 Dado el montaje conectado al puerto P1, y aprovechando los apartados


anteriores. Realizar un programa en C y otro en ensamblador, que va encendiendo
un LED de izquierda a derecha y de derecha a izquierda de forma que la luz tarde
aproximadamente 1 seg. en recorrer los 8 LEDs del montaje. Realizar la misma
operación de forma que el movimiento del LED encendido se genere a partir de la
interrupción del TIMER0.

74LS373 LEDs
330

P1

LE OE

2
Periféricos e Interfaces Industriales

• Flujograma del programa (sin interrupciones):

Inicio

Cargar
acumulador

Cargar valor
acumulador
a P1

Retardo

Rotar derecha

Cargar valor
a P1

Retardo

SI NO
= 01H

Rotar izquierda

Cargar valor
a P1

Retardo

NO
= 80H

SI

3
Periféricos e Interfaces Industriales

• Programa en ensamblador (sin interrupciones):

.TITLE RECORRIDO DE LEDS. PRACTICA1.ASM

.COMMENT * MOVIMIENTO DE UN LED QUE SE ILUMINA DE


DERECHA A IZQUIERDA CON UN RETARDO. SIN
INTERRUPCIONES.
*

.ORIGIN 0000H
JMP INI

.ORIGIN 0300H ; Comienzo de la rutina INI.

INI: MOV A,#80H ; Escritura del valor deseado en el puerto


MOV P1,A ; y llamada a la rutina RETARD.
CALL RETARD

ET1: RR A ; Rotación hacia la derecha. Permanecer en


MOV P1,A ; esta rutina mientras no se cumpla la
CALL RETARD ; condición deseada.
CJNE A,#01H,ET1

ET2: RL A ; Rotación hacia la izquierda. Se realizar


MOV P1,A ; dicha operación hasta que se cumpla la
CALL RETARD ; condición deseada.
CJNE A,#80H,ET2
JMP ET1 ; De este modo el programa se ejecuta cíclicamente.

RETARD: MOV R1,#F4H ; Inicio de la rutina RETARD.


BUCLEH: MOV R0,#FFH ; Rutina de retardo que es llamada después de cada
BUCLEL: DJNZ R0,BUCLEL ; rotación. Y que mantiene encendido el led el
DJNZ R1,BUCLEH ; intervalo de tiempo que se establezca.
RET

.END

4
Periféricos e Interfaces Industriales

• Programa en C (sin interrupciones):

#include <io51.h>

unsigned char led, a, b, control ;

void retardo() /* Bucle retardo. */


{
for (a = 1; a <= 244; a++)
{
for (b = 1; b <= 250; b++)
{
}
}
}

void rotar() /* Subprograma encargado de los desplazamientos del led. */


{
if (control == 0) /* Desplazamiento hacia la derecha. */
{
led = led >> 1 ;
P1 = led ;
retardo() ;
if (led == 0x01) /* Cuando led valga 0x01 cambia el */
{ /* sentido de rotación. */
control = 1 ;
}
}
if (control == 1) /* Desplazamiento hacia la izquierda. */
{
led = led << 1 ;
P1 = led ;
retardo() ;
if (led == 0x80) /* Cuando led valga 0x80 cambia el */
{ /* sentido de rotación. */
control = 0 ;
}
}
}

void main() /* Programa principal. */


{
control = 0 ;
led = 0x80 ; /* Se inicializa el valor del led con el que se */
P1 = led ; /* comenzar la rotación, y se llevar al puerto. */

5
Periféricos e Interfaces Industriales

for(;;)
{
rotar() ;
}
}

• Flujograma del programa (con interrupciones):

Inicio

Configuración

NA: JMP NA

RUTINA DE ATENCIÓN A LA INTERRUPCIÓN

Recarga valores

Mover leds

Izquierda Derecha
Dirección

SI NO
P1 = 80H SI NO
P1 = 01H

Rotar
Dirección izquierda
Dirección Rotar
derecha

6
Periféricos e Interfaces Industriales

RETI

• Programa en ensamblador (con interrupciones):

.TITLE RECORRIDO DE LEDS. PRACTICA1.ASM

.COMMENT * MOVIMIENTO DE UN LED QUE SE ILUMINA DE


DERECHA A IZQUIERDA CON INTERRUPCIONES
(TIMER0).
*

.ORIGIN 0000H
JMP INI

.ORIGIN 000BH ; Vectorización de la rutina de la interrupción.


JMP TIM0

.ORIGIN 0200H ; Comienzo de la rutina INI.


INI: MOV TMOD,#01H ; Configuración del timer 0 en modo de 16 bits.
MOV IE,#82H
MOV TL0,#DBH
MOV TH0,#0BH
MOV P1,#80H ; Escritura en el puerto del valor deseado.
MOV TCON,#10H ; Se arranca el timer 0.

NA: JMP NA ; Bucle que no hace nada.

; Inicio de la rutina TIMER0.


TIM0: JB PSW.1,IZQ ; Salta a la rutina IZQ si PSW.1=1.

DER: JB P1.0,CAM ; Realiza la rotación hacia la derecha o hacia


MOV A,P1 ; la izquierda según el valor de PSW.1.
RR A ; Cuando se cumple la condición establecida,
MOV P1,A ; cambia el valor de PSW.1 y pasa a rotar llevando
JMP FIN ; la dirección contraria a la que llevaba.

IZQ: JB P1.7,CAM
MOV A,P1
RL A
MOV P1,A
JMP FIN

CAM: CPL PSW.1 ; Si PSW.1=1 pasa a PSW.1=0 y viceversa.

7
Periféricos e Interfaces Industriales

FIN: RETI ; Retorno a la rutina de interrupción.

.END ; Fin de programa.

• Programa en C (con interrupciones):


#include <io51.h>

unsigned char led, control, veces ;

interrupt [0x0B] void timer0() /* Subprograma encargado de la */


{ /* interrupción del timer 0. */
TH0 = 0x0B ; /* Recarga de valores. */
TL0 = 0xDB ;
veces++ ;
if (veces == 2) /* Bucle que se repite dos veces para */
{ /* que cada led permanezca encendido */
if (control == 0) /* 125.000 µs, 62.500 µs por cada repetición. */
{
led = led >> 1 ;
P1 = led ;
if (led == 0x01)
{
control = 1 ;
}
veces = 0 ;
}
else
{
led = led << 1 ;
P1 = led ;
if (led == 0x80)
{
control = 0 ;
}
veces = 0 ;
}
} /* Fin de bucle. */
}
void main() /* Programa principal. */
{
led = 0x80 ;
P1 = led ;
control = 0 ; /* Inicialización de variables. */
veces = 0 ;
TMOD = 0x01 ; /* Configuración del Timer 0. */
IE = 0x82 ;

8
Periféricos e Interfaces Industriales

TH0 = 0x0B ;
TL0 = 0xDB ;
TR0 = 1 ;
for (;;) /* Bucle infinito. */
{
}
}