TODOPIC
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?
31 de Octubre de 2014, 06:02:41

Ingresar con nombre de usuario, contraseña y duración de la sesión
Buscar:     Búsqueda Avanzada
350522 Mensajes en 39333 Temas por 41078 Usuarios
Último usuario: tomatemacias
* Inicio Ayuda Buscar Calendario Ingresar Registrarse
Buscar en TodoPIC
+  TODOPIC
|-+  Microcontroladores PIC
| |-+  Primeros pasos - Iniciación a los microcontroladores (Moderadores: Veguepic, jfmateos2)
| | |-+  Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] 2 3 4 5 6 7 8 Marcar como favorito Imprimir
Autor Tema: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A  (Leído 362487 veces)
Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« : 05 de Febrero de 2009, 20:18:42 »

Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A


La idea de este tutorial es ayudar a los que recién están empezando, aquí mostraremos como comenzar. Usaremos en primer lugar el microcontrolador PIC16F84A, porque es el que por lo general se usa en la enseñanza. Comenzaremos explicando como esta constituido, los terminales, manejo de corrientes de los puertos, osciladores externos, circuito de reset, memoria de programa y memoria de datos. Luego iremos a lo interesante, que es la programación, nuestros primeros programitas, de los cuales se tratará de explicarlos detalladamente, el funcionamiento y los registros que se usan en cada caso.-


INDICE

El PIC16F84A

Todas las simulaciones hechas en proteus, aqui (Para el PIC16F84A)



El PIC16F628A/648A





 
Herramientas
Software para escribir nuestro código y compilar: MPLAB
Software para simular: Proteus
Una plaquita programadora.
Software para grabar nuestro PIC, se puede usar el WinPic800 o el Icprog

Smile  Aquí dejo un tutorial de como crear un proyecto en MPLAB, compilar y simular. Un programador de PIC sencillo que pueden armar  (Programador JDM – Serial)(circuito, PCB para hacer la plaqueta y una pequeña explicación de cómo grabar con WinPIC800) y un tutorial para crear placas de circuito impreso (PCB) por el método de la plancha --->  Tutoriales


Datasheets

DATASHEET del PIC16F84A
DATASHEET del PIC16F628A/648A



ConfigPIC: Software para realizar el código automáticamente a partir de una interfase de configuración.
« Última modificación: 28 de Agosto de 2009, 22:20:30 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #1 : 05 de Febrero de 2009, 20:20:10 »

Introduccion:

El PIC16F84A esta fabricado en tecnología CMOS, posee memoria FLASH, y consumo bajo de potencia. Está compuesto básicamente de una memoria ROM (1024 palabras de memoria de programa), una memoria RAM (de acceso aleatorio, 68 bytes), líneas de entrada y salida (2 Puertos) y una lógica de control que coordina la interacción de los demás bloques.
Estos micros pertenecen a la gama media y dispones de un set de 35 instrucciones, tipo RISC (Computador con Set de Instrucciones Reducido) pocas pero muy poderosas.-
Algunas funciones especiales que dispone este PIC:
  • Temporizador programable (Timer). Si se quiere medir periodos de tiempo entre eventos, generar temporizaciones o salidas con frecuencia específica, etc.
  • Perro Guardián o Watchdog. Consiste en un temporizador que, cuando se desborda ya pasa por 0, provoca un reset automático, utilizado para sistemas que no tienen control de un supervisor, y al bloquearse el micro se resetea. Si se utiliza el código debe resetearlo antes de que se desborde.
  • Memoria EEPROM de 64 bytes, para guardar datos que no se alteran a pesar de quitar la alimentación.
  • Interrupciones, cuando una señal externa, o una condición interna activa una línea de interrupción, dejando de lado la tarea que esta ejecutando, atiende dicha interrupción y luego continúa con lo que estaba haciendo.
  • Protección ante fallo de alimentación. Se trata de un circuito que resetea al micro cuando el voltaje Vdd es inferior al mínimo.
  • Estado de bajo consumo. Sleep. Si el micro debe esperar mucho tiempo sin hacer nada, posee una instrucción especial, Sleep, que lo pasa al estado de reposo. Al activarse una interrupción se “despierta” y reanuda su trabajo. (Reset externo, desbordamiento de Watchdog, interrupción por RB0, interrupción por cambio de nivel en RB4 a RB7, interrupción por escritura completada en EEPROM)
Veamos el diagrama de pines, para ver como están distribuidos sus pines. Este microcontrolador cuenta con dos puertos configurables como estradas y salidas, y consta de 18 pines los cuales se encuentran asignados de la siguiente manera:

El puerto A tiene solo cinco pines, el pin 3, ósea, RA4/TOCKI puede ser configurado a su vez como entrada/salida o como temporizador/contador. Cuando es salida se comporta como colecto abierto, por lo tanto debemos poner una resistencia Pull-up a Vdd de 1 Kohm. Cuando se configura como entrada, funciona como disparador Schmitt Trigger por lo que puede reconocer señales con un poco de distorsión.
El puerto B tiene 8 pines que pueden ser configurados como entrada/salida. RB0 puede programarse además como entrada de interrupción externa. Los pines RB4 a RB7 pueden programarse para responder a interrupciones por cambio de estado y los pines RB6 y RB7 se corresponden con líneas de entrada de reloj y entrada de datos cuando esta en modo programación.
MCLR/Vpp, es la entrada de reset si esta a nivel bajo, también es habilitador de tensión de programación. Cuando su tensión es Vdd el PIC funciona normalmente.
Vss y Vdd, son los pines de masa y alimentación. La tensión de alimentación esta comprendida entre los 2 y 5.5 Volt.
OSC1/CLKIN y OSC2/CLKOUT, pines de entrada externa de reloj y salida de oscilador a cristal respectivamente.-

Capacidad de corriente de los puertos.
La máxima capacidad de corriente de cada uno de los pines de los puertos en modo sumidero es de 25 mA y modo fuente de 20 mA. La máxima capacidad de corriente total de los puestos es,
Puerto A: Modo sumidero 80 mA; Modo fuente 50 mA.
Puerto B: Modo sumidero 150 mA; Modo fuente 100 mA.

El Oscilador externo.
Es un circuito externo que le indica al microcontrolador la velocidad a la que debe trabajar. Puede utilizar cuatro tipos distintos:
RC, Oscilador con resistencia y condensador (Poco preciso)
XT, Cristal de cuarzo.
HS, Cristal de alta velocidad
LP, Cristal de baja frecuencia y bajo consumo de potencia.
Al  momento de programar un micro se debe especificar que tipo de oscilador se usa.
Internamente la frecuencia del oscilador es dividida por 4, así que si temeos un oscilador de 4 MHz, la frecuencia de trabajo es de 1 MHz, por lo que cada instrucción se ejecuta cada 1 us.
Aquí utilizaremos un cristal XT de 4 MHz que debe ir acompañado de dos condensadores:

Reset.
El PIC 16F84A posee un temporizador interno conectado al pin de reset, que funciona cuando se da alimentación al microcontrolador. Esto hace que al encender el sistema el microcontrolador quede en reset por un tiempo mientras se estabilizan todas las señales del circuito. Para tener control sobre el reset se utiliza el siguiente circuito:
« Última modificación: 22 de Abril de 2009, 15:30:34 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #2 : 05 de Febrero de 2009, 20:20:56 »

Estructura interna del Microcontrolador.
Arquitectura del PIC, existen dos arquitecturas, la clásica de Von Neumann y la arquitectura Harvard, esta ultima es la que usan los PIC’s. Dispone de dos memorias independientes, una que contiene solo instrucciones y la otra solo contiene datos. Ambas disponen de sus respectivos buses de acceso y es posible realizar operaciones de acceso simultáneamente en ambas.

Memoria del programa.
Aquí almacenamos nuestro programa o código que debe ejecutar, en el PIC16F84A es FLASH, es rápida, de bajo consumo y alta capacidad de almacenamiento. Se divide en 2048 posiciones, pero este PIC solo tiene implementadas 1024 posiciones, de 0x00 hasta 0x3FF.

Cuando ocurre un reset, el contador de programa (PC) apunta a la dirección 0x00, y el micro inicia nuevamente. Aquí se debe escribir todo lo relacionado con la iniciación del mismo, por ejemplo configuración de puertos, etc.
Si ocurre una interrupción PC apunta a la dirección 0x04, y aquí debemos escribir el código necesario para atender a dicha interrupción.
Memoria RAM estática.
Donde se encuentran los 24 registros específicos (SFR) y 68 registros de propósito general (GPR). Se halla dividida en 2 Bancos de 128 bytes cada uno.

Algo que se debe tener en cuenta es la pila o Stack, que consta de 8 posiciones, cada posición contiene la dirección y datos de la instrucción que se esta ejecutando, así cuando se ejecuta una llamada call o una interrupción, el PC sabe donde regresar. (Limitar las llamadas anidadas)
« Última modificación: 08 de Febrero de 2009, 01:08:57 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #3 : 05 de Febrero de 2009, 20:22:06 »

Comenzando con la creación de nuestro código:A continuación vamos a desarrollar nuestro primer programa. Considero que se tiene conocimiento del lenguaje Assembler, si no es así se puede leer el tutorial ASM desde cero de este mismo foro.
Este activará un led conectado a RB0 siempre que el interruptor conectado a RA0 este cerrado. Para ello vamos a necesitar el siguiente circuito:

En  RA0 tenemos conectado un pulsador de forma que cuando lo pulsemos se introduzca un cero lógico en el pin y cuando no lo pulsemos se introduzca un uno lógico. Tenemos un Led con su correspondiente resistencia limitadora de corriente en el pin RB0.

Diagrama de Flujo:

Primero que nada debemos especificar con que microcontrolador estamos trabajando, esto lo realizamos es las dos primeras líneas:
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
En el archive P16F84A.inc se encuentran las definiciones de las direcciones de los registros específicos, los bits utilizados en cada registro y los fusibles del micro.

Configuración de fusibles. Hay ciertos aspectos del PIC que han de ser activados o desactivados mediante hardware a la hora de programarlo. Esto quiere decir que no se pueden volver a cambiar  hasta que el chip no se reprograme de nuevo. El PIC16F84A dispone de 4 fuses (los modelos superiores tienen más). Cada fuse activa o desactiva una opción de funcionamiento.
OSC: Este fuse controla el modo de oscilación que usará el PIC para funcionar. Como ya sabemos, el oscilador se puede configurar de 4 maneras distintas, dependiendo de la velocidad y del tipo de circuito oscilador empleado.
WDT: El famoso "perro guardián" del PIC se configura aquí. Esta es una capacidad del microcontrolador de autorresetearse.
PWRT: Si activamos este fuse, lo que conseguimos es que se genere un retardo en la inicialización del microcontrolador.
CP: Activando este fuse tendremos la garantía de que el código que escribamos en el PIC no pueda ser leído por otra persona, para que no nos lo copien, modifiquen, etc. (Code Protection). Esto no impide que el PIC funcione como siempre, ni que no se pueda sobrescribir su contenido
Código
GeSHi (asm):
  1. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

Definición de variables que utilizaremos en nuestro proyecto. En este caso solo definiremos bits, por ejemplo Led y Pulsador.
Para organizar nuestro programa lo estructuraremos de la siguiente manera:
Nivel      Directiva      Operandos   ; Comentarios
Código
GeSHi (asm):
  1. ;**** Definicion de variables ****
  2. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
  3. Pulsador equ 0 ; Definimos Pulsador como el bit 0, en este caso sera para PORTA

Configuración de puertos.
Para la configuración necesitamos los siguientes registros:
STATUS > 0x03; PORTA > 0x05; PORTB > 0x06; TRISA > 0x86 y TRISB > 0x86.
Por defecto los puertos quedan configurados como entradas de datos y si se quiere cambiar hay que configurarlos. Esto se realiza con los registros TRISA y TRISB, teniendo en cuenta que si se asigna un cero (0) a un pin, quedara como salida y si se asigna un uno (1), quedara como entrada.
En nuestro caso se necesita colocar TRISA igual a 11111 (o se puede dejar por default) y TRISB 11111110. Ahora bien, cuando el PIC arranca se encuentra en el Banco 0, TRISA y TRISB se encuentran en el Banco 1, entonces debemos cambiar de Banco. Esto se realiza con el bit RP0 del registro STATUS. Si este se pone un cero a RP0, estaremos en el Banco 0. Si se coloca un uno, estaremos en el Banco 1.
Registro W: es el registro más importante que tiene el microcontrolador y es denominado ACUMULADOR.

 
Código
GeSHi (asm):
  1. ;**** Configuracion de puertos ***
  2. Reset org 0x00 ; Aqui comienza el micro.-
  3. goto inicio ; Salto a inicio de mi programa.-
  4. org 0x05 ; Origen del código de programa.-
  5. Inicio bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  6. movlw b'11111' ; Muevo 11111 a W.-
  7. movwf TRISA ; Cargo en TRISA.-
  8. movlw b'11111110'
  9. movwf TRISB
  10. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  11. bcf PORTB,Led ; Comienza apagado.-

Ya configurado nuestro PIC, vamos a realizar la rutina que ejecutara.
Código
GeSHi (asm):
  1. ;**** Control de Led ****
  2. Bucle btfsc PORTA,Pulsador ; Preguntamos si esta en 0 logico.-
  3. goto Apagar ; Esta a 1 logico, Apagamos Led.-
  4. bsf PORTB,Led ; Esta a 0 logico, Encendemos Led.-
  5. goto Bucle ; Testeamos nuevamente la condicion del Pulsador.-
  6.  
  7. Apagar bcf PORTB,Led ;Apagamos Led.-
  8. goto Bucle ; Testeamos nuevamente la condicion del Pulsador.-
  9.  
  10. end
Aquí solamente en un bucle infinito testeamos continuamente el estado del pulsador, y según su estado se encenderá o apagará el Led.-
 rebotando
« Última modificación: 20 de Junio de 2009, 14:51:09 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #4 : 05 de Febrero de 2009, 20:24:25 »

Programa completo:
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
  7. Pulsador equ 0 ; Definimos Pulsador como el bit 0, en este caso sera para PORTA
  8. ;**** Configuracion de puertos ***
  9. Reset org 0x00 ; Aqui comienza el micro.-
  10. goto Inicio ; Salto a inicio de mi programa.-
  11. org 0x05 ; Origen del codigo de programa.-
  12. Inicio bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  13. movlw b'11111' ; Muevo 11111 a W.-
  14. movwf TRISA ; Cargo en TRISA.-
  15. movlw b'11111110'
  16. movwf TRISB
  17. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  18. bcf PORTB,Led ; Comienza apagado.-
  19. ;**** Control de Led ****
  20. Bucle btfsc PORTA,Pulsador ; Preguntamos si esta en 0 logico.-
  21. goto Apagar ; Esta a 1 logico, Apagamos Led.-
  22. bsf PORTB,Led ; Esta a 0 logico, Encendemos Led.-
  23. goto Bucle ; Testeamos nuevamente la condicion del Pulsador.-
  24.  
  25. Apagar bcf PORTB,Led ;Apagamos Led.-
  26. goto Bucle ;Testeamos nuevamente la condicion del Pulsador.-
  27.  
  28. end

Bueno aquí ya tenemos nuestro programita terminado, solo falta compilarlo y simularlo para detectar errores, esto esta mínimamente explicado en el tutorial del Utilitario MPLAB adjuntado al principio.-
Se adjunta el circuito realizado en Proteus para simulación.-
En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #5 : 05 de Febrero de 2009, 20:26:30 »

Creación de Demoras:

Ciclo de maquina:

Es la unidad básica de tiempo que utiliza el microcontrolador y equivale a 4 ciclos de reloj. Ósea, si tenemos un oscilador de 4 MHz, el ciclo de reloj seria de 250 ns y el ciclo maquina de 1 us.
Las instrucciones del microcontrolador necesitan 1 ciclo maquina excepto algunas excepciones, como son los comandos que incluyen saltos (goto, call, btfss, btfsc, return, etc) que necesitan dos ciclos maquina.

Demoras mediante lazo simple

Código
GeSHi (asm):
  1. Demora_xxus
  2. movlw 0xXX ; Cargamos valor XX que controla duración (1)
  3. movwf Contador ; Iniciamos Contador (1)
  4. Repeticion
  5. Decfsz Contador ; Decrementa contador y si es cero sale  (1 si no sale, 2 si sale)
  6. goto Repeticion ; No es 0, repetimos (2)
  7. return ; Regresamos de la subrutina (2)

Entre paréntesis se muestra el número de ciclos que demora cada instrucción.-
De manera que el número de ciclos de instrucción Tsub consumidos por la rutina, incluyendo los 2 ciclos de la llamada (CALL) serán
Tsub = [2 + 1 + 1 + (0xXX - 1)*(1 + 2) + 2 + 2] ciclos = (3*0xXX + 5) *Tcy
Donde Tcy es la duración en segundos de un ciclo de instrucción. Utilizando un oscilador de 4 MHz la mayor duración posible es de 770 us, con 0xXX = 0xFF.-

Demoras mediante Lazos anidados

Para lograr demoras de mayor duración deben utilizarse lazos anidados, poniendo un lazo de demora dentro de otro.

Código
GeSHi (asm):
  1. Demora_xx
  2. movlw 0xXX ; (1)
  3. movwf Contador1 ; (1)
  4. Repeticion1
  5. movlw 0xYY ; (1)
  6. movwf Contador2 ; (1)
  7. Repeticion2
  8. decfsz Contador2,1 ; (1 si no sale, 2 si sale)
  9. goto Repeticion2 ; (2)
  10. decfsz Contador1,1 ; (1 si no sale, 2 si sale)
  11. goto Repeticion1 ; (2)
  12. return ; (2)

La duración de esta rutina en ciclos de reloj será
Tsub = 2 + 1 + 1 + (0xXX)*[1 + 1 + (0xYY - 1)*(1 + 2) + 2 + 1 + 2] + [1 + 1 + (0xYY - 1)*(1 + 2) + 2 + 2 + 2] ciclos
Lo cual se puede simplificar como sigue
Tsub = [0xXX*((0xYY - 1)*3 + 7) + 5] Tcy
En este caso el máximo que se puede conseguir es de aprox. 196 milisegundos.-
Bueno ahora que se entiende como se realizan las demoras, les adjunto un programita que obtiene el código necesario para una pausa, ingresando el valor de la misma y la frecuencia del oscilador utilizado.-
« Última modificación: 20 de Junio de 2009, 14:55:17 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #6 : 05 de Febrero de 2009, 20:39:57 »

Ejemplo:
En este ejemplo se explicará como calcular demoras. Se hará titilar un led conectado a RB0 siempre que el interruptor conectado a RA0 este cerrado.
Diagrama de Flujo:

Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador1 equ 0x0C ; Seleccionamos posicion en la memoria RAM (GPR) para guardar
  7. ; registro utilizado para demora.-
  8. Contador2 equ 0x0D ; Registro utilizado en demora.-
  9. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
  10. Pulsador equ 0 ; Definimos Pulsador como el bit 0, en este caso sera para PORTA
  11. ;**** Configuracion de puertos ***
  12. Reset org 0x00 ; Aqui comienza el micro.-
  13. goto Inicio ; Salto a inicio de mi programa.-
  14. org 0x05 ; Origen del codigo de programa.-
  15. Inicio bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  16. movlw b'11111' ; Muevo 11111 a W.-
  17. movwf TRISA ; Cargo en TRISA.-
  18. movlw b'11111110'
  19. movwf TRISB
  20. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  21. bcf PORTB,Led ; Comienza apagado.-
  22. ;**** Control de Led ****
  23. Bucle btfsc PORTA,Pulsador ; Preguntamos si esta en 0 logico.-
  24. goto Apagar ; Esta a 1 logico, Apagamos Led.-
  25. bsf PORTB,Led ; Esta a 0 logico, Encendemos Led.-
  26. call Demora_150ms ; Mantenemos prendido 150 milisegundos
  27. bcf PORTB,Led ; Apagamos Led
  28. call Demora_150ms ; Apagamos durante 150 ms, Ya realizamos un titilo.-
  29. goto Bucle ; Testeamos nuevamente la condicion del Pulsador
  30.  
  31. Apagar bcf PORTB,Led ;Apagamos Led.-
  32. goto Bucle ; Testeamos nuevamente la condicion del Pulsador.-
  33. ;**** Demora ****
  34. Demora_150ms
  35. movlw 0xFF ;
  36. movwf Contador1 ; Iniciamos contador1.-
  37. Repeticion1
  38. movlw 0xC3 ;
  39. movwf Contador2 ; Iniciamos contador2
  40. Repeticion2
  41. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  42. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  43. decfsz Contador1,1 ; Decrementa Contador1.-
  44. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  45. return ; Regresa de la subrutina.-
  46.  
  47. end
« Última modificación: 10 de Febrero de 2009, 21:33:09 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #7 : 05 de Febrero de 2009, 20:41:34 »

Creación de Tablas: Control de un Display de 7 Segmentos.
Un Display es una colección de Leds ubicados de forma estratégica. Si se los agrupa uniendo sus cátodos será de CÁTODO COMUN, o bien agrupando sus ánodos, un Display de ANODO COMUN.
Por otro lado estos Leds pueden ser fabricados en forma de Puntos o Segmentos, tal es así que se encuentran Display de 7 segmentos, como los de la imagen:

El programa que realizaremos leerá la cantidad de veces que se activa un pulsador y mostraremos el resultado. Conectaremos el Display en forma directa, es decir conectando el puerto B del micro a los pines del Display, y luego encender cada uno de los segmentos del Display para visualizar el valor correspondiente. Para ello crearemos una tabla que contenga los distintos códigos para el numero que necesitemos visualizar.


Es obvio que con un solo display solamente podremos contar de 0 a 9.

Diagrama de Flujo:
Antes de continuar tratare de explicar algunos registros importantes:
El PC. Direccionamiento del programa: Especifica la dirección de la instrucción que se ejecutará. Consta de 13 bits, con lo que es posible direccionar hasta 8K palabras, pero en el 16F84A solo se implementa 1k.

La parte alta del contador de programa (PCH) no se puede acceder directamente, ella debe cargarse desde los 5 bits más bajos del registro llamado PCLATCH (dirección 0x08).

En la creación de tablas, la posición a leer de la misma se realiza con el control del registro PCL. Este registro es de 8 bits, por lo que direcciona solo 256 posiciones, por ello se debe tener en cuenta la posición de la tabla en la memoria de programa o también controlar los bits mas significativos de PC (Si nuestra  tabla tiene mas de 255 posiciones, si o si debemos manejar estos bits [PCLATCH]).
Para devolver el valor direccionado se utiliza retlw, esta instrucción devuelve un valor en el acumulador al retornar de una subrutina. La creación de la tabla se hará de la siguiente forma:
Código
GeSHi (asm):
  1. Tabla
  2. addwf PCL,f
  3. retlw Valor0
  4. retlw Valor1
  5. retlw Valor2
  6. retlw Valor3
  7.               ;        ....
Donde Valor0, Valor1, Valor2... etc. son los valores que queremos almacenar en la tabla.
La estrategia a seguir para consultar algún valor de la tabla es cargar en el acumulador (W) la dirección de la tabla donde se encuentra el valor que quieres leer y después llamar a la subrutina TABLA (con un CALL).
 Advertencia: la carga de W no puede superar el número de valores de la tabla, sino se estará ejecutando una instrucción errónea provocando un mal funcionamiento del programa.-

Explicado lo necesario pasamos al código del ejemplo:

Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador equ 0x0C ; Registro para almacenar conteo
  7. Contador1 equ 0x0D ; Registro utilizado en demora.-
  8. Contador2 equ 0x0E ; Registro utilizado en demora.-
  9. Pulsador equ 7 ; Definimos Pulsador como el bit 7, en este caso sera para PORTB
  10. ;**** Inicio  del Micro ****
  11. Reset org 0x00 ; Aqui comienza el micro.-
  12. goto Inicio ; Salto a inicio de mi programa.-
  13.  
  14. ;**** Tabla de conversion BCD a 7 Segmentos ****
  15. ; Se coloca al inicio para asegurar ubicacion en Pagina.-
  16. org 0x05 ; Origen del codigo de tabla.-
  17. BCD7SEG: ; retlw b'gfedcba'  para display catodo comun
  18. addwf PCL,1 ; Se incrementa el contador del programa.-
  19. retlw b'0111111' ; 0
  20. retlw b'0000110' ; 1
  21. retlw b'1011011' ; 2
  22. retlw b'1001111' ; 3
  23. retlw b'1100110' ; 4
  24. retlw b'1101101' ; 5
  25. retlw b'1111101' ; 6
  26. retlw b'0000111' ; 7
  27. retlw b'1111111' ; 8
  28. retlw b'1101111' ; 9
  29. clrf Contador ; Si llega 10, se resetea contador
  30. retlw b'0111111' ; 0
  31.  
  32. ;**** Programa principal ****
  33. ;**** Configuración de puertos ****
  34. Inicio bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  35. movlw b'10000000' ; RB7 como entrada y los demas como salida.-
  36. movwf TRISB
  37. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  38. movlw b'0111111' ; Comienza en cero.-
  39. movwf PORTB
  40. clrf Contador
  41. ;**** Testeo de Pulsador ****
  42. Testeo
  43. btfss PORTB,Pulsador ; Testeamos si esta a 1 logico.-
  44. goto Testeo ; No, seguimos testeando.-
  45. call Demora_20ms ; Eliminamos Efecto rebote
  46. btfss PORTB,Pulsador ; Testeamos nuevamente.-
  47. goto Testeo ; Falsa Alarma, seguimos testeando.-
  48. incf Contador,1 ; Se ha pulsado, incrementamos contador.-
  49. movfw Contador ; pasamos contador a W
  50. call BCD7SEG ; Llamamos tabla.-
  51. movwf PORTB ; Cargamos valor recibido por Tabla en PORTB
  52. btfsc PORTB,Pulsador ; Esperamos a que se suelte el pulsador -**-
  53. goto $-1 ; No, PCL - 1, --> btfss PORTA,Pulsador.-
  54. call Demora_20ms ; Eliminamos efecto rebote.-
  55. btfsc PORTB,Pulsador ; Testeamos nuevamente.-
  56. goto $-4 ; No, Falsa alarma, volvemos a testear a que se suelte (**).-
  57. goto Testeo ; Si, Testeamos nuevamente.-
  58. ;**** Demora ****
  59. Demora_20ms
  60. movlw 0xFF ;
  61. movwf Contador1 ; Iniciamos contador1.-
  62. Repeticion1
  63. movlw 0x19 ;
  64. movwf Contador2 ; Iniciamos contador2
  65. Repeticion2
  66. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  67. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  68. decfsz Contador1,1 ; Decrementa Contador1.-
  69. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  70. return ; Regresa de la subrutina.-
  71.  
  72. end

Una manera más cómoda de escribir la tabla de instrucciones RETLW puede lograrse usando la directiva DT (Define Table) del ensamblador, la cual nos permite definir una tabla de datos que será sustituida por una lista de instrucciones RETLW; así, la tabla anterior puede quedar como sigue:
Código
GeSHi (asm):
  1. BCD7SEG: ; retlw b'gfedcba'  para display catodo comun
  2. addwf PCL,1 ; Se incrementa el contador del programa.-
  3. DT 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
  4. clrf Contador
  5. retlw 0x3F

Rutinas de Lectura de una Tabla en Memoria de Programa, sin importar donde esté ubicada
Aquí hay ejemplos de como trabajar para colocar una tabla en cualquier lugar de la memoria de programa.

Control anti rebote:
En el momento de presionar un botón pulsador o cualquier conmutador electromecánico es inevitable que se produzca un pequeño arco eléctrico durante el breve instante en que las placas del contacto se aproximan o se alejan de sus puntos de conexión.

La duración de este depende de la calidad de los switches y la velocidad de accionamiento, pero no dura más de 20 milisegundos.
Se adjunta simulación.-
« Última modificación: 20 de Junio de 2009, 15:11:50 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #8 : 05 de Febrero de 2009, 20:44:07 »

Otra forma de crear una tabla. Direccionamiento Indirecto.-
En la programación de los microcontroladores PIC la mayoría de las instrucciones emplean direccionamiento directo, pero también es posible que operen en un modo de direccionamiento directo. Para el direccionamiento indirecto se emplean dos registros especiales: el FSR y el INDF (este ultimo no es un registro físico). El registro FSR se emplea para “señalar o apuntar” a una dirección de la memoria RAM cuyo contenido puede ser leído o escrito de forma indirecta empleando cualquier instrucción que use como operando al registro INDF.
Esta forma de direccionamiento es particularmente útil cuando se manejan tablas o arreglos de datos.-

Directo vs Indirecto.

 
Código
GeSHi (asm):
  1. ; DIRECTO:
  2. ; Definimos registro en la memoria de datos.-
  3. MyRegistro equ 0x10 ; Ubicado en 0x10.-
  4.  
  5. ; Cargamos dato en el registro.-
  6. movlw 0x8A ;
  7. movwf MyRegistro ; MyRegistro = 0x8a.-
  8. ; Leemos dato del registro.-
  9. movfw MyRegistro ; Movemos el valor que tenga MyRegistro a W.-
  10. movwf PORTB ; Por ejemplo, lo cargamos en PORTB.-
  11.  
  12. ; INDIRECTO:
  13. ; Cargamos dato en el registro.-
  14. movlw 0x10 ;
  15. movwf FSR ; Direccionamos Registro de datos ubicado en 0x10.-
  16. movlw 0x8A ;
  17. movwf INDF ; Cargamos registro direccionado con el valor 0x8A.-
  18.  
  19. ; Leemos dato en el registro.-
  20. movlw 0x10 ;
  21. movwf FSR ; Direccionamos Registro de datos ubicado en 0x10.-
  22. movfw INDF ; Movemos el valor que tenga el registro seleccionado a W.-
  23. movwf PORTB ; Por ejemplo, lo cargamos en PORTB.-

Utilizaremos el direccionamiento Indirecto para crear la tabla de control del Display. Aquí no utilizaremos el pulsador, solo se hará el contador automático de 0 a 9.- Al iniciar el microcontrolador cargaremos el código de 7 Segmentos para controlar el Display en la memoria de Datos con direccionamiento indirecto.
Luego, al realizar el conteo leeremos el código correspondiente almacenado y lo enviaremos al PORTB.-

Aquí utilizamos el registro STATUS nuevamente, pero para control de las operaciones aritméticas. Nosotros guardaremos el código de 7 Segmentos del 0 al 9, en los registros 0x10 a 0x19. Si nuestro contador nos direcciona el registro ubicado en 0x1A, que seria el “10”, lo reseteamos y direccionamos el “0”, ósea registro 0x10. Esto lo hacemos realizando la resta del registro seleccionado y 0x1A, FSR – 0x1A, y si el resultado es cero, reseteamos.
El bit Z (Zero) del registro STATUS, este indica si una operación lógica o aritmética realizada da como resultado cero. También tenemos el bit C (Carry) (0), que en instrucciones aritméticas se activa cuando se presenta un acarreo desde el bit mas significativo del resultado, el bit DC (Digit Carry), que en operaciones aritméticas se activa si ocurre acarreo entre el bit 3 y bit 4.-
Código completo:
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador equ 0x0C ; Seleccionamos posición en la memoria RAM (GPR) para guardar
  7. ; registro utilizado para demora.-
  8. Contador1 equ 0x0D ; Registro utilizado en demora.-
  9. Contador2 equ 0x0E
  10. Pulsador equ 7 ; Definimos Pulsador como el bit 0, en este caso será para PORTA
  11.  
  12.  
  13. Reset
  14. org 0x00 ; Aquí comienza el micro.-
  15. goto Inicio ; Salto a inicio de mi programa.-
  16. ;**** Programa principal ****
  17. ;**** Configuracion de puertos ****
  18. Inicio
  19. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  20. clrf TRISB ; PORTB como salida.-
  21. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  22. call Config_Tabla ; Cargamos registros con Codigo de 7 segmentos.-
  23. movfw INDF ; Leemos codigo de 7 Segmentos para el CERO.-
  24. movwf PORTB ; Mostramos el CERO.-
  25. ;**** Testeo de Pulsador ****
  26. Bucle
  27. call Demora_190ms ; Demora para visualizar Display
  28. incf FSR,1 ; Incrementamos Puntero.-
  29. movlw 0x1A ; Consulamos si se pide codigo para mostrar "10",
  30. subwf FSR,0 ; si es asi reseteamos FSR, apunta a 0x10--> "0".-
  31. btfss STATUS,Z ; Si Z=1 --> 0x1A - FSR = 0.-
  32. goto Muestro_Display ; No, muestro display.-
  33. movlw 0x10 ; Si reseteo puntero.-
  34. movwf FSR ;
  35. Muestro_Display
  36. movfw INDF ; Leo Registro que apunta FSR.-
  37. movwf PORTB ; Lo cargo en PORTB.-
  38. goto Bucle ; Continuo conteo.-
  39.  
  40. ;**** Demora ****
  41. Demora_190ms
  42. movlw 0xFF ;
  43. movwf Contador1 ; Iniciamos contador1.-
  44. Repeticion1
  45. movlw 0xFF ;
  46. movwf Contador2 ; Iniciamos contador2
  47. Repeticion2
  48. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  49. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  50. decfsz Contador1,1 ; Decrementa Contador1.-
  51. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  52. return ; Regresa de la subrutina.-
  53. ;**** Cargamos tabla en memoria ****
  54. Config_Tabla
  55. movlw 0x10 ;
  56. movwf FSR ; Direccionamos el registro 0x10 de la memoria RAM (GPR).-
  57. movlw 0x3F ; Cargamos el codigo para mostrar el CERO.-
  58. movwf INDF ; Lo guardamos donde apunta FSR --> 0x10.-
  59. ;....................
  60. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x11.-
  61. movlw 0x06 ; Cargamos codigo para UNO.-
  62. movwf INDF ; Lo guardamos donde apunta FSR.-
  63. ;....................
  64. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x12.-
  65. movlw 0x5B ; Cargamos codigo para DOS.-
  66. movwf INDF ; Lo guardamos donde apunta FSR.-
  67. ;....................
  68. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x13.-
  69. movlw 0x4F ; Cargamos codigo para TRES.-
  70. movwf INDF ; Lo guardamos donde apunta FSR.-
  71. ;....................
  72. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x14.-
  73. movlw 0x66 ; Cargamos codigo para CUATRO.-
  74. movwf INDF ; Lo guardamos donde apunta FSR.-
  75. ;....................
  76. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x15.-
  77. movlw 0x6D ; Cargamos codigo para CINCO.-
  78. movwf INDF ; Lo guardamos donde apunta FSR.-
  79. ;....................
  80. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x16.-
  81. movlw 0x7D ; Cargamos codigo para SEIS.-
  82. movwf INDF ; Lo guardamos donde apunta FSR.-
  83. ;....................
  84. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x17.-
  85. movlw 0x07 ; Cargamos codigo para SIETE.-
  86. movwf INDF ; Lo guardamos donde apunta FSR.-
  87. ;....................
  88. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x18.-
  89. movlw 0xFF ; Cargamos codigo para OCHO.-
  90. movwf INDF ; Lo guardamos donde apunta FSR.-
  91. ;....................
  92. incf FSR,1 ; Incrementamos FSR, ahora apunta a 0x19.-
  93. movlw 0x6F ; Cargamos codigo para NUEVE.-
  94. movwf INDF ; Lo guardamos donde apunta FSR.-
  95. ;....................
  96. movlw 0x10 ;
  97. movwf FSR ; Direccionamos Registro del CERO.-
  98. return ; Cargado los valores, retornamos.-
  99. ;..................................................................
  100. end
En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #9 : 05 de Febrero de 2009, 20:45:32 »

Control de varios DisplayPara el control de varios display la idea es multiplexar la señal enviada por el microcontrolador, con él administraremos el encendido de cada display y sus segmentos (lo cual se hace por programa).
Para ejemplificar haremos un contador automático de 0 a 999:
El hardware necesario es el siguiente:

Diagramas de Flujo:


Se observa que el Puerto B se utiliza para enviar los datos a mostrar en cada display, mientras que por el Puerto A seleccionas el display que mostrará ese dato. Supongamos que quiero mostrar "231", pues muy fácil, pongo el puerto B en 0000110 (código para el 1), y activo ahora el 3º transistor  por un periodo de tiempo corto, desactivamos este transistor, cargamos el puerto B con 1001111 y activamos el 2º transistor por un tiempito, lo mismo hacemos para mostrar “1”. Repetimos esta misma secuencia mientras se quiera mostrar este valor. La secuencia es tan rápida que el observador no nota el momento en que cambias de display.

Control de conteo:
Para realizar el conteo incrementamos continuamente Unidad, cuando está llega a 10, las reseteamos a 0, e incrementamos en 1 Decena. La misma operación se realiza con Decena, al llegar a 10 se lleva a 0 y se incrementa Centena.-
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Unidad equ 0x0C ; Guardamos conteo unidad
  7. Decena equ 0x0D ;
  8. Centena equ 0x0E ;
  9. Contador1 equ 0x0F ; Registro utilizado en demora.-
  10. Contador2 equ 0x10 ; Registro utilizado en demora.-
  11. Contador equ 0x11 ; Control de Refresco de Display.-
  12.  
  13. MuestroU equ 2 ; Para control del 1º Display
  14. MuestroD equ 1 ; Para control del 2º Display
  15. MuestroC equ 0 ; Para control del 3º Display
  16.  
  17. ;**** Inicio del Micro ****
  18. Reset
  19. org 0x00 ; Aquí comienza el micro.-
  20. goto Inicio ; Salto a inicio de mi programa.-
  21.  
  22. ;**** Tabla de conversion BCD a 7 Segmentos ****
  23. ; Se coloca al inicio para asegurar ubicacion en Pagina.-
  24. org 0x05 ; Origen del código de tabla.-
  25. BCD7SEG ; retlw b'gfedcba'  para display catodo comun
  26. addwf PCL,1 ; Se incrementa el contador del programa.-
  27. DT 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
  28.  
  29. ;**** Programa principal ****
  30. ;**** Configuracion de puertos ****
  31. Inicio
  32. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  33. clrf TRISA ; PORTA como salida
  34. clrf TRISB ; PORTB como salida.-
  35. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  36. clrf PORTA ; Desactivo todos los Displays
  37. clrf Unidad ; Comienza en cero --> 0 0 0.-
  38. clrf Decena
  39. clrf Centena
  40. goto Actualizo_Display ; Esta rutina multiplexa los displays.-
  41. ;**** Testeo de Pulsador ****
  42. Bucle
  43. incf Unidad,1 ; Incremeto Unidad.
  44. movlw d'10' ; Si es 10 reseteo e incremento Decena
  45. subwf Unidad,0 ;
  46. btfss STATUS,Z ;
  47. goto Actualizo_Display ; no es 10
  48. clrf Unidad ; Si, reseteo.-
  49. incf Decena,1 ; Incremento Decena.-
  50. movlw d'10' ; Si Decena = 10, reseteo e incremento Centena
  51. subwf Decena,0 ;
  52. btfss STATUS,Z ;
  53. goto Actualizo_Display ; No es 10.-
  54. clrf Decena ; Si, reseteo.-
  55. incf Centena,1 ; Incremento Centena.-
  56. movlw d'10' ; Si es 10 Reseteo.-
  57. subwf Centena,0
  58. btfss STATUS,Z
  59. goto Actualizo_Display ; No es 10.-
  60. clrf Centena ; Si, reseto
  61. ;**** Se multiplexan los Display ****
  62. Actualizo_Display
  63. movlw d'20' ; Cargo Contador = 20
  64. movwf Contador ; Para repeticiones de visualizacion del mismo valor
  65. ; durante 150 ms.-
  66. Refresco
  67. movfw Unidad ; Obtengo codigo de 7 Segmentos para Unidad.-
  68. call BCD7SEG ;
  69. bcf PORTA,MuestroC ; Apago Display de Centena, Se entiende al mirar rutina.-
  70. movwf PORTB ; Cargo unidad en PORTB.-
  71. bsf PORTA,MuestroU ; Enciendo Display de Unidad.-
  72. call Demora_5ms
  73. movfw Decena ; Obtengo codigo 7 Segmentos para Decena.-
  74. call BCD7SEG
  75. bcf PORTA,MuestroU ; Apago Display de Unidad.-
  76. movwf PORTB ; Cargo PORTB con Decena.-
  77. bsf PORTA,MuestroD ; Enciendo Display de Decena.-
  78. call Demora_5ms
  79. movfw Centena ; Obtengo codigo de 7 Segmentos para Centena.-
  80. call BCD7SEG
  81. bcf PORTA,MuestroD ; Apago Display de Decena.-
  82. movwf PORTB ; Cargo PORTB con Centena.-
  83. bsf PORTA,MuestroC ; Enciendo Display Centena.-
  84. call Demora_5ms
  85. decfsz Contador,1 ; Pregunto si ya se ha repetido 10 veces el ciclo?
  86. goto Refresco ; No, repito.-
  87. goto Bucle ; Si, actualizo cuenta.-
  88. ;**** Demora ****
  89. Demora_5ms
  90. movlw 0xFF ;
  91. movwf Contador1 ; Iniciamos contador1.-
  92. Repeticion1
  93. movlw 0x05 ;
  94. movwf Contador2 ; Iniciamos contador2
  95. Repeticion2
  96. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  97. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  98. decfsz Contador1,1 ; Decrementa Contador1.-
  99. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  100. return ; Regresa de la subrutina.-
  101.  
  102. end

En este ejemplo se mantiene la visualización del mismo valor durante aprox. 300 ms, se puede determinar ya que utilizamos 3 demoras de 5 ms despreciando los ciclos utilizados en los comandos, que son aprox. 30 (30 us). Entonces por ciclo tenemos 15 ms, y por 20 repeticiones, 300 ms.-

Al final de este hilo se ha agregado un ejemplo de control de 3 display con el registro de desplazamiento 74LS164.
Ejemplo
« Última modificación: 20 de Junio de 2009, 15:18:26 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #10 : 05 de Febrero de 2009, 20:46:41 »

Decodificador BCD.

La otra posibilidad es utilizar un decodificador BCD como el 74LS47 o el 74LS249, o el CD4511. Estos integrados disponen de 4 entradas correspondientes a un código binario BCD, y 7 salidas que se conectan a un Display.

Lo importante de este integrado, es que posee 4 pines de entrada y 7 de salida, mas unos cuantos de configuración. El hecho es que, los 4 pines de entrada (A, B, C y D) serán los que reciban el código en binario enviado por el micro. Una vez recibido el dato, el integrado se hará cargo de decodificarlo y enviarlo por los pines de salida (a, b, c, d, e, f y g) para mostrarlo en el display. Lo que nos falta saber, es que dato deberé enviar al decodificador.
DCBAValor que muestra el Display
0000
0
0001
1
0010
2
0011
3
0100
4
0101
5
0110
6
0111
7
1000
8
1001
9
« Última modificación: 20 de Junio de 2009, 16:50:06 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #11 : 05 de Febrero de 2009, 20:47:37 »

INTERRUPCIONESUna de las características más importante de los microcontroladores y que mencionamos al inicio del tutorial, es que tienen la posibilidad de manejar interrupciones. Se trata de un acontecimiento que hace que el micro deje de lado lo que se encuentra realizando, atienda ese suceso y luego regrese y continúe con lo suyo.
Hay dos tipos de interrupciones  posibles, una es mediante una acción externa (es decir por la activación de uno de sus pines), la otra es interna (por ejemplo cuando ocurre el desbordamiento de uno de sus registros)

En el 16F84A hay 4 fuentes de interrupción:
  • Por el pin RB0/INT, que regresa al PIC del modo SLEEP (interrupción externa).
  • Por los pines RB4 a RB7, configurados como entrada y en caso de que alguno de ellos cambie de estado (interrupción externa).
  • Por desbordamiento del registro TMR0, cuando este registro pasa de 255 a 0 en decimal (interrupción interna).
  • Al completar la escritura de la EEPROM de datos (interrupción interna).

Cada fuente de interrupción esta controlada por 2 bits. Un bit local de interrupciones (Terminado en E) de permiso o prohibición de ejecución. Si esta en 0 bloqueará la solicitud de interrupción, y si esta en 1 permitirá la ejecución. Un bit que actúa como señalizador (Terminado en F) el cual es activado (puesto a 1) si se ha producido la interrupción. Además existe 1 bit de control global, el bit GIE (INTCON <7>) el cual si esta desactivado bloquea todas las solicitudes de interrupción.

Lo anterior descrito puede entenderse observando el diagrama lógico de la siguiente figura:


El bit GIE se borra automáticamente cuando se reconoce una interrupción para evitar que se produzca otra mientras se está atendiendo a la primera y al retornar de la interrupción con la instrucción RETFIE, el bit GIE se vuelve a activar poniéndose a 1. En cambio los bits señalizadores o banderas de interrupción deben ser puestos a cero por el tratamiento de la interrupción realizada por el usuario (Programador)
Cuando una interrupción está habilitada (su bit local de habilitación está activado, el bit GIE está activado) y ocurre el evento que la activa, el valor de PC se guarda en la PILA y en éste se carga el 0x04 (único vector de interrupción). Es a partir de esta dirección que se debe colocar el tratamiento de la interrupción, detectando por medio de los bits banderas cual de los eventos ha ocurrido y actuar según sea el caso.

Nota: El único registro que se salva en la PILA es PC, para preservar algún otro registro debe ser el propio programa de atención a la interrupción el que se encargue de salvar su estado al inicio de la rutina y de devolverlos al final del mismo.

Resumiendo, las acciones que se realizan automáticamente el microcontrolador y las que el programador debe tener en cuenta en sus programas son las siguientes:
  • Cuando se activa una posible causa de interrupción, el flag correspondiente se activa. Si el bit de permiso correspondiente está a 1 y el bit de habilitación de todas las interrupciones (GIE) está a 1, se produce la interrupción.
  • Para evitar que se produzca otra interrupción mientras se está atendiendo a otra anterior, el bit GIE se pone a 0.
  • El valor del PC se guarda en la PILA
  • El PC se carga con el valor 0x04, que es el vector de interrupciones
  • El programador, debe comenzar la rutina de atención a la interrupción con un salto a la posición de memoria donde se encuentra el programa, seguidamente se guardan todos los registros que puedan ser modificados por esta, seguidamente si están habilitadas varias vías de interrupción, se debe explorar el valor de las banderas para determinar la causa de la interrupción.
  • Dependiendo de la causa de la interrupción, la rutina de interrupción se bifurca a la subrutina correspondiente.
  • Se deben devolver los valores que tenían los registros antes de producirse la interrupción y se deben borrar por software las banderas que indican las fuentes de las interrupciones, antes del retorno al programa principal.
  • Cuando se llega a la última instrucción de la rutina de interrupción, RETURN, se carga el PC con el valor que se guardó inicialmente en la PILA y el bit GIE se pone automáticamente a 1.

Bits utilizados.
  • INTF para RB0/INT, bit 1 de INTCON, si es 1 ocurrió interrupción externa
  • RBIF para los pines B4 a RB7, bit 0 de INTCON, si es 1 por lo menos un pin cambio de estado
  • T0IF para TMR0, bit 2 de INTCON, si es 1 TMR0 desbordado
  • EEIF para la EEPROM, bit 4 de EECON1, si es 1 se ha completado escritura
  • GIE, bit 7 de INTCON, si es 1 habilita todas las interrupciones
  • EEIE, bit 6 de INTCON, si es 1 se activa interrupciones de periféricos
  • T0IE, bit 5 de INTCON, si es 1 int. TMR0 activada
  • INTE, bit 4 de INTCON, si es 1 int. Externa activada
  • RBIE, bit 3, si es 1 int. Por RB4 a RB7 activada
Todos estos bits al resetearse o iniciarse el micro se encuentran en 0.

Rutina de Servicio de Interrupciones:
Primero debes guardar el contenido del registro W, el problema de mover W a otro registro (haciendo uso de movf) es que esta instrucción corrompe la bandera Z, modificando el registro de STATUS. Según la hoja de datos otorgada por Microchip, en uno de sus apartados recomienda una secuencia de código que permite guardar y restaurar los registros sin modificarlos.

Código
GeSHi (asm):
  1. ;**** Rutina de servicio de Interrupcion ****
  2. ;  Guardado de registro W y STATUS.-
  3. Inicio_ISR
  4. movwf W_Temp ; Copiamos W a un registro Temporario.-
  5. swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
  6. movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
  7. ISR
  8. ; Atendemos la interrupción.-
  9. ; Restauramos los valores de W y STATUS.-
  10. Fin_ISR
  11. swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
  12. movwf STATUS
  13. swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
  14. swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
  15. retfie ; Salimos de interrupción.-

Los registros W_Temp y STATUS_Temp son registros alternativos para guardar temporariamente sus valores correspondientes.-
« Última modificación: 30 de Julio de 2009, 14:43:03 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #12 : 05 de Febrero de 2009, 20:48:27 »

INTERRUPCION POR TMR0El Timer 0 es un contador / temporizador de 8 bits. El registro principal de este módulo es TMR0 (0x01). Este registro se incrementa continuamente a una frecuencia seleccionable manejada por un preescalador y el reloj interno Fosc/4 (modo temporizador) o bien, por un preescalador y una señal externa (modo contador).
En la siguiente figura se muestra un diagrama de bloques de este módulo, en donde se indican los bits que afectan su operación y la manera en que lo hacen.

El modo Temporizador
En el modo temporizador la señal de reloj que controla el incremento del registro TMR0 es la frecuencia Fcy = Fosc/4, la cual puede ser dividida opcionalmente por el preescalador si así se desea. Como se puede ver en la figura anterior, este modo es seleccionado al limpiar el bit T0CS (OPTION_REG<5>). En este modo, el contenido del registro TMR0 se incrementará a la frecuencia Fcy dividida de acuerdo al preescalador, sin embargo, si se realiza una escritura al registro TMR0, su incremento es inhibido por los siguientes dos ciclos de instrucción (Tcy).
El modo Contador
En el modo contador, la señal que controla los incrementos del registro TMR0 es una señal externa que proviene de la patita T0CKI. En la figura anterior se puede ver que este modo se selecciona poniendo el bit T0CS en alto. Se puede seleccionar la transición que provoca los incrementos mediante el bit “Timer0 Source Edge Select“ T0SE (OPTION_REG<4>), limpiando este bit se selecciona la transición de subida, mientras que al ponerlo en alto se selecciona la de bajada.
Observación: En este modo, la señal conectada a TOCKI es muestreada durante los ciclos Q2 y Q4 del reloj interno, por ello es necesario que permanezca en alto al menos por 2 Tosc más un pequeño retardo de 20nseg y lo mismo en bajo. (Es decir, señales demasiado estrechas (rápidas) no podrán ser detectadas).
El preescalador
El preescalador es un divisor de frecuencia de módulo seleccionable. Como se puede ver en la figura anterior, el preescalador está compartido entre el timer0 y el módulo Watchdog, sin embargo sólo puede conectarse a uno de los dos y esto se establece mediante el bit PSA (OPTION_REG<3>), así, con este bit en alto el preescalador es asignado al reloj del Watchdog, mientras que con un nivel bajo en PSA el preescalador dividirá la frecuencia que maneja al Timer 0.
La selección del módulo (valor de división de frecuencia) del preescalador se puede realizar mediante los bits PS2,PS1,PS0 (OPTION_REG<2:0>) de acuerdo a la siguiente tabla:
PS2 PS1 PS0Divisor
0001/2
0011/4
0101/8
0111/16
1001/32
1011/64
1101/128
1111/256

NOTA: Si se necesita el timer en 1:1 solo hay que asociar el preescaler al Watchdog.
« Última modificación: 17 de Mayo de 2009, 16:00:53 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #13 : 05 de Febrero de 2009, 20:49:53 »

Ejemplo modo temporizador.
Para calcular una temporización se necesita el tiempo de un ciclo de instrucción (es decir 1 microsegundo, si estas trabajando con un XT de 4 Mhz), el valor del Divisor de Frecuencia (el que seleccionabas con los bits PS2, PS1 y PS0), y finalmente el complemento del valor cargado en TMR0 (es decir 255-TMR0). Entonces tenemos: Temporización = Ciclo de instrucción. (256-TMR0) .Divisor de Frecuencia
De este modo si queremos temporizar 4 ms con un divisor de frecuencia de 32, tendríamos:



Vemos que la máxima temporización posible es con TMR0 = 0, y Divisor de Frecuencia en 256, lográndose unos 65.5 ms aprox.

Para ejemplificar el uso de esta interrupción haremos titilar un led conectado al PIN RB0 cada 200 ms, para ello haremos una temporización con TMR0 de 50ms y contaremos 4 desbordes del mismo para lograr los 200 ms necesarios. Lo interesante de usar interrupción es que con el micro se puede estar ejecutando cualquier tarea y no ocupar este tiempo en un bucle de demora. El hardware necesario es equivalente al primer ejemplo realizado.-
Diagrama de Flujo:
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador equ 0x0C ; Contador para detectar 4 desbordes de TMR0.-
  7. W_Temp equ 0x0D ; Registro para guardar temporalmente W.-
  8. STATUS_Temp equ 0x0E ; Registro para guardar temporalmente STATUS
  9.  
  10. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
  11.  
  12. ;**** Inicio del Micro ****
  13. Reset
  14. org 0x00 ; Aquí comienza el micro.-
  15. goto Inicio ; Salto a inicio de mi programa.-
  16. ;**** Vector de Interrupcion ****
  17. org 0x04 ; Atiendo Interrupcion.-
  18. goto Inicio_ISR
  19.  
  20. ; **** Programa Principal ****
  21. ;**** Configuracion de puertos ***
  22. org 0x05 ; Origen del código de programa.-
  23. Inicio
  24. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  25. movlw b'11111110' ; RB0 como salida.-
  26. movwf TRISB
  27. movlw b'00000111' ; Se selecciona TMR0 modo temporizador y preescaler de 1/256.-
  28. movwf OPTION_REG
  29. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  30. bcf PORTB,Led ; El Led comienza apagado.-
  31. movlw 0x3D ; Cargamos 61 en TMR0 para lograr aprox. 50ms.-
  32. movwf TMR0
  33. clrf Contador ; Iniciamos contador.-
  34. movlw b'10100000' ; Habilitamos GIE y T0IE (interrupción del TMR0)
  35. movwf INTCON
  36. ;**** Bucle ****
  37. Bucle
  38. nop ; Aqui el micro puede ejecutar cualquier otra tarea
  39. goto Bucle ; sin necesidad de utilizar tiempo en un bucle de demora.-
  40.  
  41.  
  42. ;**** Rutina de servicio de Interrupcion ****
  43.  
  44. ;---> Aqui haremos copia de respaldo para mostrar como se hace aunque no es
  45. ; necesario ya que el micro no hace otra tarea mientras tanto <---
  46.  
  47. ;  Guardado de registro W y STATUS.-
  48. Inicio_ISR
  49. movwf W_Temp ; Copiamos W a un registro Temporario.-
  50. swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
  51. movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
  52. ;**** Interrupcion por TMR0 ****
  53. ISR
  54. btfss INTCON,T0IF ; Consultamos si es por TMR0.-
  55. goto Fin_ISR ; No, entonces restauramos valores.-
  56. incf Contador ; Si, Incrementamos contador
  57. movlw 0x04 ; Consultamos si se han producido 4 desbordes
  58. subwf Contador,0 ; para obtener 200 ms.-
  59. btfss STATUS,Z ;
  60. goto Actualizo_TMR0 ; No, cargo TMR0 si salgo.-
  61. clrf Contador ; Si, reseteo Contador y controlo Led.-
  62. btfss PORTB,Led ; Si esta apagado, prendo y viseversa.-
  63. goto Prendo_led
  64. bcf PORTB,Led ; Apago Led.-
  65. Actualizo_TMR0 ; Actualizo TMR0 para obtener una temporizacion de 50 ms.-
  66. movlw 0x3D ; d'61'
  67. movwf TMR0
  68. bcf INTCON,T0IF ; Borro bandera de control de Interrupcion.-
  69. goto Fin_ISR ; Restauro valores.-
  70. Prendo_led
  71. bsf PORTB,Led ; prendo Led.-
  72. goto Actualizo_TMR0
  73. ; Restauramos los valores de W y STATUS.-
  74. Fin_ISR
  75. swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
  76. movwf STATUS
  77. swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
  78. swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
  79. retfie ; Salimos de interrupción.-
  80. ;..........................................
  81.  
  82. end



Una ayuda adicional Wink
El programita presentado en el primer post, tiene una utilidad que nos ayudará en el cálculo del preescaler y valor inicial del Timer para obtener una temporización deseada, aparte de generar el código.
« Última modificación: 10 de Julio de 2009, 19:01:20 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #14 : 05 de Febrero de 2009, 20:51:00 »

Ejemplo modo contador.

El siguiente programa realiza el conteo del número de veces que produce una transición de bajo a alto en la patita T0CKI. El valor del contador se incrementará una vez por cada dos transiciones, y al detectarse 10 cambiamos el estado del Led conectado a RB0.

Diagrama de Flujo:

 
Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador equ 0x0C ; Contador para detectar 4 desbordes de TMR0.-
  7. W_Temp equ 0x0D ; Registro para guardar temporalmente W.-
  8. STATUS_Temp equ 0x0E ; Registro para guardar temporalmete STATUS
  9.  
  10. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
  11.  
  12. ;**** Inicio del Micro ****
  13. Reset
  14. org 0x00 ; Aquí comienza el micro.-
  15. goto Inicio ; Salto a inicio de mi programa.-
  16. ;**** Vector de Interrupcion ****
  17. org 0x04 ; Atiendo Interrupcion.-
  18. goto Inicio_ISR
  19.  
  20. ; **** Programa Principal ****
  21. ;**** Configuracion de puertos ***
  22. org 0x05 ; Origen del código de programa.-
  23. Inicio
  24. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  25. movlw b'11111110' ; RB0 como salida.-
  26. movwf TRISB
  27. movlw b'00100000' ; Se selecciona TMR0 modo Contador, transicion positiva  
  28. movwf OPTION_REG ; y preescaler de 1/2.-
  29. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  30. bcf PORTB,Led ; El Led comienza apagado.-
  31. movlw 0xFB ; Cargamos 251 en TMR0 para contar 10 pulsos en RA4/TOCKI.-
  32. movwf TMR0
  33. movlw b'10100000' ; Habilitamos GIE y T0IE (interrupción del TMR0)
  34. movwf INTCON
  35. ;**** Bucle ****
  36. Bucle
  37. nop ; Aqui el micro puede ejecutar cualquier otra tarea
  38. goto Bucle ; sin necesidad de utilizar tiempo en un bucle de demora.-
  39.  
  40.  
  41.  
  42.  
  43. ;**** Rutina de servicio de Interrupcion ****
  44.  
  45. ;---> Aqui haremos copia de respaldo para mostrar como se hace aunque no es
  46. ; necesario ya que el micro no hace otra tarea mientras tanto <---
  47.  
  48. ;  Guardado de registro W y STATUS.-
  49. Inicio_ISR
  50. movwf W_Temp ; Copiamos W a un registro Temporario.-
  51. swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
  52. movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
  53. ;**** Interrupcion por TMR0 ****
  54. ISR
  55. btfss INTCON,T0IF ; Consultamos si es por TMR0.-
  56. goto Fin_ISR ; No, entonces restauramos valores.-
  57. btfss PORTB,Led ; Si, Controlamos Led.Si esta apagado, prendo y viseversa.-
  58. goto Prendo_led
  59. bcf PORTB,Led ; Apago Led.-
  60. Actualizo_TMR0 ; Cargamos 251 en TMR0 para contar 10 pulsos en RA4/TOCKI.-
  61. movlw 0xFB ; d'251'
  62. movwf TMR0
  63. bcf INTCON,T0IF ; Borro bandera de control de Interrupcion.-
  64. goto Fin_ISR ; Restauro valores.-
  65. Prendo_led
  66. bsf PORTB,Led ; prendo Led.-
  67. goto Actualizo_TMR0
  68. ; Restauramos los valores de W y STATUS.-
  69. Fin_ISR
  70. swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
  71. movwf STATUS
  72. swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
  73. swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
  74. retfie ; Salimos de interrupción.-
  75. ;..........................................
  76.  
  77. end
« Última modificación: 10 de Febrero de 2009, 21:42:40 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #15 : 05 de Febrero de 2009, 20:52:09 »

INTERRUPCION EXTERNA, RB0/INT
Para el control de la interrupción externa se necesitan dos bits más, ellos son RPBU (OPTION_REG<7>), que activa o desactiva las resistencias Pull-Up internas del PORTB, en caso de que el dispositivo conectado al puerto sea de colector abierto y el más importante INTEDG (OPTION_REG<6>), si esta en 1, la interrupción se genera por flanco ascendente, y en 0, la interrupción se genera por flanco descendente.-
Para mostrar su uso haremos un ejemplo sencillo que muestre como se configura, el cual al presionar un pulsador conectado a RB0 cambiará el estado de un led conectado a RB1, para ello configuramos que la interrupción de genere por flanco ascendente:
Diagrama de Flujo:

Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. Contador1 equ 0x0C
  7. Contador2 equ 0x0D
  8.  
  9. Pulsador equ 0 ; pin RB0
  10. Led equ 1 ; pin RB1
  11.  
  12. ;**** Inicio del Micro ****
  13. Reset
  14. org 0x00 ; Aqui comienza el micro.-
  15. goto Inicio ; Salto a inicio de mi programa.-
  16. ;**** Vector de Interrupcion ****
  17. org 0x04 ; Atiendo Interrupcion.-
  18. goto ISR
  19.  
  20. ; **** Programa Principal ****
  21. ;**** Configuracion de puertos ***
  22. org 0x05 ; Origen del codigo de programa.-
  23. Inicio
  24. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  25. movlw b'11111101' ; RB0 como entrada y RB1 como salida.-
  26. movwf TRISB
  27. movlw b'01000000' ; Config. Por flanco Ascendente.-
  28. movwf OPTION_REG
  29. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  30. bcf PORTB,Led ; El Led comienza apagado.-
  31. movlw b'10010000' ; Habilitamos GIE y INTE (interrupción por RB0)
  32. movwf INTCON
  33. ;**** Bucle infinito ****
  34. Bucle
  35. nop ;
  36. goto Bucle ;
  37.  
  38. ;.............................................
  39. ;**** Rutina de servicio de Interrupcion ****
  40. ;**** Interrupcion por RB0 ****
  41. ISR
  42. btfss INTCON,INTF ; Consultamos si es por RB0.-
  43. retfie ; No, Salimos de interrupción.-
  44. call Demora_20ms ; Comprueba si es rebote.-
  45. btfss PORTB,Pulsador
  46. goto Fin_ISR ; Es rebote, entonces salimos.-
  47. btfss PORTB,Led ; Si esta prendido, lo apagamos.-
  48. goto Prender_Led
  49. bcf PORTB,Led ; Apagamos Led
  50. goto Fin_ISR
  51. Prender_Led
  52. bsf PORTB,Led ; Encendemos Led
  53. Fin_ISR
  54. bcf INTCON,INTF ; Limpiamos bandera.-
  55. retfie ; Salimos de interrupción.-
  56. ;..........................................
  57. ;**** Demora ****
  58. Demora_20ms
  59. movlw 0xFF ;
  60. movwf Contador1 ; Iniciamos contador1.-
  61. Repeticion1
  62. movlw 0x19 ;
  63. movwf Contador2 ; Iniciamos contador2
  64. Repeticion2
  65. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  66. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  67. decfsz Contador1,1 ; Decrementa Contador1.-
  68. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  69. return ; Regresa de la subrutina.-
  70.  
  71. end
« Última modificación: 20 de Abril de 2009, 17:15:20 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #16 : 05 de Febrero de 2009, 20:54:45 »

INTERRUPCION EXTERNA, RB4 a RB7
Aprovecharemos esta interrupción para detectar cuando se ha presionado una tecla de un Teclado Matricial. Un teclado matricial es un simple arreglo de botones conectados en filas y columnas, de modo que se pueden leer varios botones con el mínimo número de pines requeridos. Un teclado matricial 4×3 solamente ocupa 4 líneas de un puerto para las filas y otras 3 líneas para las columnas, de este modo se pueden leer 12 teclas utilizando solamente 7 líneas de un microcontrolador.
Para detectar la tecla presionada se utilizara el siguiente hardware:

Configuraremos RB0 a RB3 como salida y las colocaremos a nivel bajo. RB4 y RB7 configuradas como entradas, y en estado normal (sin presión de teclas) estarán a nivel alto. Al presionar una tecla se conecta una fila con una columna, se produce un cambio de nivel en alguna de las columnas (De nivel alto a bajo), y se genera la interrupción. Para detectar que tecla se ha presionado, se colocan RB0 a RB3 a nivel alto, y se pasan a nivel bajo de a una por vez, detectando si se produce algún cambio en las columnas.

Se utiliza una variable que se incrementa con la cuenta de las teclas revisadas, de este modo al detectar una pulsación el valor de la cuenta será el valor de la tecla presionada. Si al final no se presionó ninguna tecla la variable se pone a cero y la cuenta vuelve a comenzar.

En nuestro ejemplo representaremos la tecla presionada en forma binaria con leds conectados al puerto A.
Diagrama de Flujo:

Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;**** Definicion de variables ****
  6. NTecla equ 0x0C ; Seleccionamos posición en la memoria RAM (GPR) para guardar
  7. W_Temp equ 0x0D ; Registro para guardar temporalmente W.-
  8. STATUS_Temp equ 0x0E ; Registro para guardar temporalmete STATUS
  9.  
  10.  
  11.  
  12. ;**** Inicio del Micro ****
  13. Reset
  14. org 0x00 ; Aquí comienza el micro.-
  15. goto Inicio ; Salto a inicio de mi programa.-
  16. ;**** Vector de Interrupcion ****
  17. org 0x04 ; Atiendo Interrupcion.-
  18. goto Inicio_ISR
  19. ;**** Programa principal ****
  20. ;**** Configuracion de puertos ****
  21. Inicio
  22. bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
  23. clrf TRISA ; PORTA como Salida.-
  24. movlw b'11110000' ; Nible bajo como Salida y Nible alto como Entrada.-
  25. movwf TRISB
  26. bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
  27. clrf PORTB
  28. bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
  29. movlw b'10001000' ; Habilitamos GIE y RBIE (interrupción RB4 a RB7)
  30. movwf INTCON
  31. clrf NTecla
  32. ;**** Bucle ****
  33. Bucle
  34. nop
  35. goto Bucle
  36. ;**** Rutina de servicio de Interrupcion ****
  37.  
  38. ;---> Aqui haremos copia de respaldo para mostrar como se hace aunque no es
  39. ; necesario ya que el micro no hace otra tarea mientras tanto <---
  40.  
  41. ;  Guardado de registro W y STATUS.-
  42. Inicio_ISR
  43. movwf W_Temp ; Copiamos W a un registro Temporario.-
  44. swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
  45. movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
  46. ;**** Interrupcion por TMR0 ****
  47. ISR
  48. btfss INTCON,RBIF ; Consultamos si es por RB4 a RB7.-
  49. goto Fin_ISR ; No, entonces restauramos valores.-
  50. call Tecla_Presionada ; Se detecta que tecla fue presionada
  51. movfw NTecla
  52. movwf PORTA ; Mostarmos en diplay tecla Presionada.-
  53. ; Restauramos los valores de W y STATUS.-
  54. Fin_ISR
  55. swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
  56. movwf STATUS
  57. swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
  58. swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
  59. retfie ; Salimos de interrupción.-
  60.  
  61.  
  62. ;**** Rutinas *****
  63. ; Rastreamos Tecla presionada.-
  64. Tecla_Presionada
  65. clrf NTecla          ; Borra Numero de Tecla y
  66. incf NTecla,1        ; prepara NTecla para primer codigo.
  67. movlw b'00001110'     ; Saca 0 a la primera fila
  68. movwf PORTB           ; de la Puerta B
  69. nop                     ; Para estabilizacion de señal.  
  70. Test_Columnas        
  71. btfss PORTB,4         ; Primera columna = 0        
  72. goto Suelta_tecla    ; Sale si se ha pulsado tecla.
  73. incf NTecla,1        ; Si no tecla pulsada, incrementa nº tecla.
  74. btfss PORTB,5         ; Segunda columna = 0
  75. goto Suelta_tecla    ; Sale si se ha pulsado tecla.
  76. incf NTecla,1        ; Si no tecla pulsada, incrementa nº tecla.
  77. btfss PORTB,6         ; Tercera columna = 0
  78. goto Suelta_tecla    ; Sale si se ha pulsado tecla.
  79. incf NTecla,1        ; Si no tecla pulsada, incrementa nº tecla.
  80. ; En este caso no se Usa teclado 3x4.-
  81. ; btfss PORTB,7         ; Cuarta columna = 0
  82. ; goto Suelta_tecla    ; Sale si se ha pulsado tecla.
  83. ; incf NTecla,1        ; Si no tecla pulsada,incrementa nº Tecla.
  84.                            
  85. Ultima_tecla    
  86. btfss PORTB,3 ; Ya se revisaron todas las filas?
  87. goto Null_tecla ; Si, Falsa alarma, no se ha presionado ninguna.-
  88. bsf STATUS,C        ; No, seguimos con la siguiente.Pone a 1 Bit C    
  89. rlf PORTB,1     ; asi la Fila 1 pasa a 1 con la rotaci¢n a izqda.
  90. goto Test_Columnas                                            
  91.                                                            
  92. Null_tecla        
  93. clrf NTecla          ; Coloca variable Tecla a 0 (Ninguna)
  94. bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
  95. clrf PORTB ; Dejamos Puerto para recibir otra tecla.-
  96. return                  ; y regresa.        
  97.                                                            
  98. Suelta_tecla
  99. ; Ahora se espera a que la tecla sea soltada para evitar rebotes
  100. ; y reactivaciones de tecla
  101. Espera1        
  102. btfss PORTB,4         ; Si no se suelta la tecla FILA 1
  103. goto Espera1         ; vuelve a esperar.
  104. Espera2        
  105. btfss PORTB,5         ; Si no se suelta la tecla FILA 2
  106. goto Espera2         ; vuelve a esperar.
  107. Espera3
  108. btfss PORTB,6         ; Si no se suelta la tecla FILA 3
  109. goto Espera3         ; vuelve a esperar.              
  110. Espera4
  111. btfss PORTB,7         ; Si no se suelta la tecla FILA 4
  112. goto Espera4         ; vuelve a esperar.          
  113.  
  114. bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-  
  115. clrf PORTB ; Dejamos Puerto para recibir otra tecla.-              
  116. return       ; vuelve al programa principal que hizo la llamada.
  117. ;..........................................
  118. end

También con la variable NTecla (Numero de Tecla presionada) se puede utilizar como entrada a una tabla para codificar en ASCKII la tecla presionada:
Código
GeSHi (asm):
  1. movfw NTecla
  2. call Tabla_TMatricial
  3. ;Codificacion de Tecla presionada:
  4. Tabla_TMatricial
  5. addwf PCL,1
  6. DT "1","2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"
« Última modificación: 20 de Abril de 2009, 17:24:58 por Suky » En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #17 : 05 de Febrero de 2009, 20:56:49 »

Control del LCD
Descripción: La pantalla de cristal liquido o LCD (Liquid Crystal Display) es un dispositivo µControlado de visualización grafico para la presentación de caracteres, símbolos o incluso dibujos (en algunos modelos). En este caso  dispone de 2 filas de 16 caracteres cada una y cada carácter dispone de una matriz de 5x7 puntos (pixels), aunque los hay de otro número de filas y caracteres. Este dispositivo esta gobernado internamente por un microcontrolador Hitachi 44780 y regula todos los parámetros de presentación, este modelo es el mas comúnmente usado y la información que se adjunta se basará en el manejo de este u otro LCD compatible.

Conexión del modulo LCD al PIC16F84A mediante bus de 4 bits.

En este ejemplo haremos uso de dos directivas más de ensamblador. Estas son #DEFINE y macro.

#DEFINE es empleado para crear sustituciones dentro del texto del programa que lo simplifiquen. La forma correcta es #DEFINE NOMBRE TEXTO, con lo que, cada vez que el compilador encuentre la orden NOMBRE, la sustituirá por el texto. El problema que se nos plantea es que, si bien es más flexible que la directiva EQU, puesto que esta sólo nos permitía asignar un valor, sólo se nos permite con #DEFINE una línea de texto, y esta debe ser fija.
Código
GeSHi (asm):
  1. #DEFINE LCD_E LCD_PORT_Control,E

Este problema se soluciona mediante macro. Esta directiva tiene la siguiente forma:

NOMBRE macro ARGUMENTO1, ARGUMENTO2, ETC
              TEXTO
              TEXTO...
 endm

De este modo NOMBRE será sustituido como comando por la secuencia completa definida tras macro hasta endm, y los sucesivos argumentos serán, a su vez, sustituidos dentro del texto.

En nuestro ejemplo lo utilizaremos para enviar un carácter o un comando al LCD, de la siguiente manera:

Código
GeSHi (asm):
  1. LCD_Putc macro Carac
  2. movlw Carac
  3. call LCD_Caracter
  4. endm
  5. LCD_Putd macro Coman
  6. movlw Coman
  7. call LCD_Comando
  8. endm

Rutinas de Control:

LCD_Config_puertos: Configura los puertos del PIC para el uso del modulo LCD, solo afecta a los pines utilizados.-
LCD_Init: Inicializa el módulo LCD para su correcto funcionamiento. Es necesario ejecutar esta subrutina al principio de los programas que vayan a utilizar la visualización mediante LCD.
LCD_Bandera: Explora el estado de la bandera Busy (ocupado) del módulo LCD  y espera que termine cualquier comando previo antes de  volver a la rutina que le llamo.-
LCD_Enable: Habilita el módulo LCD durante 2us para recepción de datos o envío.-
LCD_Comando: Configura módulo LCD para recibir un comando mediante rutina LCD_Envio_Data.-
LCD_Caracter: Configura módulo LCD para recibir un carácter mediante rutina LCD_Envio_Data.-
LCD_Envio_Data: Envía dato al LCD, Cargando el nible alto y luego el nible bajo.-

Nota: Observar que las líneas de control y bus de datos es fácilmente modificable en Declaración de bits para control LCD y Declaración de Bytes del LCD.
En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #18 : 05 de Febrero de 2009, 20:58:36 »

Como ejemplo de aplicación se muestra un ejemplo donde se visualiza un mensaje (“Todo Pic”):

Código
GeSHi (asm):
  1. ; **** Encabezado ****
  2. list p=16F84A
  3. #include P16F84A.inc
  4. __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
  5. ;///////////////////////////////////////////////////////////////////
  6. ;**** Declaración de Registros ****
  7. LCD_Dato   equ 0x0C ;registro para guardar dato a enviar al LCD
  8. Loop equ 0x0D ;registro para inicializacion del LCD
  9. Contador1 equ 0x0E ;registro para demoras
  10. Contador2 equ 0x0F ;registro para demoras
  11. ;**** Declaracion de bits para control LCD ****
  12. RS equ 0
  13. RW equ 1
  14. E equ 2
  15. BACK equ 3
  16.  
  17. D4 equ 4
  18. D5 equ 5
  19. D6 equ 6
  20. D7_BF equ 7
  21. ;**** Declaracion de Bytes del LCD ****
  22. LCD_PORT_Control equ 0x05 ; PORTA para control del LCD
  23. LCD_PORT_Data equ 0x06 ; PORTB para envio de Datos al LCD
  24. LCD_TRIS_Control equ 0x85 ; TRISA
  25. LCD_TRIS_Data equ 0x86 ; TRISB
  26. ; **** Comandos de Software para la LCD ****
  27. LCDLinea1 equ 0x80 ; Dirección comienzo línea1
  28. LCDLinea2 equ 0xC0 ; Dirección comienzo línea2
  29. LCDClr equ 0x01 ; Borra pantalla, cursor a Inicio
  30. LCDInicio equ 0x02 ; Cursor a Inicio, DDRAM sin cambios
  31. LCDInc equ 0x06 ; Modo incrementa cursor
  32. LCDDec equ 0x04 ; Modo decrementa cursor
  33. LCDOn equ 0x0C ; Pantalla On
  34. LCDOff equ 0x08 ; Pantalla Off
  35. CursOn equ 0x0E ; Pantalla On, cursor On
  36. CursOff equ 0x0C ; Pantalla On, cursor Off
  37. CursBlink equ 0x0F ; Pantalla On, Cursor parpadeante
  38. CurIzda equ 0x10 ; Mueve cursor a la izquierda
  39. CurDecha equ 0x14 ; Mueve cursor a la derecha
  40. DisIzda equ 0x18 ; Mueve Display a la izquierda
  41. DisDecha equ 0x1C ; Mueve Display a la Derecha
  42. LCDBus_4_2 equ 0x28 ; Bus 4 bits, 2 líneas, 5x7
  43. ;**** Definiciones para el ensamblador ****
  44. #DEFINE LCD_E LCD_PORT_Control,E
  45. #DEFINE LCD_RS LCD_PORT_Control,RS
  46. #DEFINE LCD_RW LCD_PORT_Control,RW
  47. #DEFINE LCD_D4 LCD_PORT_Data,D4
  48. #DEFINE LCD_D5 LCD_PORT_Data,D5
  49. #DEFINE LCD_D6 LCD_PORT_Data,D6
  50. #DEFINE LCD_D7_BF LCD_PORT_Data,D7_BF
  51. #DEFINE CD_backlight LCD_PORT_Control,BACK ; Control Backligth.-
  52. ;**** Definición de macros ****
  53. LCD_Putc macro Carac
  54. movlw Carac
  55. call LCD_Caracter
  56. endm
  57. LCD_Putd macro Coman
  58. movlw Coman
  59. call LCD_Comando
  60. endm
  61. ;//////////////////////////////////////////////////////////
  62. ;**** Inicio del Micro ****
  63. org 0x00
  64. goto Inicio
  65. ;**** Programa principal ****
  66. org 0x05
  67. Inicio
  68. call LCD_Config_puertos ; Configuramos Puertos a utilizar por LCD.-
  69. call LCD_Init ; Inicializamos LCD.-
  70. bsf LCD_backlight ; Prendemos Backlight.-
  71. LCD_Putd CursBlink ; Cursor Parpadeante.-
  72. LCD_Putc 'T' ; Escribimos en LCD.-
  73. LCD_Putc 'o'
  74. LCD_Putc 'd'
  75. LCD_Putc 'o'
  76. LCD_Putc ' '
  77. LCD_Putc 'P'
  78. LCD_Putc 'I'
  79. LCD_Putc 'C'
  80. Bucle
  81. nop
  82. goto Bucle ; Bucle Infinito.-
  83.  
  84. ;**** Subrutinas de Control ****
  85.  
  86. ;**** Configuracion de puertos ****
  87. LCD_Config_puertos
  88. bsf STATUS,RP0 ; Seleccionamos Banco 1.-
  89. bcf LCD_RS ; Colocamos todas las lineas de control y bus como Salidas.-
  90. bcf LCD_RW
  91. bcf LCD_E
  92. bcf LCD_D4
  93. bcf LCD_D5
  94. bcf LCD_D6
  95. bcf LCD_D7_BF
  96. bcf LCD_backlight
  97. bcf STATUS,RP0 ; Volvemos an Banco 0.-
  98. bcf LCD_RS
  99. bcf LCD_RW
  100. bcf LCD_E
  101. bcf LCD_D4
  102. bcf LCD_D5
  103. bcf LCD_D6
  104. bcf LCD_D7_BF
  105. bcf LCD_backlight
  106. return
  107. ;...................................
  108. ;**** Inicializacion de LCD ****
  109. LCD_Init
  110. bcf STATUS,RP0 ; Aseguramos Banco 0.-
  111. movlw 0x03
  112. movwf Loop
  113. bsf LCD_D4 ;<D7 D6 D5 D4> = 0011.-
  114. bsf LCD_D5
  115. ;.... se ejecuta 3 veces el siguiente bloque ....
  116. bsf LCD_E
  117. call Demora_5ms
  118. bcf LCD_E
  119. call Demora_5ms
  120. decfsz Loop
  121. goto $-5
  122. ;.... Interfase de 4 bits ....
  123. bcf LCD_D4 ;<D7 D6 D5 D4> = 0010.-
  124. bsf LCD_E
  125. call Demora_5ms
  126. bcf LCD_E
  127. call Demora_5ms
  128. ;.... Sistema -> << Bus de 4 bits, 2 lineas, 5x7>>.-
  129. movlw LCDBus_4_2
  130. call LCD_Comando
  131. ;....Limpia display y retorna al origen ....
  132. movlw LCDClr
  133. call LCD_Comando  
  134. return
  135. ;.........................................
  136. ;**** Lee Estado del LCD ****
  137. LCD_Bandera
  138. bcf LCD_RW
  139. bcf LCD_RS
  140. bcf LCD_E
  141. bcf LCD_D4
  142. bcf LCD_D5
  143. bcf LCD_D6
  144. bcf LCD_D7_BF
  145. nop
  146. bsf LCD_RW ; Modo Lectura.-
  147. bsf STATUS,RP0 ; Banco 1.-
  148. bsf LCD_D7_BF ; Configura TRIS para recibir estado del LCD.-
  149. bcf STATUS,RP0 ; Banco 1.-
  150. bsf LCD_E
  151. nop
  152. btfsc LCD_D7_BF ; Lee estado del LCD, 1-> Ocupado.-
  153. goto $-1 ; Esperamos a que se desocupe.-
  154. bcf LCD_E ; LCD_D7/BF->0, seguimos adelante.-
  155. bsf STATUS,RP0 ; Banco 1.-
  156. bcf LCD_D7_BF ; Reconfigura TRIS para envio de Data.-
  157. bcf STATUS,RP0 ; Banco 1.-
  158. return
  159. ;.............................
  160. ;**** Envia pulso Enable ****
  161. LCD_Enable
  162. bsf LCD_E
  163. nop
  164. nop
  165. bcf LCD_E
  166. return
  167. ;.............................
  168. ;**** Envia Dato al LCD ****
  169. ;*** Previamente configurado como Comando o como Caracter.-
  170. LCD_Envio_Data
  171. movwf LCD_Dato ; Guardamos Dato a enviar.-
  172. ; CARGAMOS NIBLE ALTO EN PUERTO.-
  173. bcf LCD_D4 ; Cargamos un cero.-
  174. btfsc LCD_Dato,4 ; Si es 1, modificamos a uno, sino seguimos.-
  175. bsf LCD_D4
  176. bcf LCD_D5 ;
  177. btfsc LCD_Dato,5
  178. bsf LCD_D5
  179. bcf LCD_D6 ;
  180. btfsc LCD_Dato,6
  181. bsf LCD_D6
  182. bcf LCD_D7_BF ;
  183. btfsc LCD_Dato,7
  184. bsf LCD_D7_BF
  185. call LCD_Enable ; Habilitamos LCD para recepcion de Data.-
  186. ; CARGAMOS NIBLE BAJO EN PUERTO.-
  187. bcf LCD_D4 ; Cargamos un cero.-
  188. btfsc LCD_Dato,0 ; Si es 1, modificamos a uno, sino seguimos.-
  189. bsf LCD_D4
  190. bcf LCD_D5 ;
  191. btfsc LCD_Dato,1
  192. bsf LCD_D5
  193. bcf LCD_D6 ;
  194. btfsc LCD_Dato,2
  195. bsf LCD_D6
  196. bcf LCD_D7_BF ;
  197. btfsc LCD_Dato,3
  198. bsf LCD_D7_BF
  199. call LCD_Enable ; Habilitamos LCD para recepcion de Data.-
  200. return
  201. ;.............................
  202. ;**** Envia Comando al LCD ****
  203. LCD_Comando
  204. call LCD_Bandera ;Controla si el LCD esta en condiciones de recibir un nuevo dato.-
  205. bcf LCD_RW ; Modo escritura.-
  206. bcf LCD_RS ; Se enviara Comando.-
  207. call LCD_Envio_Data ; Envio Comando.-
  208. return
  209. ;.............................
  210. ;**** Envia Caracter al LCD ****
  211. LCD_Caracter
  212. call LCD_Bandera ;Controla si el LCD esta en condiciones de recibir un nuevo dato.-
  213. bcf LCD_RW ; Modo escritura.-
  214. bsf LCD_RS ; Se enviara Caracter.-
  215. call LCD_Envio_Data ; Envio Caracter.-
  216. return
  217. ;..............................
  218. ;**** Demora ****
  219. Demora_5ms
  220. movlw 0xC8 ; 200
  221. movwf Contador1 ; Iniciamos contador1.-
  222. Repeticion1
  223. movlw 0x07 ;
  224. movwf Contador2 ; Iniciamos contador2
  225. Repeticion2
  226. decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
  227. goto Repeticion2 ; Si no es 0 repetimos ciclo.-
  228. decfsz Contador1,1 ; Decrementa Contador1.-
  229. goto Repeticion1 ; Si no es cero repetimos ciclo.-
  230. return ; Regresa de la subrutina.-
  231.  
  232. ;...............................      
  233. end

Tengo que ser sincero, no logre simularlo con Proteus. Pero con elementos reales, lo probé en varias configuraciones de líneas de control y bus de datos, por lo que debería funcionar sin problemas.-
En línea

Suky
Moderadores
DsPIC33
*****
Desconectado Desconectado

Sexo: Masculino
Argentina Argentina

Mensajes: 6774


Con Qt...


WWW
« Respuesta #19 : 05 de Febrero de 2009, 20:59:47 »

Comunicación RS232El RS232 es un estándar de comunicaciones propuesto por la Asociación de Industrias Electrónicas (EIA) la cual define la interfase mecánica, los pines, las señales y los protocolos que debe cumplir la comunicación serial. La velocidad se mide en baudios (bits/segundo) y esta normalizada a 2400, 4800, 9600, 19200, 38400, etc. Y sólo son necesarios dos cables, uno de transmisión y otro de recepción.
Todas las normas RS-232 cumplen con los siguientes niveles de voltaje:
-   Un “1” lógico es un voltaje comprendido entre –5v y –15v
-   Un “0” lógico es un voltaje comprendido entre +5v y +15 v
Los puertos series son accesibles mediante conectores. La norma RS232 establece dos tipos de conectores llamados DB-25 y DB-9, machos y hembras. La norma RS232 se estableció para conectar un ordenador con un modem, por lo que aparecen muchas patillas en los conectores DB-25 que en otro tipo de aplicaciones no se utilizan y en las que es mas común utilizar el conector DB-9.
Cada una de las patillas del conector RS232 tiene una función específica. Patillas del DB-9:
Los pines que portan los datos son RxD y TxD los demás se encargan de otros trabajos, el DTR indica que el ordenador esta encendido, DSR que el dispositivo conectado al puerto esta encendido, RTS que el ordenador al no estar ocupado puede recibir datos, al revés de CTS que lo que informa es que es el dispositivo el que puede recibir datos, DCD detecta que existen presencia de datos, etc.
Formato de un byte:
El protocolo establecido por la norma RS232 envia la información estructurada en 4 partes:
-   Bit de inicio o arranque (START). Es un paso de -12V a +12V, es decir de un “1” a un “0” lógico en la lógica negativa de la norma RS232.
-   Bits de datos (Datas) Los bits de datos son enviados al receptor después del bit Start. El bit de menos peso LSB es trasmitido primero. Un carácter de datos suele consistir en 7 u 8 bits.
-   Bit de Paridad (Parity) Dependiendo de la configuración de la transmisión un bit de paridad puede ser enviado después de los bits de datos. Con este bit se suele descubrir errores en la transmisión, puede dar paridad par o impar.
-   Bit de Parada (STOP) la línea que a -12V después del ultimo bit enviado, es decir queda a “1” en lógica negativa de la norma. El protocolo permite 1, 1.5 o 2 bits de parada.
MAX 232.
En el mercado hay muchos circuitos integrados que permiten la conversión entre niveles TTL y niveles RS232. El más destacado es el transceptor MAX232:
Este convierte los niveles RS232 <+12 y -12> a voltajes TTL <0 y +5> y viceversa sin requerir mas que una fuente de +5V y un par de capacitores.
En línea

TODOPIC
   

 En línea
Páginas: [1] 2 3 4 5 6 7 8 Imprimir 
« anterior próximo »
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.20 | SMF © 2006-2008, Simple Machines XHTML 1.0 válido! CSS válido!
Página creada en 0.86 segundos con 23 consultas.