• Viernes 8 de Noviembre de 2024, 17:11

Autor Tema:  Programa rotar leds y procedimientos de retardo(con masm 16)  (Leído 3701 veces)

Malik

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Programa rotar leds y procedimientos de retardo(con masm 16)
« en: Domingo 4 de Enero de 2009, 08:34 »
0
Hola!

Estoy tratando de resolver un ejercicio:

tengo que leer unos pulsadores que me dicen la velocidad a la que tengo que rotar unos leds . A ver lo detallo más, tengo esto:

Pulsadores:
D0 -> que si está activo a nivel bajo tengo que aumentar la velocidad con la que rotan los leds
D1 -> que si está activo a nivel bajo tengo que disminuir la velocidad con la que rotan los leds
Están en la 300h

Están conectados al bus de datos del 8086 así
xxxx xxD1D0

Leds:
Conjunto de 8 leds conectados al bus de datos através de su interfaz
Están en la 300h

Estos leds rotarán indefinidamente,  y su velocidad será controlada por los pulsadores

Pues ese es el enunciado.

Entonces, yo me pongo a ver como solucionarlo y la primera pregunta que me viene a la cabeza es: sería conveniente hacer una especie de pseudocódigo en alto nivel y apartir de él traducirlo a instrucciones asm? O la lógica se suele pensar de otra forma mejor a esta?

Yo he pensado algo así:
Código: C
  1.  
  2. leds = 01h
  3. while(1)
  4. {
  5.     Hago retardo
  6.     if (D0 == 0) //d0 pulsado -> aumento velocidad
  7.     {
  8.         if(speed != FFFF) //limite que tendrá mi registro de 16 bits
  9.         {
  10.             speed++
  11.         }
  12.     if (D1 == 0) //d1 pulsado -> decremento velocidad
  13.     {
  14.         if(D1 != 0) //limite de registro de 16 bits
  15.         {
  16.             speed--
  17.         }
  18.     }
  19.    
  20.     Roto leds
  21.     visualizo leds
  22. }
  23.  
  24.  

Es una mezcla de c y de pseudocódigo, jaja, bueno, seguro que se entiende la lógica del programita.

Pasándolo a ensamblador me sale esto:

Código: ASM
  1.  
  2.    .dosseg
  3.     .model small
  4.     .stack 100h
  5.     .code
  6. ;procedimiento de retardo: mantener un led encendido
  7. retardo proc
  8.  
  9.     mov cx, di
  10. bucle:
  11.     loop bucle
  12.  
  13. retardo endp
  14.  
  15. leds        equ 300h ;Dirección E/S de los leds
  16. pulsador    equ 300h ;Dirección E/S de los pulsadores
  17.  
  18. ; di -> speed
  19. ; bl -> Leds on/off
  20. ; ax y dx -> para in/out
  21.  
  22. ini:
  23.     ;le damos a cx una velocidad inicial
  24.     mov di, 10h
  25.     mov bl, 01h
  26. ;inicializo leds
  27.     mov dx, leds
  28.     mov al, bl
  29.     ;Inicializo leds
  30.     out dx, al
  31.    
  32. ln1@ini:
  33.     call retardo
  34.     mov dx, pulsador
  35.     in al, dx
  36.     ;Los pulsadores se activan a nivel bajo, en reposo están a vcc
  37.    
  38.     ;si he pulsado d0 y si di (contador de retardo) no
  39.     ;ha pasado el limite ffffh, entonces incremento velocidad
  40.     test al, 01h
  41.     jnz ln2@ini
  42.    
  43.     cmp di, 0FFFFh
  44.     je ln3@ini
  45.    
  46.     inc di
  47.     jmp ln3@ini
  48. ln2@ini:
  49.     ;Decremento velocidad si he pulsado d1 y no he llegado a 0
  50.     test al, 02h
  51.     jnz ln3@ini
  52.    
  53.     cmp di, 0
  54.     je ln3@ini
  55.    
  56.     dec di
  57.    
  58.     ;Sabiendo la velocidad, puedo rotar y encender led
  59. ln3@ini:
  60.    
  61.     ;roto leds y actualizo su estado
  62.     rol bl, 1
  63.    
  64.     mov dx, leds
  65.     mov al, bl
  66.     out dx, al
  67.    
  68.     jmp ln1@ini ;siguiente iteración bucle infinito
  69. end ini
  70.    
  71.    
  72.    
  73.    
  74.    
  75.  
  76.  

Masm lo ensambla correctamente... probarlo no he podido, quizás haya un simulador que permita simular cosas como esta, si conocéis alguno...

Yo creo que está bien, pero me surgen unas dudas:

Puedo saber el tiempo "exacto" de retardo de la rutina "retardo"? Por ejemplo si cx toma el valor ffh, cuantos segundos está haciendo el bucle loop?

Bueno creo que eso es todo; disculpad la extensión del post pero quería explicar todo bien para facilitaros un poquitín  ^_^

Se agradece cualquier aportación. Muchas gracias!!!

Malik

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: Programa rotar leds y procedimientos de retardo(con masm 16)
« Respuesta #1 en: Martes 6 de Enero de 2009, 08:55 »
0
Uff menudo exitazo de post jaja

Reformulo mi pregunta de otra forma, no vaya a ser que no se haya entendido ni papa en el post anterior  :lol:

Código: ASM
  1.  
  2.     mov cx, 0FFFFh
  3. bucle:  loop bucle
  4.  
  5.  

El loop bucle lo hará FFFFh veces, es decir, 2^16 veces (65.536).

Entonces, si sé el número de ciclos máquina que consume la instrucción mov cx, 0fffh, más los ciclos de loop bucle * 65536, tendré los ciclos máquina totales de ese bucle. si sé la frecuencia de reloj del microprocesador, por ejemplo 4Mhz, tengo que 1 ciclo máquina tarda (si no me he equivocado en las cuentas) 250 ns. Por lo que el número totales de ciclos de esas instrucciones * lo que tarda en ejecutar 1 ciclo tendría el tiempo total

Si no estoy equivocado en lo dicho hasta ahora, tengo dos problemas:
- Como puedo saber los ciclos máquina de cada instrucción. En unos datasheet del 8086, sólo me vienen el formato de instrucción y el número de bytes que ocupan, por lo que no soy capaz de extraer los ciclos con esa información.

-y cuál es la frecuencia de reloj con la que trabajo. Para ensamblar mis programas uso masm de 16 bits. Entonces, tengo que tomar como frecuencia la de mi micro del pc??

Bueno a ver si algún gurú de la materia me arroja un pelín de luz  ;)

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Programa rotar leds y procedimientos de retardo(con masm 16)
« Respuesta #2 en: Miércoles 7 de Enero de 2009, 08:54 »
0
¿Por qué no usas una interrupción de reloj en vez de comerte tanto la cabeza con ciclos y demás? Si lo que quieres en una función del tipo sleep(), utiliza un contador en la interrupción de reloj del sistema.

Salud

Malik

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: Programa rotar leds y procedimientos de retardo(con masm 16)
« Respuesta #3 en: Martes 20 de Enero de 2009, 19:00 »
0
Cita de: "m0skit0"
¿Por qué no usas una interrupción de reloj en vez de comerte tanto la cabeza con ciclos y demás? Si lo que quieres en una función del tipo sleep(), utiliza un contador en la interrupción de reloj del sistema.

Salud
pues porque soy un cabezota jaja. Te haré caso ;)

saludos

Malik

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: Programa rotar leds y procedimientos de retardo(con masm 16)
« Respuesta #4 en: Viernes 23 de Enero de 2009, 06:50 »
0
He hecho este apaño para los retardos. A ver que os parece:

Código: ASM
  1.  
  2.         ...
  3.     ;Interrupción para obtener hora del sistema
  4.     ;En dh carga los segundos
  5.     mov ah, 2ch 
  6.     int 21h
  7.     ;cl segundos iniciales
  8.     mov cl, dh 
  9.    
  10. Bucle:
  11.     int 21h
  12.     ;para evitar restas del tipo 1 - 59
  13.     sub dh, cl
  14.     jns positivo
  15.     add dh, 60
  16.  
  17. positivo:
  18.     ;retardo de 5 segundos
  19.     cmp dh, 5
  20.     jb Bucle
  21. ...
  22.  
  23.  

Se aceptan criticas (constructivas :P ) y mejoras  ^_^

Saludos