TODOPIC

Microcontroladores PIC => Primeros pasos - Iniciación a los microcontroladores => Mensaje iniciado por: Suky en 05 de Febrero de 2009, 21:18:42

Título: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 05 de Febrero de 2009, 21: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 (http://www.mediafire.com/?rxcjmjvl1jm) (Para el PIC16F84A)



El PIC16F628A/648A





 
Herramientas
Software para escribir nuestro código y compilar: MPLAB (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002)
Software para simular:  Proteus  (http://www.labcenter.co.uk/download/prodemo_download.cfm)
Una plaquita programadora.
Software para grabar nuestro PIC, se puede usar el WinPic800 (http://www.winpic800.com) o el Icprog (http://www.ic-prog.com/download.html)

:-)  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 (http://www.mediafire.com/file/ak3zio5hl2e/Para Comenzar.rar)


Datasheets

DATASHEET del PIC16F84A (http://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf)
DATASHEET del PIC16F628A/648A (http://host.nigde.edu.tr/muzam/PIC16F648A.pdf)



ConfigPIC (http://www.mediafire.com/file/z2o1jym5zzm/ConfigPIC.rar): Software para realizar el código automáticamente a partir de una interfase de configuración.
(http://img135.imageshack.us/img135/3100/54953366.th.jpg) (http://img135.imageshack.us/my.php?image=54953366.jpg)
Título: Introducción
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
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:
(http://img150.imageshack.us/img150/3674/pic16f84aab3.jpg)

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:
(http://img264.imageshack.us/img264/7666/osciladorcy3.bmp)

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:
(http://img156.imageshack.us/img156/801/resetze3.bmp)
Título: Estructura interna del Microcontrolador
Publicado por: Suky en 05 de Febrero de 2009, 21: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.
(http://img217.imageshack.us/img217/4196/arquitecturapicxy4.jpg)

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.
(http://img204.imageshack.us/img204/7706/memoriadelprogramawk8.jpg)

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.
(http://img516.imageshack.us/img516/7530/memoriaramii2.jpg)

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)
Título: Primer Programa
Publicado por: Suky en 05 de Febrero de 2009, 21: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 (http://www.todopic.com.ar/foros/index.php?topic=23623.0) 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:
(http://img217.imageshack.us/img217/282/hardcontrolledja0.bmp)

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:
(http://img19.imageshack.us/img19/7125/controlledtz4.jpg)

Primero que nada debemos especificar con que microcontrolador estamos trabajando, esto lo realizamos es las dos primeras líneas:
Código: 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: 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: 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: 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: 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.-
 :-/
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:24:25
Programa completo:
Código: 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.-
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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: 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: 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.-
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
(http://img19.imageshack.us/img19/9232/ledtitilandosy4.jpg)

Código: 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
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
(http://img89.imageshack.us/img89/8063/display7segnp1.jpg)

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.

(http://img516.imageshack.us/img516/3756/harddisplaysimplewb0.bmp)

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

Diagrama de Flujo:
(http://img4.imageshack.us/img4/8099/displaysimpleth3.th.jpg) (http://img4.imageshack.us/my.php?image=displaysimpleth3.jpg)
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.
(http://img204.imageshack.us/img204/4632/contadorpcnr4.jpg)

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: 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: 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.                        
  15. ;**** Tabla de conversion BCD a 7 Segmentos ****
  16. ; Se coloca al inicio para asegurar ubicacion en Pagina.-
  17.         org     0x05            ; Origen del codigo de tabla.-
  18. BCD7SEG:                        ; retlw b'gfedcba'  para display catodo comun
  19.         addwf   PCL,1           ; Se incrementa el contador del programa.-
  20.         retlw   b'0111111'      ; 0    
  21.         retlw   b'0000110'      ; 1    
  22.         retlw   b'1011011'      ; 2    
  23.         retlw   b'1001111'      ; 3    
  24.         retlw   b'1100110'      ; 4    
  25.         retlw   b'1101101'      ; 5    
  26.         retlw   b'1111101'      ; 6    
  27.         retlw   b'0000111'      ; 7    
  28.         retlw   b'1111111'      ; 8    
  29.         retlw   b'1101111'      ; 9    
  30.         clrf    Contador        ; Si llega 10, se resetea contador
  31.         retlw   b'0111111'      ; 0
  32.  
  33. ;**** Programa principal ****
  34. ;**** Configuración de puertos ****
  35. Inicio  bsf     STATUS,RP0      ; Pasamos de Banco 0 a Banco 1.-
  36.         movlw   b'10000000'     ; RB7 como entrada y los demas como salida.-
  37.         movwf   TRISB
  38.         bcf     STATUS,RP0      ; Paso del Banco 1 al Banco 0
  39.         movlw   b'0111111'      ; Comienza en cero.-
  40.         movwf   PORTB
  41.         clrf    Contador
  42. ;**** Testeo de Pulsador ****
  43. Testeo
  44.         btfss   PORTB,Pulsador  ; Testeamos si esta a 1 logico.-
  45.         goto    Testeo                  ; No, seguimos testeando.-
  46.         call    Demora_20ms             ; Eliminamos Efecto rebote
  47.         btfss   PORTB,Pulsador  ; Testeamos nuevamente.-
  48.         goto    Testeo                  ; Falsa Alarma, seguimos testeando.-
  49.         incf    Contador,1              ; Se ha pulsado, incrementamos contador.-
  50.         movfw   Contador                ; pasamos contador a W
  51.         call    BCD7SEG         ; Llamamos tabla.-
  52.         movwf   PORTB                   ; Cargamos valor recibido por Tabla en PORTB
  53.         btfsc   PORTB,Pulsador  ; Esperamos a que se suelte el pulsador -**-
  54.         goto    $-1                     ; No, PCL - 1, --> btfss        PORTA,Pulsador.-
  55.         call    Demora_20ms             ; Eliminamos efecto rebote.-
  56.         btfsc   PORTB,Pulsador  ; Testeamos nuevamente.-
  57.         goto    $-4                     ; No, Falsa alarma, volvemos a testear a que se suelte (**).-  
  58. goto    Testeo                  ; Si, Testeamos nuevamente.-
  59.                        
  60. ;**** Demora ****
  61. Demora_20ms
  62.         movlw   0xFF                    ;
  63.         movwf   Contador1               ; Iniciamos contador1.-
  64. Repeticion1
  65.         movlw   0x19                    ;
  66.         movwf   Contador2               ; Iniciamos contador2
  67. Repeticion2
  68.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  69.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  70.         decfsz  Contador1,1             ; Decrementa Contador1.-
  71.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  72.         return                          ; Regresa de la subrutina.-
  73.  
  74.         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: 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 (http://www.todopic.com.ar/foros/index.php?topic=12345.msg74300#msg74300)
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.
(http://img205.imageshack.us/img205/1919/antirrebote.jpg)

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.-
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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: 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: 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.                
  41. ;**** Demora ****
  42. Demora_190ms
  43.         movlw   0xFF                    ;
  44.         movwf   Contador1               ; Iniciamos contador1.-
  45. Repeticion1
  46.         movlw   0xFF                    ;
  47.         movwf   Contador2               ; Iniciamos contador2
  48. Repeticion2
  49.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  50.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  51.         decfsz  Contador1,1             ; Decrementa Contador1.-
  52.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  53.         return                          ; Regresa de la subrutina.-
  54. ;**** Cargamos tabla en memoria ****
  55. Config_Tabla
  56.         movlw   0x10    ;
  57.         movwf   FSR             ; Direccionamos el registro 0x10 de la memoria RAM (GPR).-
  58.         movlw   0x3F    ; Cargamos el codigo para mostrar el CERO.-
  59.         movwf   INDF    ; Lo guardamos donde apunta FSR --> 0x10.-
  60. ;....................
  61.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x11.-
  62.         movlw   0x06    ; Cargamos codigo para UNO.-
  63.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  64. ;....................
  65.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x12.-
  66.         movlw   0x5B    ; Cargamos codigo para DOS.-
  67.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  68. ;....................
  69.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x13.-
  70.         movlw   0x4F    ; Cargamos codigo para TRES.-
  71.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  72. ;....................
  73.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x14.-
  74.         movlw   0x66    ; Cargamos codigo para CUATRO.-
  75.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  76. ;....................
  77.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x15.-
  78.         movlw   0x6D    ; Cargamos codigo para CINCO.-
  79.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  80. ;....................
  81.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x16.-
  82.         movlw   0x7D    ; Cargamos codigo para SEIS.-
  83.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  84. ;....................
  85.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x17.-
  86.         movlw   0x07    ; Cargamos codigo para SIETE.-
  87.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  88. ;....................
  89.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x18.-
  90.         movlw   0xFF    ; Cargamos codigo para OCHO.-
  91.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  92. ;....................
  93.         incf    FSR,1   ; Incrementamos FSR, ahora apunta a 0x19.-
  94.         movlw   0x6F    ; Cargamos codigo para NUEVE.-
  95.         movwf   INDF    ; Lo guardamos donde apunta FSR.-
  96. ;....................
  97.         movlw   0x10    ;
  98.         movwf   FSR             ; Direccionamos Registro del CERO.-
  99.         return                  ; Cargado los valores, retornamos.-    
  100. ;..................................................................
  101.         end
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:45:32
Control de varios Display
Para 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:
(http://img90.imageshack.us/img90/4061/hard3displayiv2.bmp)

Diagramas de Flujo:
(http://img4.imageshack.us/img4/9899/3displaymainev2.th.jpg) (http://img4.imageshack.us/my.php?image=3displaymainev2.jpg)

(http://img4.imageshack.us/img4/2979/3displayrutinafa2.th.jpg) (http://img4.imageshack.us/my.php?image=3displayrutinafa2.jpg)

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.
(http://img147.imageshack.us/img147/3754/3displaysiw2.jpg)

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: 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.                        
  23. ;**** Tabla de conversion BCD a 7 Segmentos ****
  24. ; Se coloca al inicio para asegurar ubicacion en Pagina.-
  25.         org     0x05            ; Origen del código de tabla.-
  26. BCD7SEG                 ; retlw b'gfedcba'  para display catodo comun
  27.         addwf   PCL,1           ; Se incrementa el contador del programa.-
  28.         DT 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F  
  29.  
  30. ;**** Programa principal ****
  31. ;**** Configuracion de puertos ****
  32. Inicio
  33.         bsf     STATUS,RP0      ; Pasamos de Banco 0 a Banco 1.-
  34.         clrf    TRISA           ; PORTA como salida
  35.         clrf    TRISB           ; PORTB como salida.-
  36.         bcf     STATUS,RP0      ; Paso del Banco 1 al Banco 0
  37.         clrf    PORTA           ; Desactivo todos los Displays
  38.         clrf    Unidad          ; Comienza en cero --> 0 0 0.-
  39.         clrf    Decena
  40.         clrf    Centena
  41.         goto    Actualizo_Display       ; Esta rutina multiplexa los displays.-
  42. ;**** Testeo de Pulsador ****
  43. Bucle
  44.         incf    Unidad,1        ; Incremeto Unidad.
  45.         movlw   d'10'           ; Si es 10 reseteo e incremento Decena
  46.         subwf   Unidad,0        ;
  47.         btfss   STATUS,Z        ;
  48.         goto    Actualizo_Display       ; no es 10
  49.         clrf    Unidad          ; Si, reseteo.-        
  50.         incf    Decena,1        ; Incremento Decena.-
  51.         movlw   d'10'           ; Si Decena = 10, reseteo e incremento Centena
  52.         subwf   Decena,0        ;
  53.         btfss   STATUS,Z        ;
  54.         goto    Actualizo_Display       ; No es 10.-
  55.         clrf    Decena          ; Si, reseteo.-
  56.         incf    Centena,1       ; Incremento Centena.-
  57.         movlw   d'10'           ; Si es 10 Reseteo.-
  58.         subwf   Centena,0
  59.         btfss   STATUS,Z
  60.         goto    Actualizo_Display       ; No es 10.-
  61.         clrf    Centena         ; Si, reseto
  62. ;**** Se multiplexan los Display ****  
  63. Actualizo_Display
  64.         movlw   d'20'                   ; Cargo Contador = 20
  65.         movwf   Contador                ; Para repeticiones de visualizacion del mismo valor
  66.                                         ; durante 150 ms.-
  67. Refresco
  68.         movfw   Unidad                  ; Obtengo codigo de 7 Segmentos para Unidad.-
  69.         call    BCD7SEG         ;
  70.         bcf     PORTA,MuestroC  ; Apago Display de Centena, Se entiende al mirar rutina.-
  71.         movwf   PORTB                   ; Cargo unidad en PORTB.-
  72.         bsf     PORTA,MuestroU  ; Enciendo Display de Unidad.-
  73.         call    Demora_5ms     
  74.         movfw   Decena                  ; Obtengo codigo 7 Segmentos para Decena.-
  75.         call    BCD7SEG
  76.         bcf     PORTA,MuestroU  ; Apago Display de Unidad.-
  77.         movwf   PORTB                   ; Cargo PORTB con Decena.-     
  78.         bsf     PORTA,MuestroD  ; Enciendo Display de Decena.-
  79.         call    Demora_5ms
  80.         movfw   Centena         ; Obtengo codigo de 7 Segmentos para Centena.-
  81.         call    BCD7SEG
  82.         bcf     PORTA,MuestroD  ; Apago Display de Decena.-
  83.         movwf   PORTB                   ; Cargo PORTB con Centena.-
  84.         bsf     PORTA,MuestroC  ; Enciendo Display Centena.-
  85.         call    Demora_5ms
  86.         decfsz  Contador,1              ; Pregunto si ya se ha repetido 10 veces el ciclo?
  87.         goto    Refresco                ; No, repito.-
  88.         goto    Bucle                   ; Si, actualizo cuenta.-
  89. ;**** Demora ****
  90. Demora_5ms
  91.         movlw   0xFF                    ;
  92.         movwf   Contador1               ; Iniciamos contador1.-
  93. Repeticion1
  94.         movlw   0x05                    ;
  95.         movwf   Contador2               ; Iniciamos contador2
  96. Repeticion2
  97.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  98.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  99.         decfsz  Contador1,1             ; Decrementa Contador1.-
  100.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  101.         return                          ; Regresa de la subrutina.-
  102.  
  103.         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 (http://www.todopic.com.ar/foros/index.php?topic=24720.msg213264#msg213264)
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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.
(http://img204.imageshack.us/img204/5091/harddisplayconversorox1.bmp)

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
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:47:37
INTERRUPCIONES
Una 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:

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:

(http://img3.imageshack.us/img3/4032/logicadeinterrupciones8.jpg)

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:

Bits utilizados.
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: 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,; 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.-
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:48:27
INTERRUPCION POR TMR0
El 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.
(http://img90.imageshack.us/img90/149/tmr0aa6.jpg)

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.
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
\mathrm{TMR0}=256-\left(\frac{4000us}{1us\cdot32}\right)
\mathrm{TMR0}=131

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:
(http://img7.imageshack.us/img7/6682/tmr0temporizadorva1.th.jpg) (http://img7.imageshack.us/my.php?image=tmr0temporizadorva1.jpg)
Código: 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,; 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.
(http://img139.imageshack.us/img139/8141/21115051.th.jpg) (http://img139.imageshack.us/my.php?image=21115051.jpg)
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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.
(http://img132.imageshack.us/img132/6776/tmrocontadornm7.bmp)

Diagrama de Flujo:
(http://img297.imageshack.us/img297/9327/tmr0contadorzi5.th.jpg) (http://img297.imageshack.us/my.php?image=tmr0contadorzi5.jpg)

 
Código: 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
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
(http://img5.imageshack.us/img5/1977/intrb0mb7.bmp)
Diagrama de Flujo:
(http://img4.imageshack.us/img4/4408/rb0wx0.th.jpg) (http://img4.imageshack.us/my.php?image=rb0wx0.jpg)

Código: 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
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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:
(http://img132.imageshack.us/img132/8633/hardwaretecladoar6.bmp)

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.
(http://img132.imageshack.us/img132/7404/tecladomatricialex4.jpg)

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:
(http://img4.imageshack.us/img4/39/tecladomatricialnu0.th.jpg) (http://img4.imageshack.us/my.php?image=tecladomatricialnu0.jpg)

Código: 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: ASM
  1. movfw   NTecla
  2.         call    Tabla_TMatricial
  3.        
  4. ;Codificacion de Tecla presionada:
  5. Tabla_TMatricial
  6.         addwf   PCL,1
  7.         DT      "1","2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21: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.
(http://img90.imageshack.us/img90/8066/hardwarelcdal7.bmp)

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: 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: 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.
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:58:36
Como ejemplo de aplicación se muestra un ejemplo donde se visualiza un mensaje (“Todo Pic”):

Código: 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.-
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 21:59:47
Comunicación RS232
El 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
(http://img26.imageshack.us/img26/7751/rs1ha7.jpg)
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:
(http://img10.imageshack.us/img10/5564/db9ld3.jpg)
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:
(http://img25.imageshack.us/img25/5108/rs232sx1.bmp)
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.
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: Suky en 05 de Febrero de 2009, 22:06:14
Para ejemplificar el uso de este protocolo para establecer comunicación con la PC, haremos un programita que reciba la data de la PC y se la reenviaremos inmediatamente.
(http://img8.imageshack.us/img8/3884/hardwarers232td3.bmp)
Para la recepción de datos aprovecharemos la interrupción externa por RB0, configurada en flanco descendente (Detectara cuando la PC envié un bit de Start). Deja pasar un tiempo una y media veces mayor que el periodo de transmisión para saltarse el bit de Start y lee el primer bit en su mitad. Lee el resto de los bits de datos, esperando un tiempo igual a la duración del periodo entre lectura y lectura para testearlos en mitad del bit. Kbhit indica si ha llegado o no un dato desde PC.  <<RS232_LeerDato>>
Para el envío de datos se envía un "0" durante un tiempo igual al periodo de la velocidad de transmisión. Este es el bit de "Start". Luego se envía el bit correspondiente al dato a enviar: Si va a enviar un "0" permanece en bajo durante el periodo correspondiente y si se va a escribir un "1" permanece en alto durante el periodo correspondiente. Al enviar los 8 bits de datos se envía un bit de Stop, nivel alto durante un periodo. <<RS232_EnviaDato>>
Los parámetros adoptados para la comunicación son los siguientes:

Para establecer comunicación con el microcontrolador utilizaremos el software Siow (http://www.mediafire.com/file/jhrzmdnmozz/Siow.rar), es un monitor del puerto serie muy sencillo de usar, solo hay que configurar los parámetros de comunicación. (También se puede usar el Hyperterminal de Windows)
(http://img23.imageshack.us/img23/7941/siowvj1.jpg)

Código: 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.         RS232_ContBits  equ     0x0C
  8.         RS232_Dato              equ     0x0D
  9.         Flags                   equ     0x0E
  10.         Contador                equ     0x0F
  11.        
  12. ;**** Definiciones para el ensamblador ****
  13. #DEFINE RS232_RX        PORTB,0         ; Línea por la que se reciben los datos.
  14. #DEFINE RS232_TX        PORTB,1         ; Línea por la que se envían los datos.
  15. #DEFINE Kbhit           Flags,0         ; Indica si se ha recibido algun dato.-
  16. ;**** Definición de macros ****
  17. ; Se envia la data de un registro a PC.-
  18. Putreg  macro   Registro
  19.         movfw   Registro
  20.         call    RS232_EnviaDato
  21. endm
  22. ; Se envia un literal a PC.-
  23. Putc    macro   ACKII
  24.         movlw   ACKII
  25.         call    RS232_EnviaDato
  26. endm
  27.  
  28. ;//////////////////////////////////////////
  29. ;**** Inicio del Micro ****
  30. Reset          
  31.         org     0x00            ; Aqui comienza el micro.-
  32.         goto    Inicio          ; Salto a inicio de mi programa.-
  33. ;**** Vector de Interrupcion ****
  34.         org     0x04            ; Atiendo Interrupcion.-
  35.         goto    ISR
  36.  
  37. ; **** Programa Principal ****
  38. ;**** Configuracion de puertos ***
  39.         org     0x05            ; Origen del codigo de programa.-
  40. Inicio         
  41.         call    RS232_Puerto    ; Se inicializa el puerto e interrupcion para enviar y recibir datos RS232.-
  42. ;**** Espera a recibir Dato ****
  43. Bucle          
  44.         btfss   Kbhit           ; ¿Se recibio Dato?
  45.         goto    $-1             ; No, seguimos esperando.-
  46.         bcf     Kbhit           ; Si, borramos bandera.-
  47.         Putreg  RS232_Dato      ; Enviamos lo guardado en RS232_Dato.-
  48.         goto    Bucle           ;
  49. ;.............................................
  50. ;**** Rutina de servicio de Interrupcion ****
  51. ;**** Interrupcion por RB0 ****
  52. ; Se lee dato enviado por PC.-
  53. ; En este caso no es necesario hacer copias de respaldo de W y STATUS.-
  54. ;----------------------------------------------------------------------------------------------
  55. ; El 1º bit recibido se guarda en RS232_Dato,7; al rotarse 7 veces (Se recibe el byte completo)
  56. ; este queda en RS232_Dato,0.-
  57. ;----------------------------------------------------------------------------------------------
  58. ISR
  59.         btfss   INTCON,INTF             ; Consultamos si es por RB0.-
  60.         retfie                          ; No, Salimos de interrupción.-
  61. RS232_LeerDato
  62.         movlw   d'7'                    ; Número de rotaciones.
  63.         movwf   RS232_ContBits
  64.         call    Demora_150us    ; El primer bit debe leerlo un tiempo igual a una
  65.                                         ; vez y media el periodo de transmisión.
  66. LeeBit
  67.         bcf     RS232_Dato,7    ; Ahora lee el pin. En principio supone que es 0.
  68.         btfsc   RS232_RX                ; ¿Realmente es cero?
  69.         bsf     RS232_Dato,7    ; No, pues cambia a "1".
  70.         rrf     RS232_Dato,1    ; Rotamos para recibir el siguiente bit.-
  71.         call    Demora_100us    ; Los siguientes bits los lee un periodo más tarde.
  72.         decfsz  RS232_ContBits,1        ; Comprueba que es el último bit.
  73.         goto    LeeBit                  ; No es el último, pasa a leer el siguiente.
  74.         bcf     RS232_Dato,7    ; Ahora lee ultimo bit enviado.Supone que es 0.
  75.         btfsc   RS232_RX                ; ¿Realmente es cero?
  76.         bsf     RS232_Dato,7    ; No, pues cambia a "1".
  77.         call    Demora_100us    ; Espera un tiempo igual al bit de Stop.
  78.         bsf     Kbhit                   ; Se indica que ha llegado dato.-
  79. Fin_ISR                                         ; El dato recibido se guarda en <<RS232_Dato>>
  80.         bcf     INTCON,INTF             ; Limpiamos bandera.-
  81.         retfie                                  ; Salimos de interrupción.-
  82. ;.................................................
  83. ;**** Rutinas ****
  84. ;*** Configura las líneas de salida y entrada ****
  85. RS232_Puerto
  86.         bsf     STATUS,RP0
  87.         bsf     RS232_RX                ; Esta línea se configura como entrada.
  88.         bcf     RS232_TX                ; Esta línea se configura como salida.
  89.         clrf    OPTION_REG              ; Config. Por flanco Descendente Interrupcion RB0.-
  90.         bcf     STATUS,RP0
  91.         bsf     RS232_TX                ; Condicion de no transmision de datos.-
  92.         movlw   b'10010000'             ; Habilitamos GIE y INTE (interrupción por RB0)
  93.         movwf   INTCON
  94.         bcf     Kbhit                   ; Borramos bandera.-
  95.         return
  96.  
  97. ;**** Se envia Dato ****+
  98. ;-----------------------------------------------------------------------------------------
  99. ; 1º se envia el LSB, luego se va rotando a la derecha y se envian los bits de mayor peso.-
  100. ;-----------------------------------------------------------------------------------------
  101. RS232_EnviaDato
  102.         movwf   RS232_Dato              ; Guarda el contenido del byte a transmitir.
  103.         movlw   d'8'                    ; Número de bits a transmitir.
  104.         movwf   RS232_ContBits
  105.         bcf     RS232_TX                ; Se genera bit de Start.
  106.         call    Demora_100us
  107. EnviaBit                                        ; Comienza a enviar datos.
  108.         btfss   RS232_Dato,0    ; ¿Es un "1" el bit a transmitir?
  109.         bcf     RS232_TX                ; No, pues envía un "0".
  110.         btfsc   RS232_Dato,0    ; ¿Es un "1" el bit a transmitir?
  111.         bsf     RS232_TX                ; Si, Transmite un "1".
  112.         rrf     RS232_Dato,1    ; Rota para envia siguiente bit.-
  113.         call    Demora_100us            ; Este es el tiempo que estará en alto o bajo.
  114.         decfsz  RS232_ContBits,1        ; Comprueba si es el último bit.
  115.         goto    EnviaBit                ; No es el último bit repite la operación.
  116.         bsf     RS232_TX                ; Envía bit de Stop.
  117.         call    Demora_100us
  118.         return
  119. ;**** Demoras ****     
  120. Demora_100us
  121.         movlw   d'31'
  122.         movwf   Contador
  123.         decfsz  Contador
  124.         goto    $-1
  125.         return
  126. Demora_150us
  127.         movlw   d'48'
  128.         movwf   Contador
  129.         decfsz  Contador
  130.         goto    $-1
  131.         return
  132. ;.....................................
  133.         end
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Azicuetano en 22 de Febrero de 2009, 10:55:40
Felicidades Suky!

Seguro que los compañeros que empiezan agradecen mucho tu trabajo  :mrgreen:


Un saludo desde Alicante.
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 22 de Febrero de 2009, 13:24:00
Gracias!!! La idea fue exponer lo que necesitaba cuando yo comence con los micros. Teoria y un ejemplo de aplicación. Cuando tenga un poco de tiempo voy agregar alguna que otra cosita.
Saludos desde Bariloche!
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Veguepic en 22 de Febrero de 2009, 18:59:17
Coincido con Azicuetano, muy completo el aporte.

Le he colocado una chincheta y espera que sigas agregando mas.

Saludos
Hugo
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: ema en 01 de Marzo de 2009, 17:37:56
Wow :shock: excelente...

Felicitaciones por aportar tanto esfuerzo a la comunidad
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Chrisbaf en 01 de Marzo de 2009, 18:04:04
gracias por este excelente tutorial , sigue adelante
Título: Re: Mis primeros programas en ASM. Tutorial PIC16F628A/648A
Publicado por: Suky en 05 de Marzo de 2009, 23:34:45
PIC16F628A/648A

Haré una introducción a los micros y realizare ejemplos para los módulos que no trae el PIC16F84A.

Características principales

Nota: Los módulos descriptos para el PIC16F628A son idénticos a los del PIC16F648A, lo único que varía entre ellos son las siguientes características:


De aquí en adelante me refiero al PIC16F628A pero los ejemplos son aplicables al PIC16F648A haciendo el cambio de encabezado:
Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f648A       ; list directive to define processor
  3.         #include        <p16f648A.inc; processor specific variable definitions


(http://img7.imageshack.us/img7/6121/pindiagram.png)
Puertos
Los PIC16F628/648A cuentan con dos puertos PORTA y PORTB, algunos pines de estos puertos de entrada/salida son multiplexados con una función alternativa de los periféricos del dispositivo. Cuando un periférico es activado el pin no puede ser usado para propósitos generales de e/s.

El PUERTO A es un puerto de entrada de 8 bits. Todos los pines, excepto RA5, pueden ser configurados como entrada o salida con la respectiva configuración del registro TRISA. El pin RA4 esta multiplexado con la entrada de reloj T0CKI y como salida se comporta como colecto abierto, por lo tanto debemos poner una resistencia Pull-up a Vdd. El pin RA5 es un disparador Schmitt solo de entrada y no cuenta con controladores de salida, según la configuración puede ser usado como Mclr (Reset externo), y además sirve también para entrar en el modo de programación cuando se aplica una tensión igual a Vpp (13,4V mínimo). Los demás pines del puerto trabajan de entrada como disparador de Schmitt Trigger y como salida lógica CMOS. Los pines RA0-RA3 sirven de entrada para el comparador analógico.

Importante: Si se utiliza en puerto A como I/O Digital, se debe deshabilitar los Comparadores Analógicos, cargando un 0x07 en CMCON.
El PORTB es un puerto bidireccional de 8 bits, del cual por software se pueden habilitar resistencias de pull-up internas. El PORTB es multiplexado con interrupciones externas, tales como detección de flanco por RB0, cambio de nivel por RB4 a RB7, USART, el módulo CCP y el reloj de entrada/salida TMR1.

Otros pines

Organización de la memoria.
El PIC16F628 posee un contador de programa de 13 bits, capaz de direccionar un espacio de memoria de 8Kx14. Sin embargo, únicamente los primeros 2Kx14, desde 0000h hasta 07FFh, están implementados. Los vectores de reset e interrupción están en las direcciones 0000h y 0004h, respectivamente. La pila (stack) es de 8 niveles, lo cual significa que puede soportar hasta 8 direcciones de retorno de subrutina.
 
(http://img10.imageshack.us/img10/7742/memorg.jpg)

El PIC16F628 posee un espacio de memoria RAM de datos de 512x8, dividido en 4 bancos de 128 bytes cada uno. Sin embargo, sólo están implementados 330 bytes, correspondiendo 224 al área de los registros de propósito general (GPR) y 36 al área de los registros de función especial (SFR). Los restantes 70 bytes implementados son espejos de algunos SFR de uso frecuente, así como de los últimos 16 GPR del banco 0. Por ejemplo, las posiciones 0Bh, 8Bh, 10Bh y 18Bh corresponden al registro INTCON, de modo que una operación hecha en cualquiera de ellos, se refleja automáticamente en los otros. Se dice, entonces, que las posiciones 8Bh, 10Bh y 18Bh están mapeadas en la posición 0Bh. Esta característica agiliza el acceso a estos registros, puesto que no siempre es necesario especificar el banco donde se encuentran. La selección del banco de ubicación de un SFR o un GPR particular se hace mediante los bits 6 (RP1) y 5 (RP0) del registro STATUS.

(http://img14.imageshack.us/img14/8660/memprog.jpg)


Interrupciones:
Registros utilizados:
INTCON: Registro de lectura y escritura que contiene varios bits de señalización y habilitación para el desbordamiento del TMR0, cambio sobre el puerto RB e interrupción externa en la patilla RB0/INT.
0.   RBIF: Indicador de interrupción por cambio de estado RB4-RB7
1.   INTF: Indicador de interrupción externa
2.   T0IF: Indicador de interrupción por desbordamiento de Timer 0
3.   RBIE: Habilitación de interrupción por cambio de estado RB4-RB7
4.   INTE: Habilitación de interrupción externa
5.   T0IE: Habilitación de interrupción por desbordamiento de Timer 0
6.   PEIE: Habilitación de interrupción de periféricos
7.   GIE: Habilitación general de interrupciones

PIR1: El registro PIR1 contiene los bits de señalización individual de las interrupciones de periféricos
0.   TMR1IF: Indicador de interrupción por desbordamiento de Timer 1
1.   TMR2IF: Indicador de interrupción por desbordamiento de Timer 2
2.   CCP1IF: Indicador de interrupción del módulo de Captura/Comparación.
a)   Modo Comparador: Coincidencia entre TMR1 y CCP1
b)   Modo Captura: Ha ocurrido una captura de TMR1
3.   No Implementado.
4.   TXIF: Indicador de interrupción de fin de transmisión USART
5.   RCIF: Indicador de interrupción de llegada de datos USART
6.   CMIF: Indicador de interrupción por cambio de estado de alguna de las salidas de los comparadores.
7.   EEIF: Indicador de interrupción de fin de escritura eeprom interna.

PIE1: Registro que posee los bits de habilitación individual para las interrupciones de periféricos. El bit PEIE del registro INTCON debe ser 1 para permitir la habilitación de cualquier interrupción de periférico.
0.   TMR1IE: Habilitación de interrupción por desbordamiento de Timer 1
1.   TMR2IE: Habilitación de interrupción por desbordamiento de Timer 2
2.   CCP1IE: Habilitación de interrupción del módulo de Captura/Comparación/PWM.
3.   No Implementado.
4.   TXIE: Habilitación de interrupción de fin de transmisión USART
5.   RCIE: Habilitación de interrupción de llegada de datos USART
6.   CMIE: Habilitación de interrupción por cambio de estado de alguna de las salidas de los comparadores.
7.   EEIE: Habilitación de interrupción de fin de escritura eeprom interna.

Lógica de Interrupciones:

(http://img3.imageshack.us/img3/4549/logicadeinterrupciones6.jpg)
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:36:59
Palabra de Configuración

Los PIC16F628A/648A han sido construidos con características tales que se pueden configurar para funcionar en modos de operación que no necesitan componentes externos tales como el circuito de reloj o de reset. Esto implica que es necesario configurar su modo de operación a través de una palabra de configuración.
La palabra de configuración se encuentra mapeada en la dirección 2007h de la memoria de programa y solo puede ser accesada durante la programación de dispositivo.

(http://img7.imageshack.us/img7/5917/configz.jpg)

CP1:CP0:Bits de protección de código
Los bits 13-10 encargados de proteger la memoria de programa.
CPD: Bit de protección para código de datos
1 = Protección deshabilitada de la memoria de datos.
0 = Protección habilitada en la memoria de datos.
LVP: Habilitación de la programación por voltaje bajo
1 = LVP habilitado, la terminal RB4/PGM tiene tal función.
0 = LCP: deshabilitado, RB4/PGM es una terminal I/O.
BODEN: Bit de reset por voltaje de alimentación bajo
1 = Reset por BOD habilitado
0 = Reset por BOD deshabilitado
MCLRE: Habilitacion del terminal de reset
1 = Terminal de reset en RA5.
0 = MCLR conectado internamente a Vdd, RA5 es un pin I/O.
PWRTEN : Bit de habilitación de temporizador al energizar
1 = PWRT habilitado.
0 = PWRT deshabilitado.
WDTEN: Bits de habilitación de Watch-Dog
1 = WDT habilitado
0 = WDT deshabilitado.
FOSC2:FOSC1:FOSC0: Bits de selección del tipo de oscilador
 
(http://img189.imageshack.us/img189/7517/configosciladores.jpg)

Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:41:49
El Módulo del Timer 0.
Idéntico al del PIC16F84.

El Módulo del Timer 1.
El Timer 1 a diferencia del Timer 0 es un contador / temporizador de 16 bits. El conteo es realizado por dos registros de 8 bits: (TMR1H (0Fh) y TMR1L (0Eh) ), estos dos registros son tanto leíbles como escribibles.
Así, el registro TMR1 se incrementa de 0000h a FFFFh y en la siguiente cuenta se reinicia en 0000h y así sucesivamente, al reciclarse se activa (en alto) la bandera TMR1IF (PIR1<0>), la cual puede ser utilizada para generar una interrupción, o bien, para ser consultada por poleo, teniendo las mismas precauciones que ya se explicaron antes para la bandera T0IF.

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.

(http://img8.imageshack.us/img8/9830/timer10.jpg)

Modo temporizador
En este modo el Timer se incrementa (si no se considera preescalador) en cada ciclo de instrucción (a la frecuencia Fosc/4). Este modo se selecciona limpiando el bit TMR1CS (T1CON<1>).
El preescalador que se puede intercalar entre el reloj Fosc/4 y el registro TMR1 puede tener sólo uno de 4 valores: 1/1, 1/2, 1/4 y 1/8.
En este caso la temporización de calcula:
Temporización = Ciclo de instrucción. (65536-TMR1) .Divisor de Frecuencia
Vemos que la máxima temporización posible es con TMR1 = 0, y Divisor de Frecuencia en 8, lográndose unos 524.3 ms aprox.

Modo contador
El Timer 1 también puede operar como contador, en este último caso, la entrada a contar se toma de la patita externa RB6/T1OSO/T1CKI.

Configuraciones:
El Timer 1 posee un bit para habilitación / deshabilitación, este es el bit TMR1ON (T1CON<0>) y habilita en alto.
Además, el Timer 1 posee una entrada interna de RESET, el cual puede ser activado por uno cualquiera de los módulos CCP que.
A continuación se describe el principal registro relacionado con el Timer 1 y todos sus bits, excepto los que tienen que ver con el modo contador:
Registro T1CON (10h)
(http://img9.imageshack.us/img9/1343/timer11.jpg)
bits 5:4
T1CKPS1:T1CKPS0.- Bits de selección del valor del divisor de frecuencia del preescalador:
1 1 = divisor 1/8
1 0 = divisor 1/4
0 1 = divisor 1/2
0 0 = divisor 1/1

bit 1
TMR1CS.- Bit de selección de la fuente de reloj
1 = Modo contador (fuente de reloj: patita RC0/T1OSO/T1CKI)
0 = Modo Temporizador (fuente de reloj Fosc/4)

bit 0
TMR1ON.- Bit de habilitación / deshabilitación del Timer 1:
1 = habilita Timer 1
0 = Deshabilita Timer 1



ConfigPIC traé una herramienta adicional que nos ayuda a seleccionar el preescaler y valor inicial del Timer para obtener una temporización deseada:
(http://img139.imageshack.us/img139/8141/21115051.th.jpg) (http://img139.imageshack.us/my.php?image=21115051.jpg)
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:45:00
Para ejemplificar haremos un simple ejemplo donde lo utilizamos como temporizador. Se hará titilar un led conectado al PIN RB0 cada 300 ms. Como se puede ver es idéntico al ejemplo realizado para Timer 0 del PIC16F84A, solo que en este caso no necesitaremos un registro adicional para lograr la demora deseada.
Hardware:
(http://img17.imageshack.us/img17/5300/tmr1.bmp)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definiciones para el ensamblador ****
  7. #DEFINE         Led     PORTB,0 ; Led ubicado en Puerto B, bit 0.-
  8.  
  9. ;//////////////////////////////////////////
  10. ;**** Inicio del Micro ****
  11. Reset          
  12.         org     0x00            ; Aquí comienza el micro.-
  13.         goto    Inicio          ; Salto a inicio de mi programa.-
  14. ;**** Vector de Interrupcion ****
  15.         org     0x04            ; Atiendo Interrupcion.-
  16.         goto    ISR
  17.  
  18. ; **** Programa Principal ****
  19. ;**** Configuracion de puertos ***
  20.         org     0x05            ; Origen del código de programa.-
  21. Inicio         
  22.         bsf     STATUS,RP0      ; Pasamos de Banco 0 a Banco 1.-
  23.         movlw   b'11111110'     ; RB0 como salida.-
  24.         movwf   TRISB
  25.         bcf     STATUS,RP0      ; Banco 0.-
  26.         movlw   b'00110001'     ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
  27.         movwf   T1CON
  28.         bcf     Led             ; El Led comienza apagado.-
  29.         movlw   0x6D            ; Cargamos 28036 en TMR1 para lograr 300ms.-
  30.         movwf   TMR1H           ; Byte alto de TMR1.-
  31.         movlw   0x84
  32.         movwf   TMR1L           ; Byte bajo de TMR1.-
  33.         bsf     STATUS,RP0      ; Banco 1.-
  34.         bsf      PIE1,TMR1IE    ; Activar interrupción por TMR1.
  35.         bsf     INTCON,GIE      ; Habilitacion general de interrupciones.-
  36.         bsf     INTCON,PEIE     ; Habilitacion de Interrupcion por perifericos.-
  37.         bcf     STATUS,RP0      ; Banco 0.-
  38. ;**** Control de Led ****
  39. Bucle          
  40.         nop                     ; Aqui el micro puede ejecutar cualquier otra tarea
  41.         goto    Bucle           ; sin necesidad de utilizar tiempo en un bucle de demora.-     
  42.  
  43.  
  44. ;**** Rutina de servicio de Interrupcion ****
  45. ;**** Interrupcion por TMR1 ****
  46. ISR
  47.         btfss   PIR1,TMR1IF     ; Consultamos si es por TMR1.-
  48.         retfie                  ; No, salimos de interrupcion.-
  49.         btfss   Led             ; Si, Controlamos Led. Si esta apagado, prendo y viseversa.-
  50.         goto    Prendo_led
  51.         bcf     Led             ; Apago Led.-
  52. Actualizo_TMR1                  ; Actualizo TMR1 para obtener una temporizacion de 300 ms.-
  53.         movlw   0x6D            ; Cargamos 28036 en TMR1.-
  54.         movwf   TMR1H           ; Byte alto de TMR1.-
  55.         movlw   0x84
  56.         movwf   TMR1L           ; Byte bajo de TMR1.-
  57.         goto    Fin_ISR         ; Restauro valores.-
  58. Prendo_led
  59.         bsf     Led             ; Prendo Led.-
  60.         goto    Actualizo_TMR1
  61. Fin_ISR
  62.         bcf     PIR1,TMR1IF     ; Borro bandera de control de Interrupcion.-
  63.         retfie                  ; Salimos de interrupción.-
  64. ;..........................................
  65.  
  66.         end
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:47:57
El Módulo del Timer 2.
El Timer es un temporizador (sin opción de trabajar como contador) de 8 bits. Su registro principal denominado TMR2 (11h) es un registro de 8 bits que se incrementa continuamente a la frecuencia seleccionada de Fosc/4 dividida por un preescalador. En la siguiente figura se muestra un diagrama de bloques del módulo del Timer2.

(http://img10.imageshack.us/img10/1640/timer20.jpg)

El preescalador
La frecuencia que incrementa al registro TMR2 puede ser dividida por un preescalador por un factor de 1/1, 1/4 o 1/16, seleccionable por los bits T2CKPS1:T2CKPS0 (T2CON<1:0>)
El Registro de comparación o de Periodo
En operación, el contenido del registro TMR2 se compara continuamente con un registro de periodo denominado PR2 (92h) cuyo valor podemos establecer por software.
Cada vez que la cuenta de TMR2 es igual a PR2, se reinicia el conteo en TMR2 desde cero, y además se genera una señal de salida, la cual es tratada por un postescalador, para poder generar una señal TMR2IF (PIR1<1>) que puede ser usada para solicitar una interrupción, o para ser leída por poleo.
El Postescalador
El postescalador divide la frecuencia con que ocurre una activación de la bandera TMR2IF, es decir, si el valor del postescalador es 1/1, esta bandera se activará cada vez que TMR2 se reinicie, en cambio, si es 1/16 (por ejemplo), TMR2IF se activará cada 16 reinicios de TMR2. En forma similar a los otros dos Timers, esta bandera debe ser limpiada previamente, si se quiere detectar su activación, esto puede ser hecho en la rutina de atención a la interrupción, o bien en la rutina que la detecta por poleo.
El valor de división del postescalador puede establecerse por software mediante los bits T2OUPS3:T2OUPS0 (T2CON<6:3>).

En este caso la temporización de calcula:
Temporización = Ciclo de instrucción. (PR2-TMR2) .Divisor de Frecuencia Pre. Divisor de frecuencia Post
Vemos que la máxima temporización posible es con TMR2 = 0, y Divisor de Frecuencia Pre en 16, Divisor de frecuencia Post en 16,  lográndose unos 65.5 ms aprox.

A continuación se describe el principal registro relacionado con el Timer 2 y todos sus bits.

Registro T2CON (12h)
(http://img14.imageshack.us/img14/8921/timer21.jpg)

bits 6:3
T2OUPS3:T2OUPS0.- Bits de selección del valor del divisor de frecuencia del postescalador, de acuerdo a la siguiente tabla:
0 0 0 0 = divisor 1/1
0 0 0 1 = divisor 1/2
0 0 1 0 = divisor 1/3

1 1 1 1 = divisor 1/16

bit 2
TMR2ON.- Bit de encendido del Timer 2
1 = Enciende (energiza) el Timer 2
0 = Apaga (desconecta) el Timer 2

bits 1:0
T2CKPS1:T2CKPS0.- Bits de configuración del valor del preescalador de acuerdo a la siguiente tabla:
0 0 = divisor 1/1
0 1 = divisor 1/4
1 x = divisor 1/16

Ejemplo de configuración para lograr una temporización de 20 ms:
Código: ASM
  1. bcf             STATUS,RP0      ; Banco 0.-
  2.         movlw   b'01000110'     ; Se selecciona TMR2, preescaler de 1/16, postescaler 1/8.-
  3.         movwf   T2CON
  4. bsf             STATUS,RP0      ; Banco 1.-
  5.         movlw   0x9D            ; Cargamos 157 en PR2 para lograr 20ms.-
  6.         movwf   PR2            
  7.         bsf     PIE1,TMR2IE     ; Activar interrupci&#243;n por TMR2.
  8.         bsf     INTCON,GIE      ; Habilitacion general de interrupciones.-
  9.         bsf     INTCON,PEIE     ; Habilitacion de Interrupcion por perifericos.-
  10.         bcf     STATUS,RP0      ; Banco 0.-

Control de interrupción:
Código: ASM
  1. ISR
  2.         btfss   PIR1,TMR2IF     ; Consultamos si es por TMR2.-
  3.         retfie                  ; No, salimos de interrupcion.-
  4.         .                       ; Si, rutina de interrupcion.
  5.         .
  6.         .
  7. Fin_ISR
  8.         bcf     PIR1,TMR2IF     ; Borro bandera de control de Interrupcion.-
  9.         retfie                  ; Salimos de interrupcion.-
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:52:08
La USART del PIC16F628/648A
La USART puede configurarse como sistema asíncrono -full dúplex-, que puede comunicarse con dispositivos periféricos como ordenadores personales u otros microcontroladores, o puede configurarse como sistema síncrono -half dúplex-, que puede comunicarse con periféricos tales como circuitos integrados convertidores A/D y D/A, EEPROMs serie, etc.
La USART del PIC puede ser configurada para operar en tres modos:
•   Modo Asíncrono (Full dúplex, transmisión y recepción simultaneas)
•   Modo síncrono Maestro (Hald duplex)
•   Modo síncrono Esclavo (Hald duplex)
Aquí solo trataré el modo asíncrono.
Modo Asíncrono.
En este modo la USART usa un formato estándar NRZ asíncrono, el cual para la sincronización usa: 1 bit de inicio (I), 8 o 9 bits de datos y 1 bit de paro (P). Mientras no se están transmitiendo datos la USART envía continuamente un bit de marca. El modo asíncrono se selecciona limpiando el bit SYNC del registro TXSTA (98H). El modo asíncrono es deshabilitado durante el modo SLEEP.
Cada dato es transmitido y recibido comenzando por el LSB. El hardware no maneja bit de Paridad, pero el noveno bit puede ser usado para este fin y manejado por software.

El módulo Asíncrono de la USART consta de 3 módulos fundamentales:
•   El circuito de muestreo
•   El generador de frecuencia de transmisión (Baud Rate)
•   El transmisor asíncrono
•   El receptor asíncrono.

El circuito de muestreo: El dato en la patita de recepción (RB1/RX/DT) es muestreado tres veces para poder decidir mediante un circuito de mayoría, si se trata de un nivel alto o un nivel bajo.
El Generador de Baud Rate (BRG)
Este generador consiste de un contador/divisor de frecuencia de 8 bits controlado por el registro SPBRG (99H).
De tal manera que la frecuencia de transmisión se calcula de acuerdo a la siguiente tabla:

(http://img8.imageshack.us/img8/2130/usart0.jpg)
En esta tabla X=valor de 8 bits en el registro del divisor, SPBRG. El bit BRGH corresponde a TXSTA<2>.
En el datasheet del PIC16F628/648A hay tablas donde se muestran algunos valores baud estándares, el divisor necesario (X=SPBRG) bajo diferentes frecuencias Fosc y el error producido en porcentaje.

El transmisor asíncrono
En la siguiente figura se muestra el diagrama de bloques del transmisor de la USART.
(http://img7.imageshack.us/img7/9805/usar1.jpg)

El corazón de este módulo es el registro de corrimiento TSR y la única manera de acceder al registro TSR es a través del registro TXREG (19H).
Para transmitir un dato, el programa deberá ponerlo primero en el registro TXREG. En cuanto el TSR termina de enviar el dato que tenía, enviando el bit de paro, se transfiere el dato contenido en TXREG (si hay alguno). En cuanto el dato de TXREG es transferido al TSR el TXREG queda vacío y esta condición se indicada mediante el bit bandera TXIF (PIR1<4>), el cual se pone en alto. Este bit NO puede ser limpiado por software, solamente se borrará cuando un nuevo dato se cargue en el registro TXREG. Si se escribe un dato seguido de otro a TXREG el primero se transfiere inmediatamente a TSR y el otro tiene que esperar hasta que el TSR termine de enviar el bit de Stop del primero. Durante esta espera TXIF permanece en bajo. Mientras el bit indicador TXIF señala el estado del registro TXREG, otro bit, TRMT (TXSTA<1>), muestra el estado del registro TSR. El bit de estado TRMT es de lectura, y se activa cuando el registro TSR está vacío. Ninguna interrupción está unida a este bit por lo que TRMT está pensado para ser consultado por “poleo” (sin usar interrupciones).
Para habilitar el módulo de transmisión es necesario poner en alto el bit TXEN (TXSTA<5>), mientras no se habilite el módulo, la patita de transmisión (RB2/TX/CK) se mantiene en alta impedancia. Si TXEN es deshabilitada a la mitad de una transmisión, está será abortada y el transmisor será reseteado.
Para seleccionar una transmisión a 9 bits, el bit TX9 (TXSTA<6>) deberá activarse, y el noveno bit deberá escribirse en TX9D (TXSTA<0>). El noveno bit se escribirá antes de cargar los 8 bits de datos en el registro TXREG. Esto es necesario, porque al escribir un dato en el registro TXREG puede tener lugar una transferencia inmediata del dato al registro TSR (si TSR está vacío). En este caso, se habrá cargado un dato incorrecto de nueve bits en el registro TSR.
De acuerdo a lo anterior, la inicialización del módulo de transmisión consiste en los siguientes pasos:
1.   Inicializar baud rate escribiendo al registro SPBRG el divisor adecuado y opcionalmente al bit BRGH.
2.   Habilitar comunicación asíncrona limpiando el bit SYNC y poniendo el bit SPEN.
3.   Si se van a usar interrupciones, poner el bit TXIE (PIE<4>).
4.   Poner el bit TX9 si se desea transmitir datos de 9 bits
5.   Habilitar transmisión poniendo el bit TXEN, lo cual pondrá el bit TXIF.
6.   Colocar el noveno bit del dato en TX9D si se están usando datos de 9 bits.
7.   Cargar el dato al registro TXREG (inicia la transmisión).


El receptor asíncrono
El módulo de recepción es similar al de transmisión, en la siguiente figura se muestran los bloques que lo constituyen.
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=24720.0;attach=10359)

Una vez que se ha seleccionado el modo asíncrono, la recepción se habilita poniendo en alto el bit CREN (RCSTA<4>)
El dato es recibido mediante la línea RB1/RX/DT y se conduce hasta el bloque Data Recovery (Recuperación de dato), la cual maneja un registro de corrimiento de alta velocidad (16 veces el Baud rate).
El corazón del receptor es el registro de corrimiento RSR. Este registro no es accesible por software, pero al capturar del bit de STOP el dato de RSR es transferido automáticamente al registro RCREG (1Ah) si éste está vacío y al mismo tiempo es puesto en alto la bandera de recepción RCIF (PIR1<5>). La única manera de limpiar la bandera RCIF es leyendo el/los datos del registro RCREG. El RCREG es un registro de doble buffer (una FIFO de dos posiciones).
Si las dos posiciones del registro RCREG están llenas (no han sido leídas) y se detecta el bit de Stop de un tercer dato de recepción, lo cual ocasiona un transferencia automática del dato recibido a RCREG, esto destruirá el primer dato recibido y activará el indicador de desbordamiento OERR (RCSTA<1>).
La única manera de limpiar el bit OERR una vez que ha sido activado es reseteando el módulo de recepción (limpiando CREN y volviéndolo a poner). Si el bit OERR está en 1, se inhibe la transferencia desde el registro RSR hasta el registro RCREG, por lo que es vital borrar el bit OERR, si estuviese activado.
El error de concordancia FERR (RCSTA<2>) se activa si un bit de STOP se lee en nivel bajo. Tanto este indicador como el noveno bit RX9D se memorizan en el mismo canal que el dato recibido, de manera que al leer RCREG se actualizan FERR y RX9D con nuevos valores, por lo cual estos bits deberán ser leídos antes de leer RCREG para no perder su información.
De acuerdo a lo anterior, la inicialización del módulo de recepción es como sigue:
1.   Inicializar el baud rate escribiendo al registro SPBRG el divisor adecuado y opcionalmente al bit BRGH .
2.   Habilitar el puerto serie asíncrono limpiando el bit SYNC y poniendo el bit SPEN.
3.   Si se van a usar interrupciones, poner el bit RCIE (PIE<5>).
4.   Si se desea recepción de datos de 9 bits se deberá poner el bit RX9 (RCSTA<0>).
5.   Habilitar la recepción poniendo el bit CREN (RCSTA<4>)
6.   El bit RCIF se pondrá cuando la recepción de un dato se complete y se generará una interrupción si RCIE está puesto.
7.   Leer el registro RCSTA para obtener el noveno bit (si se están recibiendo datos de 9 bits) o para determinar si ha ocurrido un error de recepción.
8.   Leer los 8 bits del dato recibido leyendo el registro RCREG.
9.   Si ocurrió algún error este se limpia al limpiar el bit CREN, el cual deberá volver a ponerse si se desea continuar la recepción.



ConfigPIC permite seleccionar algunos parámetros para configurar el módulo USART del pic, y generar el código de ayuda  ;)
(http://img139.imageshack.us/img139/2733/80990777.th.jpg) (http://img139.imageshack.us/my.php?image=80990777.jpg)
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:54:52
Ejemplo:
En este caso usando el módulo Usart del PIC16F628A y la interrupción que genera el mismo al recibir un dato haremos un ejemplo donde esperamos dato desde PC, lo recibimos y lo reenviamos inmediatamente.
Hardware necesario:
(http://img9.imageshack.us/img9/7292/hardrs232.bmp)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         DATA_RS232      equ             0x20    ; Dato recibido desde PC.-
  8.         Flags           equ             0x21    ;
  9. ;**** Definiciones para el ensamblador ****
  10. #DEFINE         Kbhit   Flags,0         ; Indica si se ha recibido algun dato.-
  11. ;**** Definición de macros ****
  12. ; Se envia la data de un registro a PC.-
  13. Putreg  macro   Registro
  14.         movfw   Registro
  15.         call    RS232_EnviaDato
  16. endm
  17. ; Se envia un literal a PC.-
  18. Putc    macro   ACKII
  19.         movlw   ACKII
  20.         call    RS232_EnviaDato
  21. endm
  22.  
  23.  
  24. ;/////////////////////////////////
  25. ;**** Inicio del Micro ****
  26. Reset.         
  27.         org     0x00            ; Aquí comienza el micro.-
  28.         goto    Inicio          ; Salto a inicio de mi programa.-
  29.  
  30. ;**** Vector de Interrupcion ****
  31.         org     0x04            ; Atiendo Interrupcion.-
  32.         goto    ISR
  33.  
  34. ; **** Programa Principal ****
  35.         org     0x05
  36. Inicio
  37.         bsf     STATUS,RP0      ; Banco 1
  38.         movlw   0x02
  39.         movwf   TRISB           ; Configuo pines para Usart.-
  40.         movlw   0x04
  41.         movwf   TXSTA           ; Configura modo asincrono, baud rate de alta velocidad
  42.         movlw   0x19            ; Configura velocidad a 9600 baudios con cristal de 4 Mhz
  43.         movwf   SPBRG
  44.         bsf     PIE1,RCIE       ; Habilita interrupcion de puerto serie para recepcion
  45.         bsf     INTCON,GIE      ; Habilitacion general interrupciones
  46.         bsf     INTCON,PEIE ; Habilitacion de interrupciones por perifericos
  47. ; Activar recepcion, transmision.-
  48.         bsf     TXSTA,TXEN      ; Habilita transmision
  49.         bcf     STATUS,RP0      ; Banco 0
  50.         bsf     RCSTA,SPEN      ; Habilitacion puerto serie
  51.         bsf     RCSTA,CREN      ; Habilita recepcion
  52.         bcf     Kbhit           ; Limpiamos bandera.
  53.  
  54. Bucle
  55.         btfss   Kbhit           ; ¿Se recibio Dato?
  56.         goto    $-1                     ; No, seguimos esperando.-
  57.         bcf     Kbhit           ; Si, borramos bandera.-
  58.         Putreg  DATA_RS232      ; Enviamos lo guardado en DATA_RS232.-
  59.         goto    Bucle           ;
  60. ;.............................................
  61. ;**** Rutina de servicio de Interrupcion ****
  62. ;**** Interrupcion por Usart (Recepcion de Dato)****
  63. ISR
  64.         btfss   PIR1,RCIF               ; Consultamos si es Usart.-
  65.         retfie                  ; No, Salimos de interrupción.-
  66.         movfw   RCREG           ; Llego dato, lo guardamos en un registro.
  67.         movwf   DATA_RS232
  68.         bsf     Kbhit           ; Indicamos que ha llegado Dato.-
  69. Fin_ISR
  70.         bcf     PIR1,RCIF               ; Limpiamos bandera.
  71.         retfie                  ; Salimos de interrupción.-
  72. ;..............................................
  73. ;**** Rutinas ****
  74. ;**** Se envia Dato ****
  75. RS232_EnviaDato
  76.         bsf     STATUS,RP0      ; Banco 1
  77.         btfss   TXSTA,TRMT      ; chequea si esta listo
  78.         goto    $-1             ; Esperamos  a que se desocupe.-
  79.         bcf     STATUS,RP0      ; Banco 0
  80.         movwf   TXREG           ; envia Dato.-
  81.         return
  82. ;...............................................
  83.         end
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 05 de Marzo de 2009, 23:58:53
Módulos de comparación analógica y tensión de referencia

El Módulo Comparador
Dispone de dos comparadores analógicos C1 y C2 cuyas entradas pueden ser seleccionadas entre los pines RA0 a RA3 y cuyas salidas pueden utilizarse para lectura digital interna o bien conectarse a dos pines de salida: RA4 y RA5. También podría ser posible emplear un nivel de tensión configurable y generado por otro bloque, el denominado Módulo de Referencia de Tensión.
El multiplexado para la selección de las entradas a comparar y las salidas a generar depende del registro de control de comparación CMCON (0x1F).
Existen 8 configuraciones posibles de entradas y salidas de comparación que se seleccionan con los 3 bits menos significativos (CM2-CM1-CM0). En ese mismo registro se pueden leer los estados en la salida de cada uno de los comparadores C1 y C2 y si se desea invertir o no la lógica del resultado de la comparación que aparece a la salida.
 Registro CMCOM
(http://img10.imageshack.us/img10/7134/comanalogico.jpg)

Bit 7.
C2OUT: Bit de salida del Comparador 2.
Cuando C2INV = 0:
Si C2Vin+>C2Vin- = 1
Si C2Vin+<C2Vin- = 0
Cuando C2INV = 1:
Si C2Vin+>C2Vin- = 0
Si C2Vin+<C2Vin- = 1

Bit 6.
C1OUT: bit de salida del Comparador 1.
Cuando C1INV = 0:
Si C1Vin+>C1Vin- = 1
Si C1Vin+<C1Vin- = 0
Cuando CINV = 1:
Si C1Vin+>C1Vin- = 0
Si C1Vin+<C1Vin- = 1

Bit5.
C2INV: Bit de inversión de la salida del Comparador 2.
1 = C2 Salida invertida.
0 = C2 Salida no invertida.

Bit 4.
C1INV: Bit de inversión de la salida del Comparador 1.
1 = C1 Salida invertida.
0 = C1 Salida no invertida.

Bit 3.
CIS: Selector de pin de entrada al Comparador.
Cuando CM<2:0> = 001:
1 = C1Vin- conectado a RA3.
0 = C1Vin- conectado a RA0.
Cuando CM<2:0> = 010:
1 = C1Vin- conectado a RA3.
      C2Vin- conectado a RA2.
0 = C1Vin- conectado a RA0.
      C2Vin- conectado a RA1.

Bit 2-0.
CM<2:0>: bits de selección de configuración de los Comparadores.
(http://img3.imageshack.us/img3/5291/comanalogico2.jpg)

Modo de Trabajo de los Comparadores
(http://img3.imageshack.us/img3/6232/comanalogico3.jpg)

Las áreas sombreadas de la salida del comparador en la figura representan la incertidumbre debido a tensiones de desviación y tiempo de respuesta.

Referencias de Comparación
La referencia de tensión para la comparación puede ser:
Externa: se conectará a cualquiera de los pines de entrada externos del comparador y esa tensión deberá estar comprendida entre VDD y VSS
Interna: se puede emplear una referencia de tensión generada a nivel interno por parte de un módulo interno específico presente dentro del microcontrolador cuando se configuran los bits CM<2:0> con la combinación 110

Módulo de Referencia de Tensión para Comparación
Se trata de un divisor resistivo a partir de la tensión de alimentación del microcontrolador.
Registro VRCON (9Fh)
(http://img9.imageshack.us/img9/5961/comanalogico5.jpg)

(http://img3.imageshack.us/img3/3337/comanalogico4.jpg)

VR<3:0> Selección de la tensión de referencia:
Si VRR = 1:
\mathrm{Vref}=\frac{\mathrm{VR<3:0>.Vdd}}{24}
Si VRR = 0:
\mathrm{Vref}=\left(\mathrm{Vdd}.\frac{1}{4}\right)+\frac{\mathrm{VR<3:0>.Vdd}}{32}
Interrupciones del Módulo de Comparación
El módulo de comparación puede generar una interrupción por activación del flag CMIF (Flag de Interrupción del Comparador) presente en el registro PIR1. El flag CMIF se pondrá a 1 si se produce un cambio en la salida de cualquiera de los dos comparadores (C1OUT ó C2OUT) desde la última lectura que se realizó del registro CMCON.
El flag debe ponerse a cero por software pero además debe realizarse previamente una operación de lectura (o escritura) del registro CMCON para que deje de darse la discrepancia entre el valor actual y el valor leído. Para que se produzca la interrupción deben encontrarse activadas la máscara particular (CMIE en PIE2), la de periféricos (PEIE) y la global (GIE).

Característica especial del Módulo Comparador
Si un comparador se encuentra activo y se sitúa al microcontrolador en modo de bajo consumo (SLEEP), el comparador permanecerá activo y las interrupciones si están activadas mediante sus máscaras serán funcionales y podrán sacar al micro de su modo de bajo consumo si cambia la salida de alguno de los comparadores desde la última lectura.


ConfigPIC permite seleccionar la configuración del módulo comparador analógico y tensión de referencia, generando el código de configuración.
(http://img15.imageshack.us/img15/8679/18884242.th.jpg) (http://img15.imageshack.us/my.php?image=18884242.jpg)
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: Suky en 06 de Marzo de 2009, 00:01:51
A modo de ejemplo conectaremos un potenciómetro al comparador 1, fijando una tensión de referencia interna a 3.59 Volt e invirtiendo la salida del comparador. Cuando la tensión sobre el pin RA0 (C1Vin-) sea mayor a 3.59 Volt haremos titilar un led 10 veces a modo de alarma.
Hardware necesario:
(http://img14.imageshack.us/img14/9623/companalogico.bmp)

Diagrama de Flujo:
(http://img8.imageshack.us/img8/7638/flujocomp.jpg)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7. Contador1       equ     0x20    ; Registro utilizado para demora.-
  8. Contador2       equ     0x21    ; Registro utilizado para demora.-
  9. Loop            equ     0x22    ;
  10. ;**** Definiciones para el ensamblador ****
  11. #DEFINE         Led     PORTB,0 ; Led ubicado en Puerto B, bit 0.-
  12. ;/////////////////////////////////
  13. ;**** Inicio del Micro ****
  14. Reset.         
  15.         org             0x00            ; Aquí comienza el micro.-
  16.         goto    Inicio          ; Salto a inicio de mi programa.-
  17.  
  18. ;**** Vector de Interrupcion ****
  19.         org     0x04            ; Atiendo Interrupcion.-
  20.         goto    ISR
  21.  
  22. ; **** Programa Principal ****
  23.         org     0x05
  24. Inicio
  25.         movlw   0x12            ; Seleccionamos 2 comparadores con Vref interna.
  26.                                                 ; C1Vin- -> RA0, C2Vin- -> RA1.
  27.                                                 ; Salida de comparador 1 invertida.
  28.         movwf   CMCON
  29.         bsf     STATUS,RP0      ; Banco 1
  30.         movlw   0x03            ; RA0 y RA1 como entrada.-
  31.         movwf   TRISA
  32.         clrf    TRISB           ; PORTB como salida.-
  33.         movlw   0xAF            ; Vref activado, Low, VR<3:0>=15 (Vref=3.59 Volt).-
  34.         movwf   VRCON
  35.  
  36.         bcf     STATUS,RP0      ; Banco 0.-
  37.         clrf    PORTB
  38.         movf    CMCON,f         ; Operacion de lectura.-
  39.         bcf     PIR1,CMIF               ; Limpiamos bandera.-
  40.  
  41.         bsf     STATUS,RP0      ; Banco 1.-
  42.         bsf     PIE1,CMIE               ; Habilitamos interrupcion por comparador analogico.
  43.         bsf     INTCON,PEIE     ; Habilitacion de Interrupcion por perifericos.-
  44.         bsf     INTCON,GIE      ; Habilitacion general de interrupciones.-
  45.         bcf     STATUS,RP0      ; Banco 0.-
  46. Bucle
  47.         nop
  48.         goto    Bucle
  49. ;.............................................
  50. ;**** Rutina de servicio de Interrupcion ****
  51. ;**** Interrupcion por Comparador Analogico****
  52. ISR
  53.         btfss   PIR1,CMIF               ; Interrupcion por Comparador?
  54.         retfie                  ; No, salimos de interrupcion.-
  55.         btfss   CMCON,C1OUT     ; Consultamos estado del comparador.-
  56.         goto    Fin_ISR         ; Si es 0 salimos de interrupcion.-
  57.         call    Alarma          ; Si es 1, indicamos una alarma.-
  58. Fin_ISR
  59.         movf    CMCON,f         ; Operacion de lectura.-
  60.         bcf     PIR1,CMIF               ; Limpiamos bandera.-
  61.         retfie
  62. ;..............................................
  63. ;**** Rutinas ****
  64. Alarma
  65.         movlw   0x0A            ; Hacemos titilar 10 veces el Led.-
  66.         movwf   Loop
  67.         bsf     Led
  68.         call    Demora_150ms
  69.         bcf     Led
  70.         call    Demora_150ms
  71.         decfsz  Loop
  72.         goto    $-5
  73.         return
  74. ;**** Demora ****
  75. Demora_150ms
  76.         movlw   0xFF            ;
  77.         movwf   Contador1               ; Iniciamos contador1.-
  78. Repeticion1
  79.         movlw   0xC3            ;
  80.         movwf   Contador2               ; Iniciamos contador2
  81. Repeticion2
  82.         decfsz  Contador2,1     ; Decrementa Contador2 y si es 0 sale.-        
  83.         goto    Repeticion2     ; Si no es 0 repetimos ciclo.-
  84.         decfsz  Contador1,1     ; Decrementa Contador1.-
  85.         goto    Repeticion1     ; Si no es cero repetimos ciclo.-
  86.         return                  ; Regresa de la subrutina.-
  87. ;.................................................
  88.         end
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 06 de Marzo de 2009, 00:23:28
Módulo CCP

Introducción

Los microcontroladores PIC16F628A/648A disponen de un modulo de Captura/Comparación/PWM que en conjunto con los temporizadores, permite realizar en forma sencilla las tareas de medición de tiempo y frecuencia, y generación de señales digitales.
El modulo CCP tiene 3 modos de funcionamiento, que se describen a continuación:

A continuación se da un breve resumen de los registros relacionados con cada módulo:
El registro principal de este módulo se compone de dos registros de 8 bits, denominados CCPR1H (16h) (parte más significativa) y CCPR1L (15h) (parte menos significativa). La operación del módulo se controla mediante el registro CCP1CON (17h) y el disparo de evento especial, el cual es generado al alcanzarse la igualdad en un registro de comparación reseteará el Timer 1.

Selección del modo de operación:
La selección del modo en que trabajara el módulo CCP se realiza mediante los cuatro bits menos significativos del registro CCP1CON, es decir, mediante los bits CCP1M3:CCP1M0 (CCP1CON<3:0>) de acuerdo a lo siguiente:


 El Modo de Captura
En el modo de captura el registro CCPR1 (CCPR1H:CCPR1L) captura el valor de 16 bits registro TMR1 cuando ocurre un evento en la patita RB3/CCP1. El evento en cuestión puede especificarse previamente como alguno de los siguientes:
Además de que el valor de TMR1 es capturado, la bandera de solicitud de interrupción CCP1IF es activada, la cual deberá ser limpiada por software para poder detectarla si se está consultando por poleo.
El tipo de acción que se desea detectar en esta patita se configura mediante los bits de control CCP1M3:CCP1M0 (CCP1CON<3:0>). Si ocurre otro evento de captura antes de que haya sido leído el registro CCPR1, el valor capturado anterior se perderá, ya que con la nueva captura este registro es reescrito.
En la figura siguiente se muestra un diagrama de bloques en donde se ilustra la manera en que trabaja el módulo CCP en modo de captura:

(http://img9.imageshack.us/img9/1541/ccp6280.jpg)

El preescalador del CCP
El valor del preescalador se configura mediante los bits CCP1M3:CCP1M0. Sin embargo, al realizar un cambio en la configuración del preescalador se puede generar una interrupción falsa, para evitar lo anterior se deberá apagar el modulo CCP (limpiando el registro CCP1CON) previamente al cambio de valor del preescalador.
Este preescalador es independiente al preescalador del Timer 1 (el cual puede usarse como ya se explicó con sus posibles divisores de 1/1, 1/2, 1/4, 18).

Configuraciones:
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 18:22:51
Ejemplo:
Para ejemplificar el uso del modulo CCP en modo captura vamos a realizar la medida del periodo de una onda cuadrada para así determinar su frecuencia. La forma de trabajar va a ser la siguiente:
Configuramos CCP modo captura con cada transición de subida del pin RB3/CCP1 con Timer1 modo temporizador 1/1.
Al llegar un flanco ascendente, reseteamos Timer1 y esperamos al siguiente flanco ascendente, en el cual se guarda el valor capturado y lo enviamos a la PC para poder determinar la frecuencia de la señal. Lo que hemos capturado es la cantidad de ciclos de reloj transcurridos en un ciclo de la señal a medir. Con este valor y el Tosc al cual trabaja el microcontrolador podemos determinar el periodo de la señal.
\mathrm{Periodo[s]}=\left(\frac{4}{\mathrm{20MHz}}\right)\cdot\mathrm{CCPR1}
\mathrm{Frecuencia[Hz]}=\frac{1}{\mathrm{Periodo}}

Con un cristal de 20 MHz podemos medir desde aprox. 77Hz hasta los 500kHz, claro que a más frecuencia más error en las mediciones. Por ejemplo, con algunos ensayos que he realizado a 1kHz se tiene un error de +-1Hz, 10kHz +-5Hz, 100kHz +- 0.5kHz, 200kHz +- 2kHz, etc.

Para determinar la frecuencia adjunto un programita hecho en Visual Basic que toma 10 valores enviados desde el microcontrolador, calcula un promedio del periodo y determina la frecuencia. Se hace de este modo para reducir el error cometido a altas frecuencias.

(http://img10.imageshack.us/img10/347/frecuencimetro.jpg)

Hardware necesario:

(http://img16.imageshack.us/img16/5455/hardrs232ccp.png)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         Msb                     equ             0x20    ; Guarda Byte alto de Captura para enviar por RS232
  8.         Lsb                     equ             0x21    ; Guarda byte bajo de Captura para enviar por RS232
  9.         Contador1       equ             0x22    ; Para demora
  10.         Contador2       equ             0x23    ; Para demora
  11. ;**** Definiciones para el ensamblador ****
  12.  
  13. ;**** Definición de macros ****
  14. ; Se envia la data de un registro a PC.-
  15. Putreg  macro   Registro
  16.         movfw   Registro
  17.         call    RS232_EnviaDato
  18. endm
  19.  
  20. ;/////////////////////////////////
  21. ;**** Inicio del Micro ****
  22. Reset.         
  23.         org             0x00            ; Aquí comienza el micro.-
  24.         goto    Inicio          ; Salto a inicio de mi programa.-
  25.  
  26. ; **** Programa Principal ****
  27.         org             0x05
  28. Inicio
  29.         bsf             STATUS,RP0      ; Banco 1
  30.         movlw   b'00001010'     ; RB1 entrada, RB2 salida, RB3 entrada.
  31.         movwf   TRISB          
  32.         movlw   0x04
  33.         movwf   TXSTA           ; Configura modo asincrono, baud rate de alta velocidad
  34.         movlw   0x81            ; Configura velocidad a 9600 baudios con cristal de 20 Mhz
  35.         movwf   SPBRG
  36.         bsf     TXSTA,TXEN      ; Habilita transmision
  37.         bcf             STATUS,RP0      ; Banco 0.-
  38.         bsf             RCSTA,SPEN      ; Habilitacion puerto serie
  39.  
  40.         movlw   b'00000001'     ; Se selecciona TMR1, preescaler de 1/1, modo temporizador.-
  41.         movwf   T1CON
  42.         movlw   b'00000101'     ; Se configura CCP modo captura cada flanco de subida.-
  43.         movwf   CCP1CON
  44. Bucle
  45.         bcf             PIR1,CCP1IF     ; Borramos bandera
  46.         btfss   PIR1,CCP1IF     ; Testeamos bandera.-
  47.         goto    $-1                     ; Si no se activo seguimos esperando
  48.         bcf             PIR1,CCP1IF     ; Se activo, la borramos.-
  49.         clrf    TMR1H           ; Borramos Timer1.-    
  50.         clrf    TMR1L           ;      
  51.         btfss   PIR1,CCP1IF     ; Volvemos a testear bandera.-
  52.         goto    $-1                     ; No se activo, seguimos esperando.-
  53.         movfw   CCPR1L          ; Copiamos el valor capturado.-
  54.         movwf   Lsb
  55.         movfw   CCPR1H         
  56.         movwf   Msb
  57.         Putreg  Msb                     ; Enviamos lo guardado en el registro Msb.-
  58.         Putreg  Lsb                     ; Enviamos lo guardado en el registro Lsb.-
  59.         call    Demora_30ms
  60.         goto    Bucle           ;
  61. ;..............................................
  62. ;**** Rutinas ****
  63. ;**** Se envia Dato ****
  64. RS232_EnviaDato
  65.         bsf             STATUS,RP0      ; Banco 1
  66.         btfss   TXSTA,TRMT  ; chequea si esta listo
  67.         goto    $-1                     ; Esperamos  a que se desocupe.-
  68.         bcf             STATUS,RP0      ; Banco 0
  69.         movwf   TXREG           ; envia Dato.-
  70.         return
  71. ;...............................................
  72. ; *** Demora****
  73. Demora_30ms
  74.         movlw   0xFF                    ;
  75.         movwf   Contador1               ; Iniciamos contador1.-
  76. Repeticion1
  77.         movlw   0xC3                    ;
  78.         movwf   Contador2               ; Iniciamos contador2
  79. Repeticion2
  80.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  81.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  82.         decfsz  Contador1,1             ; Decrementa Contador1.-
  83.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  84.         return                                  ; Regresa de la subrutina.-
  85. ;...............................................
  86.         end

Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 18:27:05
El Modo Comparador
En el modo de comparación el registro de 16 bits CCPR1 (CCPR1H:CCPR1L) se compara constantemente con el valor del registro de 16 bits TMR1. De manera que cuando sus valores coinciden además de activarse la bandera para solicitar interrupción CCP1IF (PIR1<2>), puede ocurrir en la patita RB3/CCP1 (previa configuración) alguna de las siguientes acciones:
La acción que ocurra en esta patita se configura mediante los bits de control CCP1M3:CCP1M0 (CCP1CON<3:0>). En la figura siguiente se muestra un diagrama de bloques en donde se ilustra la manera en que trabaja el módulo CCP en modo comparador
(http://img15.imageshack.us/img15/6833/ccp6281.jpg)

Configuraciones:

Ejemplo:
En este programa se hace uso del modo de comparación para realizar la conmutación de una señal cada vez que transcurre un tiempo, el cual se ajusta al oprimir un pulsador de incremento o uno de decremento.

Hardware necesario:
(http://img17.imageshack.us/img17/9763/comparacionhard.png)

[/list]
Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         decre   equ             0       ; Pulsador para decrementar periodo
  8.         incre   equ             1       ; Pulsador para incrementar periodo
  9.  
  10. ;/////////////////////////////////
  11. ;**** Inicio del Micro ****
  12. Reset.         
  13.         org             0x00            ; Aquí comienza el micro.-
  14.         goto    Inicio          ; Salto a inicio de mi programa.-
  15.  
  16. ; **** Programa Principal ****
  17.         org             0x05
  18. Inicio
  19.         movlw   0x07            ; Para deshabilitar comparadores analogicos.-
  20.         movwf   CMCON
  21.         bsf             STATUS,RP0      ; Banco 1
  22.         bsf             TRISA,decre     ; Como entrada.-
  23.         bsf             TRISA,incre     ; Como entrada.-
  24.         bcf             TRISB,3         ; RB3 como Salida.
  25.         bcf             STATUS,RP0      ; Banco 0.-
  26.         movlw   b'00000001'     ; Se selecciona TMR1, preescaler de 1/1, modo temporizador.-
  27.         movwf   T1CON
  28.         movlw   0x80            ; Inicia periodo de comparacion a mitad de rango.-
  29.         movwf   CCPR1H
  30.         movlw   0x00
  31.         movwf   CCPR1L
  32.         movlw   b'00001000'     ; Se configura CCP modo comparación, setea salida con coincidencia.-
  33.         movwf   CCP1CON
  34.         clrf    TMR1H           ; Comenzamos generacion de señal.-
  35.         clrf    TMR1L
  36. Bucle
  37.         bcf             PIR1,CCP1IF     ; Borramos bandera
  38.         btfss   PIR1,CCP1IF     ; Testeamos bandera.
  39.         goto    $-1                     ; Si no se activo seguimos esperando
  40.         bcf             PIR1,CCP1IF     ; Se activo, la borramos.
  41.         movlw   b'00000001'     ; Invertimos ultimo bit, para pasar de setear a resetear...
  42.         xorwf   CCP1CON,1       ; o viceversa.-
  43.         clrf    TMR1H           ; Reseteamos cuenta Timer1.
  44.         clrf    TMR1L           ;
  45.         btfsc   PORTA,decre     ; Testea pulsador para decrementar periodo.-
  46.         call    Decrementa
  47.         btfsc   PORTA,incre     ; Testea pulsador para incrementar periodo.-
  48.         call    Incrementa
  49.         goto    Bucle           ;
  50. ;..............................................
  51. ;**** Rutinas ****
  52. Decrementa
  53.         decf    CCPR1L,1        ; Decrementa parte baja.-
  54.         comf    CCPR1L,w        ; Carga el negado a W, si CCPR1L=0xFF -> W=0x00.-
  55.         btfss   STATUS,Z        ; Si W=0x00 decrementamos parte alta.-
  56.         return                          ; No.-
  57.         decf    CCPR1H,1        ; Decrementa parte alta.-
  58.         return
  59. ;..............................................
  60. Incrementa
  61.         incf    CCPR1L,1        ; Incrementa parte baja.-
  62.         btfss   STATUS,Z        ; CCPR1L=0x00?
  63.         return                          ; No.-
  64.         incf    CCPR1H,1        ; Si, incrementa parte alta
  65.         return
  66.        
  67. ;...............................................
  68.         end
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 18:32:44
Modo PWM (Modulación de Ancho de Pulso).

Con este modo de trabajo se consiguen impulsos lógicos cuya anchura del nivel alto es de duración variable, que son de enorme aplicación en el control de dispositivos tan populares como los motores y triacs.
El pin RB3/CCP1 esta configurado como salida y cambia entre los niveles 0 y 1 a intervalos de tiempos variables,  logrando un pulso cuyo nivel alto tiene un ancho variable dentro del intervalo del periodo de trabajo:

(http://img23.imageshack.us/img23/5449/ccp6283.jpg)

La base de tiempos es el Timer2 más dos bits adicionales para tener los 10.
El periodo se determina con el registro PR2, ya que cuando TMR2=PR2:

(http://img14.imageshack.us/img14/9973/ccp6282.jpg)
De esta manera, de acuerdo a la figura anterior, el siguiente valor de comparación para TMR2 en el comparador de 10 bits es el Ciclo de Trabajo, el cual al alcanzarse limpiará la patita CCP1.
El ciclo de trabajo se determina con el contenido del CCPR1L y los dos bits de CCP1CON (CCP1X y CCP1Y).

Periodo del PWM

\mathrm{PeriodoPWM}=\left(\mathrm{PR2} + 1 \right)\cdot 4\cdot\mathrm{Tosc}\cdot\mathrm{TMR2 Preescaler}

\mathrm{FrecuenciaPWM}=\frac {1}{\mathrm{PeriodoPWM}}

Ciclo de Trabajo del PWM
El ciclo de Trabajo se especifica escribiendo un valor de 10 bits al registro CCPR1L (los 8 bits más significativos (msb)) y los dos bits menos significativos (lsb) a CCP1CON<5:4>.

\mathrm{CTPWM}=\left(\mathrm{CCPR1L:CCP1CON<5:4>}\right)\cdot\mathrm{Tosc}\cdot\mathrm{TMR2 Preescaler}

Como se puede ver en la figura anterior, el valor que determina la duración de C.T. del PWM no es el cargado en CCPR1L, sino en CCPR1H, el cual sólo se actualiza en el momento en que TMR2 alcanza el valor de PR2 (es decir, cada vez que se completa un periodo). Por ello, aunque CCPR1L puede ser escrito en cualquier momento, el Ciclo de Trabajo solo se actualiza hasta que termina el periodo que está en transcurso.
No hay otra manera de escribir al registro CCPR1H, ya que este es un registro de sólo lectura.

El número de divisiones que se pueden tener en un Ciclo de Trabajo será
2^{n}
, donde n es el número de bits usados, por lo tanto su duración máxima será:
\mathrm{CTPWM}=2^{n}\cdot\mathrm{Tosc}\cdot\mathrm{TMR2 Preescaler}

Sin embargo, dependiendo del valor de Ciclo de trabajo máximo (CT_PWM) deseado, no será posible realizar las
2^{n}
divisiones y por lo tanto no se podrán usar los n bits de resolución. O al revés, si se elige una resolución deseada n no será posible tener cualquier Ciclo de Trabajo máximo (CT_PWM) Deseado.

De la ecuación anterior se puede despejar cual es la resolución máxima:
\mathrm{ResolucionPWM}=\frac{\log\left(\frac{\mathrm{CTPWM}}{\mathrm{Tosc}\cdot\mathrm{TMR2 Preescaler}}\right)}{\log 2}

Veamos con un ejemplo, si fijamos PR2 en 100 y usamos preescaler 1/4 con un oscilador de 20 MHz, tendremos un PWM de periodo 80.8us. El ciclo de trabajo no puede superar este valor por lo que despejando de las ecuaciones anteriores, CCPR1L:CCP1CON<5:4> no puede ser mayor a 404. Aquí se ve claramente que no se pueden usar los 10 bits de resolución, sino “8.66” bits. Caso contario el pin RB3/CCP1 nunca será reseteado.

En la siguiente tabla se resumen diversas elecciones de resolución n y la correspondiente frecuencia F_PWM máxima, así como el valor de PR2 con el que se logra (para un frecuencia del cristal de 20 Mhz).

(http://img11.imageshack.us/img11/2681/ccp6284.jpg)

Secuencia de configuración del PWM
A continuación se resumen los pasos para realizar la configuración inicial del PWM:
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 18:34:33
Ejemplo:

Como ejemplo generaremos dos frecuencias distintas seleccionables mediante la acción de un pulsador conectador a RB0. Una de las señales será de 500Hz y la otra de 2kHz, con ciclo de trabajo de 50%.

Con oscilador de 4MHz y preescaler 1/16 tendremos:

Señal de 500HzPR2=124 (0x7C)CCPR1L&2bits=250(0xFA)CCPR1L=0x3E & 2bits=10
Señal de 2kHzPR2=30 (0x1E)CCPR1L&2bits=62 (0x3E)CCPR1L=0x0F & 2bits=10

Hardware necesario:

(http://img17.imageshack.us/img17/9135/pwm.png)
Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         Flags   equ             0x20    ; Registro para guardar banderas.-
  8.  
  9.         Selec   equ             0               ; Bit para indicar seleccion(Selec=1->500Hz; Selec=0->2kHz).-
  10. ;**** Definiciones para el ensamblador ****
  11.         #define Signal Flags,Selec
  12.        
  13.        
  14. ;/////////////////////////////////
  15. ;**** Inicio del Micro ****
  16. Reset.         
  17.         org             0x00            ; Aquí comienza el micro.-
  18.         goto    Inicio          ; Salto a inicio de mi programa.-
  19.  
  20. ; **** Programa Principal ****
  21.         org             0x05
  22. Inicio
  23.         bsf             STATUS,RP0      ; Banco 1
  24.         bsf             TRISB,0         ; Como Entrada.-
  25.         bcf             TRISB,3         ; RB3 como Salida.
  26.         bcf             STATUS,RP0      ; Banco 0.-
  27.         movlw   b'00000110'     ; Se selecciona TMR2, preescaler de 1/16.-
  28.         movwf   T2CON
  29.         bsf             STATUS,RP0      ; Banco 1
  30.         movlw   0x7C            ; Inicia periodo de 500Hz.-
  31.         movwf   PR2
  32.         bcf             STATUS,RP0      ; Banco 0.-
  33.         bsf             Signal
  34.         movlw   0x3E            ; Ciclo de trabajo 50%
  35.         movwf   CCPR1L
  36.         bsf             CCP1CON,CCP1X
  37.         bcf             CCP1CON,CCP1Y
  38.         bsf             CCP1CON,CCP1M3  ; Configura modulo CCP modo PWM.-
  39.         bsf             CCP1CON,CCP1M2
  40. Bucle
  41.         btfss   PORTB,0         ; Testea si se quiere cambiar de Frecuencia.-
  42.         goto    $-1                     ; No se quiere cambiar.-
  43.         btfss   Signal          ; A cual cambiar?
  44.         goto    Cambiar500Hz
  45. Cambiar2kHz
  46.         bsf             STATUS,RP0      ; Banco 1
  47.         movlw   0x1E
  48.         movwf   PR2    
  49.         bcf             STATUS,RP0      ; Banco 0
  50.         bcf             Signal          ; Señal de 2kHz
  51.         movlw   0x0F            ; Ciclo de trabajo 50%
  52.         movwf   CCPR1L
  53.         goto    Bucle           ;
  54.  
  55. Cambiar500Hz
  56.         bsf             STATUS,RP0      ; Banco 1
  57.         movlw   0x7C            ; Inicia periodo de 500Hz.-
  58.         movwf   PR2                     ; Señal de 500 Hz.-
  59.         bcf             STATUS,RP0      ; Banco 0.-
  60.         bsf             Signal
  61.         movlw   0x3E            ; Ciclo de trabajo 50%
  62.         movwf   CCPR1L 
  63.         goto    Bucle
  64. ;...............................................
  65.         end
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 18:37:34
Otro ejemplo:
En este se fija la frecuencia de PWM en 2 kHz y se varía el ciclo de trabajo con 2 pulsadores de control conectados a RB0 y RB1. Solo se modifica en byte alto del CT, ósea el registro CCPR1L con lo que CT se varía de 4 en 4.

Hardware necesario:

(http://img9.imageshack.us/img9/2410/pwm2.png)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         Contador1       equ             0x20    ;
  8.         Contador2       equ             0x21    ;
  9.        
  10.         decre   equ             0       ; Pulsador para decrementar Ciclo de Trabajo
  11.         incre   equ             1       ; Pulsador para incrementar Ciclo de Trabajo
  12.        
  13.        
  14. ;/////////////////////////////////
  15. ;**** Inicio del Micro ****
  16. Reset.         
  17.         org             0x00            ; Aquí comienza el micro.-
  18.         goto    Inicio          ; Salto a inicio de mi programa.-
  19.  
  20. ; **** Programa Principal ****
  21.         org             0x05
  22. Inicio
  23.         bsf             STATUS,RP0      ; Banco 1
  24.         bsf             TRISB,incre     ; Como Entrada.-
  25.         bsf             TRISB,decre     ; Como Entrada.-
  26.         bcf             TRISB,3         ; RB3 como Salida.
  27.         bcf             STATUS,RP0      ; Banco 0.-
  28.         movlw   b'00000110'     ; Se selecciona TMR2, preescaler de 1/16.-
  29.         movwf   T2CON
  30.         bsf             STATUS,RP0      ; Banco 1
  31.         movlw   0x1E            ; Señal de 2kHz
  32.         movwf   PR2    
  33.         bcf             STATUS,RP0      ; Banco 0
  34.         clrf    CCPR1L          ; Ciclo de trabajo 0%
  35.         bcf             CCP1CON,CCP1X
  36.         bcf             CCP1CON,CCP1Y
  37.         bsf             CCP1CON,CCP1M3  ; Configura modulo CCP modo PWM.-
  38.         bsf             CCP1CON,CCP1M2
  39. Bucle
  40.         btfsc   PORTB,decre     ; Testea si se quiere reducir CT.-
  41.         goto    Decrementa
  42.         btfsc   PORTB,incre     ; Testea si se quiere aumentar CT.-
  43.         goto    Incrementa
  44.         goto    Bucle
  45. Incrementa
  46.         incf    CCPR1L,1
  47.         call    Demora_50ms
  48.         goto    Bucle
  49. Decrementa
  50.         decf    CCPR1L,1
  51.         call    Demora_50ms
  52.         goto    Bucle
  53.  
  54.  
  55. ;**** Demora ****
  56. Demora_50ms
  57.         movlw   0xFF                    ;
  58.         movwf   Contador1               ; Iniciamos contador1.-
  59. Repeticion1
  60.         movlw   0x40                    ;
  61.         movwf   Contador2               ; Iniciamos contador2
  62. Repeticion2
  63.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  64.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  65.         decfsz  Contador1,1             ; Decrementa Contador1.-
  66.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  67.         return                                  ; Regresa de la subrutina.-
  68. ;..............................................
  69.         end
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: WillyP en 31 de Marzo de 2009, 19:02:30
Excelente Suky, vaya que te has tomado trabajo y dedicación con este aporte. :)  Te felicito.
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: Suky en 31 de Marzo de 2009, 19:03:05
Mas info:

Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: marvicdigital en 11 de Abril de 2009, 02:27:09
Suky..muchas gracias por tu valioso aporte a la comunidad, estoy mur agradecido contigo...de verdad que si pudiera te envitaba a un buen par de cervezas..como se nota que trabajas para enseñar..trabajas más que le registro W  :mrgreen:..

Saludos y de nuevo mil gracias.

Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 11 de Abril de 2009, 21:00:19
Citar
de verdad que si pudiera te envitaba a un buen par de cervezas..

Venga, venga!  :D  :D  :D

Saludos!!!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: gasparin en 13 de Abril de 2009, 00:30:11
Suky te has mandado con este excelente y completo tutorial
Mi reconocimiento a gran esfuerzo de tu parte
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: gcgiron en 18 de Abril de 2009, 22:56:56
Suki, y demas participantes del foro, muchas gracias por este tutorial; para mi que estoy empezando es una buena forma de ser guiado paso a paso.

Les animo a que sigan compartiendo la información y los conocimientos, que ya nos llegará el momento, a los que somos nuevos, de compartir y enseñar.

Guido.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: kaneda en 30 de Abril de 2009, 19:05:55
Muy buena info sobre los perifericos del PIC16F628A... queria saber si tienes idea de cuanto es el valor maximo de tension que soportan las entradas analogicas del pic para usarlo como comparador. supongo que es vdd pero no estoy seguro. muchas gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 30 de Abril de 2009, 19:58:26
Muy buena info sobre los perifericos del PIC16F628A... queria saber si tienes idea de cuanto es el valor maximo de tension que soportan las entradas analogicas del pic para usarlo como comparador. supongo que es vdd pero no estoy seguro. muchas gracias

Si exactamente, entre Vss y Vdd. Fíjate en el datasheet del micro que internamente tiene 2 diodos en serie que limitan la tensión de entrada entre -0.3V y 5.3V...
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: acervantes en 09 de Mayo de 2009, 14:01:59
Muy buen aporte para personas como yo que estan empezando en esto de los PICs, gracias por tu aporte.

Solo que tengo la siguiente duda. Encontre el siguiente programador PIC JDM, creen que funcione para un 16F628A? o hay que modificar algo para que funcione bien?.

(http://img11.imageshack.us/img11/3193/diagramajdm.jpg)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 09 de Mayo de 2009, 16:42:55
Al principio del hilo, donde esta el índice, deje un comprimido con un JDM más general. Te conviene armarte ese ya que tiene casi los mismos componentes y vas a poder grabar mayor variedad de micros (Para el futuro). :wink:
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: acervantes en 10 de Mayo de 2009, 03:41:02
Al principio del hilo, donde esta el índice, deje un comprimido con un JDM más general. Te conviene armarte ese ya que tiene casi los mismos componentes y vas a poder grabar mayor variedad de micros (Para el futuro). :wink:

Gracias por responder. En efecto armare el programador que tu tienes ya que lo tienes probado para un 16F628A-I/P.
Otra duda: ¿Crees que funcione de igual forma si le pongo el sustituto de los Transistores?
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 10 de Mayo de 2009, 03:59:59
A que sustituto te refieres? Igual no creo que haya problemas...
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 17 de Mayo de 2009, 01:24:21
Control de Displays con 74LS164

Aquí realizo un nuevo ejemplo de manejo de varios displays de 7 segmentos. En este caso realizaremos el control de 3 displays con la ayuda del registro de desplazamiento 74LS164. Las ventajas que conlleva el uso de este CI es que no necesitaremos multiplexar la señal enviada a los displays, algo que limita mucho al microcontrolador, ya que debe refrescarlos continuamente. Y la desventaja es que necesitaremos un 74LS164 por cada display.

Hardware: (los pines 7 y 14 del 74LS164 van a GND y 5V, y se debe agregar una resistencia a cada linea que une el 74LS164 con el display)
(http://img206.imageshack.us/img206/451/74ls164displays.th.png) (http://img206.imageshack.us/my.php?image=74ls164displays.png)

Con este circuito se pueden manejar 3 displays + los 3 puntos. El primer bit que ingresa será empujado por los demás. Ejemplo para enviar 12.7:
(http://img526.imageshack.us/img526/1757/001hvs.jpg)


Código: 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. Display1        equ             0x0C    ; Valor que luego de convertido se enviara al Display 1
  7. Display2        equ             0x0D    ; Valor que luego de convertido se enviara al Display 2
  8. Display3        equ             0x0E    ; Valor que luego de convertido se enviara al Display 3
  9. DataEnviar      equ             0x0F    ; Dato convertido a codigo 7 Segmentos a enviar
  10. ContBits        equ             0x10    ; Para controlar el envio de bits
  11.  
  12. Desc            equ             0               ; Definimos Pulsador descendente.-
  13. Asc                     equ             1               ; Definimos Pulsador ascendente.-
  14. BClock          equ             0               ; Pin reloj del 74LS164
  15. BData           equ             1               ; Pin data del 74LS164
  16. BReset          equ             2               ; Pin Reset del 74LS164
  17. Pto                     equ             0               ; Bit punto, Con este indicamos si se muestra punto.-
  18.        
  19. Resett          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'abcdefg0'  para display catodo comun
  26.                         addwf   PCL,1           ; Se incrementa el contador del programa.-
  27.                         DT 0xFC , 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6 
  28.  
  29. ;**** Programa principal ****
  30. ;**** Configuracion de puertos ****
  31. Inicio          bsf             STATUS,RP0      ; Pasamos de Banco 0 a Banco 1.-
  32.                         movlw   b'11111000'     ; RB7 como entrada y los demas como salida.-
  33.                         movwf   TRISB
  34.                         bcf             STATUS,RP0      ; Paso del Banco 1 al Banco 0
  35.                         clrf    Display1
  36.                         clrf    Display2
  37.                         clrf    Display3
  38.                         bsf             PORTB,BReset    ; Habilitamos 74LS164.-
  39.                         bcf             PORTB,BData
  40.                         bsf             PORTB,BClock    ; Seteamos Clock.-
  41.  
  42.                         goto    ActualizoDisplays
  43.  
  44. ;**** Testeo de Pulsador ****
  45. Testeo
  46.                         btfss   PORTA,Desc      ; Testeamos si esta a 1 logico.-
  47.                         goto    Descender       ; No
  48.                         btfss   PORTA,Asc       ; Testeamos si esta a 1 logico.-
  49.                         goto    Ascender                                               
  50.                         goto    Testeo          ; Si, Testeamos nuevamente.-
  51.  
  52.  
  53.  
  54. ;**** Rutinas ****
  55. Descender
  56.                         btfss   PORTA,Desc      ;
  57.                         goto    $-1                     ; Esperamos hasta que se suelte.-
  58.                         decf    Display1,1      ; Decremento Display1.
  59.                         movlw   d'255'          ; Si paso de 0 a 255...
  60.                         subwf   Display1,0      ; decremento Display2
  61.                         btfss   STATUS,Z        ;
  62.                         goto    ActualizoDisplays       ; no es 255
  63.                         movlw   d'9'
  64.                         movwf   Display1        ; Si, cargo 9.-        
  65.                         decf    Display2,1      ; Decremento Display2.-
  66.                         movlw   d'255'          ; Si paso de 0 a 255...
  67.                         subwf   Display2,0      ; decremento display3
  68.                         btfss   STATUS,Z        ;
  69.                         goto    ActualizoDisplays       ; No es 10.-
  70.                         movlw   d'9'
  71.                         movwf   Display2        ; Si, cargo 9.-
  72.                         decf    Display3,1      ; Decremento Display3.-
  73.                         movlw   d'255'          ; Si paso de 0 a 255...
  74.                         subwf   Display3,0     
  75.                         btfss   STATUS,Z
  76.                         goto    ActualizoDisplays       ; No es 10.-
  77.                         movlw   d'9'
  78.                         movwf   Display3        ; Si, cargo 9.-
  79.                         goto    ActualizoDisplays
  80. ;.........................................................
  81. Ascender       
  82.                         btfss   PORTA,Asc       ;
  83.                         goto    $-1                     ; Esperamos hasta que se suelte.-
  84.                         incf    Display1,1      ; Incremeto Display1.
  85.                         movlw   d'10'           ; Si es 10 reseteo e incremento Display2
  86.                         subwf   Display1,0      ;
  87.                         btfss   STATUS,Z        ;
  88.                         goto    ActualizoDisplays       ; no es 10
  89.                         clrf    Display1        ; Si, reseteo.-        
  90.                         incf    Display2,1      ; Incremento Display2.-
  91.                         movlw   d'10'           ; Si Decena = 10, reseteo e incremento Display3
  92.                         subwf   Display2,0      ;
  93.                         btfss   STATUS,Z        ;
  94.                         goto    ActualizoDisplays       ; No es 10.-
  95.                         clrf    Display2                ; Si, reseteo.-
  96.                         incf    Display3,1      ; Incremento Display3.-
  97.                         movlw   d'10'           ; Si es 10 Reseteo.-
  98.                         subwf   Display3,0
  99.                         btfss   STATUS,Z
  100.                         goto    ActualizoDisplays       ; No es 10.-
  101.                         clrf    Display3                ; Si, reseto
  102.                         goto    ActualizoDisplays
  103. ;...................................................   
  104. ActualizoDisplays
  105.                         movfw   Display1
  106.                         call    BCD7SEG                 ; Convertimos BCD a codigo 7 Segmentos.-
  107.                         movwf   DataEnviar              ; Cargamos dato a enviar devuelto x BCD7SEG.-
  108.                         call    EnviaDato
  109.                         movfw   Display2
  110.                         call    BCD7SEG                 ; Convertimos BCD a codigo 7 Segmentos.-
  111.                         movwf   DataEnviar              ; Cargamos dato a enviar devuelto x BCD7SEG.-
  112.                         bsf             DataEnviar,Pto  ; A ejemplo cargamos punto a enviar.-
  113.                         call    EnviaDato
  114.                         movfw   Display3
  115.                         call    BCD7SEG                 ; Convertimos BCD a codigo 7 Segmentos.-
  116.                         movwf   DataEnviar              ; Cargamos dato a enviar devuelto x BCD7SEG.-
  117.                         call    EnviaDato
  118.                         goto    Testeo
  119. ;**** Se envia Dato a los registros de desplazamiento ****
  120. ;-----------------------------------------------------------------------------------------
  121. ; 1º se envia el LSB, luego se va rotando a la derecha y se envian los bits de mayor peso.-
  122. ;-----------------------------------------------------------------------------------------
  123. EnviaDato
  124.                         movlw   d'8'                    ; Número de bits a transmitir.
  125.                         movwf   ContBits
  126. EnviaBit                                                        ; Comienza a enviar datos.
  127.                         btfss   DataEnviar,0    ; ¿Es un "1" el bit a transmitir?
  128.                         bcf             PORTB,BData             ; No, pues envía un "0".
  129.                         btfsc   DataEnviar,0    ; ¿Es un "1" el bit a transmitir?
  130.                         bsf             PORTB,BData             ; Si, Transmite un "1".
  131.                         bcf             PORTB,BClock    ; Clock=0.-
  132.                         nop
  133.                         bsf             PORTB,BClock    ; Clock=1.-
  134.                         rrf             DataEnviar,1    ; Rota para envia siguiente bit.-
  135.                         decfsz  ContBits,1              ; Comprueba si es el último bit.
  136.                         goto    EnviaBit                ; No es el último bit repite la operación.
  137.                         return                                  ; Retornamos.-
  138. ;.................................................................................
  139.                         end
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: ing_alqa en 20 de Mayo de 2009, 18:51:13
Gracias, muchas gracias. Literalmente aplaudí al finalizar de leer las primeras aplicaciones con el PIC16F84A. Saludos desde Colombia. A propósito, sabes donde puedo encontrar información para iniciarme en las comunicaciones PIC-Ethernet? Gracias de nuevo.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 20 de Mayo de 2009, 18:56:49
En este mismo foro hay mucha información, mira aquí (http://www.google.com.ar/search?client=firefox-a&rls=org.mozilla%3Aes-AR%3Aofficial&channel=s&hl=es&q=site%3Awww.todopic.com.ar%2Fforos%2F+-printpage+-bookmark+Ethernet&meta=&btnG=Buscar+con+Google).

Saludos!
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: acervantes en 21 de Mayo de 2009, 10:56:54
Otro ejemplo:
En este se fija la frecuencia de PWM en 2 kHz y se varía el ciclo de trabajo con 2 pulsadores de control conectados a RB0 y RB1. Solo se modifica en byte alto del CT, ósea el registro CCPR1L con lo que CT se varía de 4 en 4.

Hardware necesario:

(http://img9.imageshack.us/img9/2410/pwm2.png)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         Contador1       equ             0x20    ;
  8.         Contador2       equ             0x21    ;
  9.        
  10.         decre   equ             0       ; Pulsador para decrementar Ciclo de Trabajo
  11.         incre   equ             1       ; Pulsador para incrementar Ciclo de Trabajo
  12.        
  13.        
  14. ;/////////////////////////////////
  15. ;**** Inicio del Micro ****
  16. Reset.         
  17.         org             0x00            ; Aquí comienza el micro.-
  18.         goto    Inicio          ; Salto a inicio de mi programa.-
  19.  
  20. ; **** Programa Principal ****
  21.         org             0x05
  22. Inicio
  23.         bsf             STATUS,RP0      ; Banco 1
  24.         bsf             TRISB,incre     ; Como Entrada.-
  25.         bsf             TRISB,decre     ; Como Entrada.-
  26.         bcf             TRISB,3         ; RB3 como Salida.
  27.         bcf             STATUS,RP0      ; Banco 0.-
  28.         movlw   b'00000110'     ; Se selecciona TMR2, preescaler de 1/16.-
  29.         movwf   T2CON
  30.         bsf             STATUS,RP0      ; Banco 1
  31.         movlw   0x1E            ; Señal de 2kHz
  32.         movwf   PR2    
  33.         bcf             STATUS,RP0      ; Banco 0
  34.         clrf    CCPR1L          ; Ciclo de trabajo 0%
  35.         bcf             CCP1CON,CCP1X
  36.         bcf             CCP1CON,CCP1Y
  37.         bsf             CCP1CON,CCP1M3  ; Configura modulo CCP modo PWM.-
  38.         bsf             CCP1CON,CCP1M2
  39. Bucle
  40.         btfsc   PORTB,decre     ; Testea si se quiere reducir CT.-
  41.         goto    Decrementa
  42.         btfsc   PORTB,incre     ; Testea si se quiere aumentar CT.-
  43.         goto    Incrementa
  44.         goto    Bucle
  45. Incrementa
  46.         incf    CCPR1L,1
  47.         call    Demora_50ms
  48.         goto    Bucle
  49. Decrementa
  50.         decf    CCPR1L,1
  51.         call    Demora_50ms
  52.         goto    Bucle
  53.  
  54.  
  55. ;**** Demora ****
  56. Demora_50ms
  57.         movlw   0xFF                    ;
  58.         movwf   Contador1               ; Iniciamos contador1.-
  59. Repeticion1
  60.         movlw   0x40                    ;
  61.         movwf   Contador2               ; Iniciamos contador2
  62. Repeticion2
  63.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  64.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  65.         decfsz  Contador1,1             ; Decrementa Contador1.-
  66.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  67.         return                                  ; Regresa de la subrutina.-
  68. ;..............................................
  69.         end


En este ejemplo ¿la frecuencia que estas utilizando es de 4Mhz, lo que es lo del oscilador interno.? Tengo una pregunta: ¿Puedes cambiar la frecuencia de oscilacion a 48khz? ¿Como puedo cambiar el duty cycle no de 4 en 4 si no de 1 en 1? ¿Tendras algun ejemplo para controlar el angulo de disparo del TRIAC o SCR? Gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 21 de Mayo de 2009, 11:23:14
Si exactamente, utilizo el oscilador interno. Para cambiarlo a 48kHz debes configurar el bit OSCF en el registro PCON(8Eh)

1 =  Selección de 4MHz para el oscilador interno.
0 = Selección de 48kHz para el oscilador interno.


Con respecto a variar CT en 1 en 1 hay que trabajar con los bits CCP1X y CCP1Y. No me he dado el tiempo para hacer un ejemplo, pero cuando pueda lo are.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: acervantes en 23 de Mayo de 2009, 02:42:06
Se puede limitar el ciclo de trabajo de este ejemplo ya que cuando llega a 0% de Duty Cycle, le das otro decremento, se dispara a 1 logico. Es decir, darle un rango de maximo y minimos, decrementos e incrementos. Gracias :)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 23 de Mayo de 2009, 21:30:48
Claro que si, fíjate en este ejemplo (http://www.todopic.com.ar/foros/index.php?topic=24720.msg213264#msg213264) como se hace un control de estos.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: david1820 en 13 de Junio de 2009, 19:57:00
Suky con como podría programar un dimmer para que al momento de apretar el botón se prenda el foco y al momento de soltarlo el foco vaya disminuyendo su intensidad te lo agradecería tu ayuda.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 14 de Junio de 2009, 00:24:29
Suky con como podría programar un dimmer para que al momento de apretar el botón se prenda el foco y al momento de soltarlo el foco vaya disminuyendo su intensidad te lo agradecería tu ayuda.
En este caso utilizaría PWM, dale una miradita al ultimo ejemplo del PIC16F628 y yo creo que se te va a ser muy fácil diseñar un código.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 17 de Junio de 2009, 21:48:09
Oye discupla ese programa de interrupcion en TMR0 que tienes en primeros programas como lo adaptarias a un 16f628a, cuando lo simulo no me funciona podrias ayudarme

Para utilizar ese mismo código el el PIC16F628 solo hay que cambiar el encabezado y la posición de nuestras variables:
Código: ASM
  1. ; **** Encabezado ****
  2. list p=16f628A ; list directive to define processor
  3. #include <p16f628A.inc> ; processor specific variable definitions
  4. __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5. ;**** Definicion de variables ****
  6. Contador equ 0x20 ; Contador para detectar 4 desbordes de TMR0.-
  7. W_Temp equ 0x21 ; Registro para guardar temporalmente W.-
  8. STATUS_Temp equ 0x22 ; Registro para guardar temporalmente STATUS
  9.  
  10. Led equ 0 ; Definimos Led como el bit cero de un registro, en este caso PORTB.-

Otra cosa que debes tener en cuenta cuando migras un código del PIC16F84 al PIC16F628 es la configuración de los comparadores analógicos, para utilizar los pines RA0-RA3 como I/O digitales debes colocar:
Código: ASM
  1. movlw   0x07
  2.      movwf   CMCON
Mientras se este en el banco 0.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: hellser en 18 de Junio de 2009, 23:52:45
ah gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: OTSELECTRONICSEIRL en 28 de Junio de 2009, 20:50:31
Hola.
Deseo saber si esta afirmacion que expusiste es correcta:

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.

Gracias.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: OTSELECTRONICSEIRL en 28 de Junio de 2009, 22:12:40
Fe de Erratas:
Dice:
Memoria de programa: 2048 locaciones de 14 bits
Debe decir:
Memoria de programa: 1024 locaciones de 14 bits
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 28 de Junio de 2009, 22:39:29
Hola.
Deseo saber si esta afirmacion que expusiste es correcta:

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.

Gracias.
Es cuando se habilta el fuse Power-up Timer, este mantiene resteado el PIC durante un tiempo, y permite que se estabilice la tensión.

Fe de Erratas:
Dice:
Memoria de programa: 2048 locaciones de 14 bits
Debe decir:
Memoria de programa: 1024 locaciones de 14 bits
Error, El pic 16F628 es de 2048 words:
Mirando el Datasheet:
(http://img33.imageshack.us/img33/4910/caractes.jpg)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: miguel valdivia en 06 de Agosto de 2009, 14:17:27
HOLA   Suky  SABES QUE COMPILE EL PROGRAMA
TUYO DEL EJEMPLO DE PWM CON EL MOTORCITO Y LO HICE EN PROTEUS (TENGO 7.5)
Y NO HACE NADA , ME PUEDES AYUDAR PARA SABER
QUE HAGO MAL
SALUDOS DE CHILE    :-/ :-/ :-/ :D
         
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 06 de Agosto de 2009, 17:24:48
Por favor no escribas en mayúscula, en un foro es elevar el tono  :x

Después, he leído que la versión 7.5 tiene problemas para simular el PWM, puede ser eso.

Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: miguel valdivia en 07 de Agosto de 2009, 10:17:48
disculpame  suky porfavor por  las mayusculasn ,
no lei las reglas del foro , no fue un improperio.
pero porque este proteus genera este problema.
osea que en el proto me deberia   funcionar
saludos
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 07 de Agosto de 2009, 10:36:19
disculpame  suky porfavor por  las mayusculasn ,
no lei las reglas del foro , no fue un improperio.
pero porque este proteus genera este problema.
osea que en el proto me deberia   funcionar
saludos


No debería dar problemas, en vez de colocar un motor (el cual necesita driver de potencia) prueba colocando simplemente un led y prueba como varia su luminosidad.

Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: cristiandb en 25 de Agosto de 2009, 12:49:21
hola!
muy buen tutorial para empezar....pero tuve un problema....
no me anduve el ejercicio del led tildando...nose que pasa....pero el led se queda prendido...no prende y apaga..
que problema puede ser....del programador  o algo que puedo estar haciendo mal?
muchas gracias!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 25 de Agosto de 2009, 13:15:03
hola!
muy buen tutorial para empezar....pero tuve un problema....
no me anduve el ejercicio del led tildando...nose que pasa....pero el led se queda prendido...no prende y apaga..
que problema puede ser....del programador  o algo que puedo estar haciendo mal?
muchas gracias!

Como estas realizando las pruebas? Si es un protoboard asegúrate que las conexiones estén bien fijas. Que el pin Mclr este a Vcc mediante una resistencia, que el oscilador este con sus capacitores lo más próximo al microcontrolador, etc.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: beto1234 en 26 de Agosto de 2009, 10:14:03
  COMUNICACIÓN IR - PIC16F628 Y PIC12F629

 Hola amigos PICLISTEROS, voy a explicar como hacer la comunicación de dos PIC  por medio de infrarrojo. En este ejemplo voy a codificar la señal con el pic12f629 y lo decodificaré con el pic16f628a, la codificación de pulsos que puse es muy facíl pero eficiente ya q no detecta otros controles IR. Al comprobar q el código es el correcto hacemos titilar un led 10veces.
 
 INFORMACIÓN DE INTERNET:  
 http://heli.xbot.es/fd/ir.htm (http://heli.xbot.es/fd/ir.htm)
 http://r-luis.xbot.es/sensores/ir.html (http://r-luis.xbot.es/sensores/ir.html)
 
 HERRAMIENTAS QUE USE:
Soft-MPLAB IDE V8.X (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002#P140_5618)
MCE PDX USB -080609 (Programador y Debugger Express) (http://www.mcelectronics.com.ar/pdx/)
Soft- Pickit 2 Develooment (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023805)

 EMISOR IR

Nombre de los componentes Importantes:
PIC12F629 (http://www.datasheetcatalog.org/datasheet/microchip/41190c.pdf)
Transitor BC337 (http://www.datasheetcatalog.org/datasheet/fairchild/BC337.pdf)
LED EMISOR  L-53F3BT (http://www.datasheetcatalog.org/datasheets2/85/85702_1.pdf)
(http://beto123456789.webcindario.com/emisor.jpg)
Código: [Seleccionar]
INCLUDE <P12F629.INC>
__CONFIG _CP_OFF & _WDT_OFF  & _PWRTE_ON & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
cblock 0x20 ; programación moderna para designar registros
Contador1
Contador2    
endc
   org     0x00
   goto INICIO

   ORG 0x05


INICIO
        BCF STATUS,RP0 ;Bank 0
        CLRF GPIO ;Init GPIO
        MOVLW 07h ;Ponemos como I/O digital
        MOVWF CMCON
        BSF STATUS,RP0 ;Bank 1
   movlw b'00000010'
movwf TRISIO ; puertos gpx como salidas menos gp1 q es entrada
   banksel GPIO ; programación moderna para posiscionar en un banco especifico
   clrf    Contador1 ; limpiamos
        clrf    Contador2 ; limpiamos
        clrf    GPIO ;limpiamos            
BUCLE
        nop;no hacemos nada
        btfsc GPIO,1 ;si el boton esta presionado- enviamos la señal codificada
        call Codigo
      
 goto BUCLE

Codigo ; 1   1010
        bsf  GPIO,2; 1 de inicio
        call Demora_30ms
        bsf GPIO,2       ;1
        call Demora_30ms
        bcf GPIO,2       ;0
        call Demora_30ms
        bsf GPIO,2       ;1
        Call Demora_30ms
        bcf GPIO,2       ;0
        Call suelta
return
suelta
     btfss GPIO,1
     return
     goto suelta

;---------RUTINA DEL RETARDO DE TIEMPO----------
;...............................................
; *** Demora****
Demora_30ms
movlw 0xFF ;
movwf Contador1 ; Iniciamos contador1.-
Repeticion1
movlw 0xC3 ;
movwf Contador2 ; Iniciamos contador2
Repeticion2
decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
goto Repeticion2 ; Si no es 0 repetimos ciclo.-
decfsz Contador1,1 ; Decrementa Contador1.-
goto Repeticion1 ; Si no es cero repetimos ciclo.-
return ; Regresa de la subrutina.-
;...............................................

end


 RECEPTOR IR

Componentes Importantes
PIC16F628A (http://www.datasheetcatalog.org/datasheet/microchip/40044b.pdf)
LED RECEPTOR(Fototransistor) - L51P3C (http://www.datasheetcatalog.org/datasheets2/59/59198_1.pdf)

(http://beto123456789.webcindario.com/receptor.jpg)
Código: [Seleccionar]
INCLUDE <P16F628A.INC>
__CONFIG _CP_OFF & _WDT_ON & _LVP_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT
cblock 0x20
Contador1
Contador2
ESTADO  
Loop  
endc
   org     0x00
   goto INICIO

   ORG 0x05
INICIO
       bsf STATUS,RP0 ; Banco 1
       Movlw    b'00010000' ;
       Movwf    TRISB  ; RB5 como entrada  los demás como salida
       banksel PORTB ;me posiciono en el banco del portb
       clrf    PORTB ; portb limpio
       clrf    Contador1 ; limpiamos
       clrf    Contador2 ; limpiamos
BUCLE
        clrwdt ;limpio W
        BCF ESTADO,1 ;pongo en 0 el bit1 del registro ESTADO
        btfss PORTB,4;si recive un 0 llama a Vercodigo q es el conprueba
        call VerCodigo
        BTFSC ESTADO,1;Probamos si el código fue correcto si es así titilamos el led  
        call Alarma
goto BUCLE
;***************** LEER CODIGO ENVIADO POR EL TRANSMISOR *********************
;************* SI EL CODIGO ES CORRECTO   ==>  ESTADO,1 = 1 **********
;************* SI EL CODIGO ES INCORRECTO ==>  ESTADO,1 = 0 **********
;Codigo 1 1010
VerCodigo
    
BCF ESTADO,1


    CALL Demora_30ms
BTFSC PORTB,4   ;******  0 ******
RETURN

CALL Demora_30ms
BTFSS PORTB,4 ;******  1 ******
RETURN

CALL Demora_30ms
BTFSC PORTB,4 ;******  0 ******
RETURN

CALL Demora_30ms
BTFSS PORTB,4 ;******  1 ******
RETURN

    CALL Demora_30ms
CALL Demora_30ms

BSF ESTADO,1 ; ESTADO,1 = 1
RETURN


Alarma
movlw 0x0A ; Hacemos titilar 10 veces el Led.-
movwf Loop
bsf PORTB,5
call Demora_150ms
bcf PORTB,5
call Demora_150ms
decfsz Loop
goto $-5
return

;.................................................
;---------RUTINA DEL RETARDO DE TIEMPO----------
;**** Demora 150MS ****
Demora_150ms
    clrf    Contador1 ; limpiamos
    clrf    Contador2 ; limpiamos
movlw 0xFF ;
movwf Contador1 ; Iniciamos contador1.-
Repeticion1
movlw 0xC3 ;
movwf Contador2 ; Iniciamos contador2
Repeticion2
decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
goto Repeticion2 ; Si no es 0 repetimos ciclo.-
decfsz Contador1,1 ; Decrementa Contador1.-
goto Repeticion1 ; Si no es cero repetimos ciclo.-
return ; Regresa de la subrutina.-
;...............................................
; *** Demora****
Demora_30ms
movlw 0xFF ;
movwf Contador1 ; Iniciamos contador1.-
Repeticion3
movlw 0xC3 ;
movwf Contador2 ; Iniciamos contador2
Repeticion4
decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
goto Repeticion4 ; Si no es 0 repetimos ciclo.-
decfsz Contador1,1 ; Decrementa Contador1.-
goto Repeticion3 ; Si no es cero repetimos ciclo.-
return ; Regresa de la subrutina.-
;...............................................
end

end

(http://beto123456789.webcindario.com/IR.jpg)
(http://beto123456789.webcindario.com/IR2.jpg)


Salu2 BETO ROBLEDO SANCHEZ- Estudiante de la UTN - Facultad Regional Resistencia - I.Q
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 26 de Agosto de 2009, 10:53:51
Bienvenido al foro beto1234!

(http://img222.imageshack.us/img222/3871/yb641.gif) Muy buen proyecto! Te animo que crees un  nuevo tema en el subforo proyectos con PIC para presentarlo :wink:


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: beto1234 en 27 de Agosto de 2009, 01:24:13
 Hola muchas gracias.. A ver si puedo presentar algún proyectivo con MATLAB y un PIC, ahora pronto no creo pero mas adelante seguro. Estoy metido con el matlab en el tema de procesamiento de imágenes y de audio. Estoy tratando de darle uso mas industrial a esto.. pero no tengo drama en presentarlo aqui. :D.

 
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Pts en 06 de Septiembre de 2009, 19:38:15
Una pregunta gente, me baje el ejemplo en proteus isis del led titilando, mi pregunta es si desde RB0/INT puedo poner mas de un led, o sea que en el proteus funciona perfecto agrego mas led y titilan todos, pero quizas halla problema en la practica, recien estoy empezando agradeceria su ayuda.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: jim_17 en 06 de Septiembre de 2009, 23:32:02
Pts, colocando una resistencia, un transistor (NPN)  y los leds en paralelo en el colector con su respectiva resistencia debería funcionar.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: picnew en 19 de Octubre de 2009, 15:17:44
Buenas tardes, tratando de compilar un programa muy sencillo en MPLAB me he encontrado con este problema:

Executing: "C:\Archivos de programa\Microchip\MPASM Suite\MPAsmWin.exe" /q /p16F84 "Carrito.asm" /l"Carrito.lst" /e"Carrito.err" /o"Carrito.o"
Warning[205] C:\DOCUMENTS AND SETTINGS\USUARIO\ESCRITORIO\CERCO KEROMUCHI\PROGRAMAS\CARRITO.ASM 1 : Found directive in column 1. (LIST)
Warning[205] C:\DOCUMENTS AND SETTINGS\USUARIO\ESCRITORIO\CERCO KEROMUCHI\PROGRAMAS\CARRITO.ASM 3 : Found directive in column 1. (include)
Skipping link step.  The project contains no linker script.
BUILD FAILED: Mon Oct 19 13:38:33 2009


Lo cual no me permite simular el programa, es MPLAB 7.50.

Aca tambien envió el programa que descargue de un tutorial:


include "P16F84.INC"
 __CONFIG   _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC


Resultado    EQU  0x10             ;Define la posición del resultado
             org 0x00                       ;Vector de Reset

             goto Inicio
             org 0x05                      ;Salva el vector de interrupción
Inicio       movlw 0x07         ;Carga 1er. sumando en W
             addlw 0x06         ;Suma el 2º sumando
             movwf Resultado    ;Almacena el resultado
             nop                ;Poner breakpoint de parada
             nop
             END               ;Fin del programa fuente


De antemano muchas gracias


Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: picnew en 19 de Octubre de 2009, 15:39:45
hermanos ya consegui la respuesta disculpen mi ignorancia, me hacia falta agregarle un archivo de link correspondiente al modelo de pic a usar, caramba hace unos 10 años utilice MPLAB pero si mal no recuerdo no habia que agregar ese archivo de link, o estoy errado?

De antemano, muchas gracias nuevamente
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 19 de Octubre de 2009, 15:50:06
No, no es necesario. En Project/Select Lenguaje Toolsuite selecciona MPASM Toolsuite y verifica que las "rutas" de los archivos estén correctamente.
Luego al hacer Build All si aparece una ventana preguntando absolute o reloacatable coloca absolute.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: picnew en 19 de Octubre de 2009, 17:47:18
Nuevamente yo..... espero disculpen ahora superado el primer inconveniente surge otro al tratar de simular, me indica lo siguiente:

CORE-E0002: Stack under flow error occurred from instruction at 0x00000a


Agradeciendo nuevament su ayuda.


Saludos
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 19 de Octubre de 2009, 19:26:53
Simular donde? En el mismo MPLab,Proteus u otro?
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: miguel valdivia en 02 de Diciembre de 2009, 12:22:17
Hola suky , encontre un problema en tu programa de cambio de ciclo de trabajo:
en el bucle de testeo del puerto b 6 y 7  se esta preguntando si esta e BTFSC , pero en tu esquematico estos pines estan a masa
entonces deberia ser BTFSS o me equivoco
otra cosa el retardo no sera muy poco
porque lo estoy probando y todavia no me funciona

saludos desde chile
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 02 de Diciembre de 2009, 13:30:59
No, fíjate que al pulsar la tecla, el pin del PIC pasa a 1 (5V). Y en el test de estos pines se testea si es cero, salta a consultar por el otro, si este también es cero se salta al bucle nuevamente.

La demora es para que al mantenerlo presionado se note el cambio gradual, y capaz si sea demasiado poco  :tongue: Pero si es el caso veras que pasa de 0% a 100% (Ciclo de trabajo) casi sin poder controlarlo.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: kapotik en 13 de Diciembre de 2009, 20:47:03
Buenas a todos!!

suki quisiera saber si me podrias enseñar como recivir un caracter o una cadena de caracteres por rs 232 y luego poder tratarla, o sea hacer alguna comparacion, por ejemplo si recibio en el caracter nº 23 una "p" que aga tal cosa. Es pero haber sido lo mas claro posible, ya que enviar desde el pic al pc me sale muy bien pero no se como recibirlo y tratarlo.
Espero me puedas ayudar y si no todo bien igual.

Un saludo desde Mendoza Argentina para todos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 13 de Diciembre de 2009, 20:58:38
Hola kapotik!

Para recibir una cadena puedes usar el direccionamiento indirecto como para guardarlo en un rango de la memoria.

Para comparar datos podes hacerlo de la siguiente:

Código: ASM
  1. ; Se recibe un carácter y se guarda en RData por ejemplo.
  2.     ; Se quiere saber si es la 'a'
  3.     movlw   'a'  ; Cargamos en W en ascii a
  4.     subwf  RData,0 ; Restamos W-RData y lo guardamos en W.
  5.     btfsc  STATUS,Z  ; Consultamos si la operacion a resultado 0.
  6.     goto  SiEsA  ; Si es A.
  7.     goto  NoEsA  ; No es A...


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: kapotik en 14 de Diciembre de 2009, 10:36:31
Gracias suky por contestar tan rapídamente!!
disculpa mi ignorancia pero podrias mostrarme como recibir la cadena de caracteres. La comparacion si me quedo bien claro.

Saludos
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: micronet3 en 19 de Enero de 2010, 19:48:56
wow amigo suky, que locura, hace tiempo que no toco el assembler, pero igual jamas he llegado a tocar varios temas en assembler, que bien amigo.
muchas gracias por tu esfuerzo, esto es mejor que un libro de assembler
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: beto1234 en 22 de Febrero de 2010, 13:24:40
USO DE LA LIBRERIA MATEMATICA + - / *

 Bueno amigos voy a tratar de explicar como poder multiplicar, dividir, sumar y restar usando una librería  matemática muy útil. Para crear esta librería, abrimos el bloc de notas de windows que se encuentra en el menú accesorios. Copiamos el código de la librería que mas abajo la dejo, y lo guardan con el nombre "Matematica" y la extensión "INC".
Código: [Seleccionar]
;****************************************************************************************************************************************
;****************************************************************************************************************************************
;*********************************LIBRERIA DE FUNCIONES MATEMATICAS + - * / *************************************************************
;****************************************************************************************************************************************
;****************************************************************************************************************************************

CBLOCK
  NUM1H
  NUM1L
  NUM2H
  NUM2L
  RESU1H
  RESU1L
  ACCdHI
  ACCdLO
  tempMat
  Flags

ENDC

;*******************************************************************************************************************************************
;*******************************************************************************************************************************************
;******************************************************************************************************************************************
;         Double Prec*ision Subtraction ( NUM1 - NUM2 -> RESU1 )
;
Restar   
movfw NUM1L
movwf RESU1L
movfw NUM1H
movwf RESU1H
movf NUM2L,W
movwf ACCdHI
movf NUM2H,W
movwf ACCdLO
comf ACCdHI,1
incf ACCdHI,1
btfsc STATUS,Z
decf ACCdLO,1
comf ACCdLO,1
movf ACCdHI,w
addwf RESU1L,1
btfsc STATUS,C
incf RESU1H,1
movf ACCdLO,w
addwf RESU1H,1
retlw   0
;******************************************************************************************************************************************
;*******************************************************************************************************************************************
;***********************Double Precision Addition ( NUM1 + NUM2 -> NUM1 )*******************************************************************
;*******************************************************************************************************************************************

Sumar            bcf     Flags,0 ;Clear temp Carry bit
movf    NUM2L,0       
addwf   NUM1L,1 ;add lsb
btfsc   STATUS,C  ;add in carry
  incf    NUM1H,1
btfsc STATUS,C
bsf Flags,0
movf    NUM2H,0
addwf   NUM1H, 1         ;add msb
btfsc Flags,0
bsf     STATUS,C
retlw   0
;*******************************************************************
;               Double Precision Multiply ( 16x16 -> 32 )
;         ( NUM1*NUM2 -> NUM1,RESU1) : 32 bit output with high word
;  in ACCb ( NUM1H,NUM1L ) and low word in ACCc ( RESU1H,RESU1L ).
;*******************************************************************



Multiplicar                          ;results in ACCb(16 msb's) and ACCc(16 lsb's)

        bcf STATUS,RP0 ;banco0
                bcf STATUS,RP1

call    setup
mloop   rrf     ACCdHI, 1       ;rotate d right
rrf     ACCdLO, 1
btfsc   STATUS,C    ;need to add?
call    Suma
rrf     NUM1H, 1
rrf     NUM1L, 1
rrf     RESU1H, 1
rrf     RESU1L, 1
decfsz  tempMat, 1      ;loop until all bits checked
goto    mloop

    retlw   0
   

setup           movlw   .16             ; for 16 shifts
movwf   tempMat
movf    NUM1H,0          ;move ACCb to ACCd
movwf   ACCdHI
movf    NUM1L,0
movwf   ACCdLO
clrf    NUM1H
clrf    NUM1L
retlw   0
;*******************************************************************
;       Double Precision Divide ( 16/16 -> 16 )
;
;         ( NUM1/NUM2 -> NUM1 with remainder in RESU1 ) : 16 bit output
; with Quotiont in NUM1 (NUM1H,NUM1L) and Remainder in RESU1 (RESU1H,RESU1L).
;
;   NOTE  :  Before calling this routine, the user should make sure that
;            the Numerator(NUM1) is greater than Denominator(NUM2). If
;            the case is not true, the user should scale either Numerator
;            or Denominator or both such that Numerator is greater than
;            the Denominator.
;*******************************************************************


Dividir call    setup
clrf    RESU1H
clrf    RESU1L
dloop   bcf     STATUS,C
rlf     ACCdLO,1
rlf     ACCdHI,1
rlf     RESU1L,1
rlf     RESU1H,1
movf    NUM2H,0
subwf   RESU1H,0        ;check if a>c
btfss   STATUS,2
goto    nochk
movf    NUM2L,0
subwf   RESU1L,0    ;if msb equal then check lsb
nochk   btfss   STATUS,0    ;carry set if c>a
goto    nogo
movf    NUM2L,0        ;c-a into c
subwf   RESU1L,1
btfss   STATUS,0
decf    RESU1H,1
movf    NUM2H,0
subwf   RESU1H,1
bsf     STATUS,0    ;shift a 1 into b (result)
nogo    rlf     NUM1L,1
rlf     NUM1H,1
decfsz  tempMat,1         ;loop untill all bits checked
goto    dloop

retlw 0



MODO DE USO
 Para probar solamente abran el MPLAB => File Registers , y van a ver los resultados en el registro TRISA ó TRISB así también como cada registro usado por la librería.

RESTA

Código: [Seleccionar]
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
cblock 0x20 ; registros de uso

ENDC
;**** Configuracion de puertos ***
Reset org 0x00 ; Aqui comienza el micro.-
goto Inicio ; Salto a inicio de mi programa.-
org 0x05 ; Origen del codigo de programa.-
Inicio
   
        bsf STATUS,RP0 ;banco1
        bcf STATUS,RP1
      clrf TRISA
        clrf TRISB

CALC   ; RESTA 1BYTE - 1BYTE = 1BYTE
       ;(NUM1H,NUM1L) -  (NUM2H,NUM2L) = (RESU1H,RESU1L)
       ; 10 - 4 = 6
       ; El resultado lo paso al TrisA
        movlw     .10
        MOVWF NUM1L
CLRF NUM1H
MOVLW .4
MOVWF NUM2L
CLRF NUM2H
CALL Restar
        banksel     TRISA
MOVF RESU1L,0
        MOVWF TRISA             
MOVF RESU1H,0
MOVWF TRISB
goto CALC

INCLUDE  "C:\....\Matematica.INC"
end

SUMA

Código: [Seleccionar]
#include P16F877A.inc
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
cblock 0x20 ; registros de uso

ENDC
;**** Configuracion de puertos ***
Reset org 0x00 ; Aqui comienza el micro.-
goto Inicio ; Salto a inicio de mi programa.-
org 0x05 ; Origen del codigo de programa.-
Inicio
   
        bsf STATUS,RP0 ;banco1
        bcf STATUS,RP1
      clrf TRISA
        clrf TRISB

CALC   ; SUMA 1BYTE + 1BYTE = 1BYTE
       ;(NUM1H,NUM1L) +  (NUM2H,NUM2L) = (NUM1H,NUM1L)
       ; 10 - 4 = 6
       ; El resultado lo paso al TrisA
        movlw     .10
        MOVWF NUM1L
CLRF NUM1H
MOVLW .4
MOVWF NUM2L
CLRF NUM2H
CALL Sumar
        banksel     TRISA
MOVF NUM1L,0
        MOVWF TRISA             
MOVF NUM1H,0
MOVWF TRISB
goto CALC

INCLUDE  "C:\...\Matematica.INC"
end

MULTIPLICACIÓN

Código: [Seleccionar]
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
cblock 0x20 ; registros de uso

ENDC
;**** Configuracion de puertos ***
Reset org 0x00 ; Aqui comienza el micro.-
goto Inicio ; Salto a inicio de mi programa.-
org 0x05 ; Origen del codigo de programa.-
Inicio
   
        bsf STATUS,RP0 ;banco1
        bcf STATUS,RP1
      clrf TRISA
        clrf TRISB

CALC   ; MULTIPLICA 1BYTE * 1BYTE = 1BYTE
       ;(NUM1H,NUM1L) *  (NUM2H,NUM2L) = ( RESU1H,RESU1L )
       ; 2 * 4 = 8
       ; El resultado lo paso al TrisA
        movlw     .2
        MOVWF NUM1L
CLRF NUM1H
MOVLW .4
MOVWF NUM2L
CLRF NUM2H
CALL Multiplicar
        banksel     TRISA
MOVF RESU1L,0
        MOVWF TRISA             
MOVF RESU1H,0
MOVWF TRISB
goto CALC

INCLUDE  "C:\...\Matematica.INC"
end

DIVISIÓN

Código: [Seleccionar]
#include P16F877A.inc
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
cblock 0x20 ; registros de uso

ENDC
;**** Configuracion de puertos ***
Reset org 0x00 ; Aqui comienza el micro.-
goto Inicio ; Salto a inicio de mi programa.-
org 0x05 ; Origen del codigo de programa.-
Inicio
   
        bsf STATUS,RP0 ;banco1
        bcf STATUS,RP1
      clrf TRISA
        clrf TRISB

CALC   ; DIVIDE 1BYTE / 1BYTE = 1BYTE
       ;(NUM1H,NUM1L) /  (NUM2H,NUM2L) = (NUM1H,NUM1L) ,  resto en ( RESU1H,RESU1L )
       ; 6 / 3 = 2
       ; El resultado lo paso al TrisA
        movlw     .6
        MOVWF NUM1L
CLRF NUM1H
MOVLW .3
MOVWF NUM2L
CLRF NUM2H
CALL Dividir
        banksel     TRISA
MOVF NUM1L,0
        MOVWF TRISA             
MOVF NUM1H,0
MOVWF TRISB
goto CALC

INCLUDE  "C:\...\Matematica.INC"
end



 
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 22 de Febrero de 2010, 13:29:20
Excelente aporte Beto!  :-/ Una librería muy útil  :P


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: chicho en 11 de Abril de 2010, 00:19:56
Hola Suky y gracias por este tutorial, esta muy bueno.
Yo recien estoy dando mis primeros pasos en este tema de los Pic y queria hacerte una pregunta, como ejemplo te digo que estoy probando con el pic 16f84 al cual conecte 2 leds, 1 en RB0 que enciende cada ves que oprimo el pulsador y el otro led en RB1 el cual quiero que prenda despues de haber oprimido el pulsador una determinada cantidad de veces,
No se si se entiende lo que digo: el led en RB0 enciende siempre que oprima el pulsador y el led en RB1 cuando el pulsador fue oprimido por ejemplo 5 veces.
Como hago para ir contando las veces que se oprimio el pulsador?
Desde ya muchas gracias por tu ayuda
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 11 de Abril de 2010, 09:29:03
Puedes utilizar una variable (Un registro de la RAM) para contar cuantas veces a sido pulsado, esperando que el botón se presione y suelte. Luego comparas este valor con un literal para saber si se ha pulsado N veces.


Saludos!
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A
Publicado por: etarrita en 03 de Mayo de 2010, 16:10:15
Otro ejemplo:
En este se fija la frecuencia de PWM en 2 kHz y se varía el ciclo de trabajo con 2 pulsadores de control conectados a RB0 y RB1. Solo se modifica en byte alto del CT, ósea el registro CCPR1L con lo que CT se varía de 4 en 4.

Hardware necesario:

(http://img9.imageshack.us/img9/2410/pwm2.png)

Código: ASM
  1. ; **** Encabezado ****
  2.         list            p=16f628A       ; list directive to define processor
  3.         #include        <p16f628A.inc; processor specific variable definitions
  4.         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON
  5.  
  6. ;**** Definicion de variables ****
  7.         Contador1       equ             0x20    ;
  8.         Contador2       equ             0x21    ;
  9.        
  10.         decre   equ             0       ; Pulsador para decrementar Ciclo de Trabajo
  11.         incre   equ             1       ; Pulsador para incrementar Ciclo de Trabajo
  12.        
  13.        
  14. ;/////////////////////////////////
  15. ;**** Inicio del Micro ****
  16. Reset.         
  17.         org             0x00            ; Aquí comienza el micro.-
  18.         goto    Inicio          ; Salto a inicio de mi programa.-
  19.  
  20. ; **** Programa Principal ****
  21.         org             0x05
  22. Inicio
  23.         bsf             STATUS,RP0      ; Banco 1
  24.         bsf             TRISB,incre     ; Como Entrada.-
  25.         bsf             TRISB,decre     ; Como Entrada.-
  26.         bcf             TRISB,3         ; RB3 como Salida.
  27.         bcf             STATUS,RP0      ; Banco 0.-
  28.         movlw   b'00000110'     ; Se selecciona TMR2, preescaler de 1/16.-
  29.         movwf   T2CON
  30.         bsf             STATUS,RP0      ; Banco 1
  31.         movlw   0x1E            ; Señal de 2kHz
  32.         movwf   PR2    
  33.         bcf             STATUS,RP0      ; Banco 0
  34.         clrf    CCPR1L          ; Ciclo de trabajo 0%
  35.         bcf             CCP1CON,CCP1X
  36.         bcf             CCP1CON,CCP1Y
  37.         bsf             CCP1CON,CCP1M3  ; Configura modulo CCP modo PWM.-
  38.         bsf             CCP1CON,CCP1M2
  39. Bucle
  40.         btfsc   PORTB,decre     ; Testea si se quiere reducir CT.-
  41.         goto    Decrementa
  42.         btfsc   PORTB,incre     ; Testea si se quiere aumentar CT.-
  43.         goto    Incrementa
  44.         goto    Bucle
  45. Incrementa
  46.         incf    CCPR1L,1
  47.         call    Demora_50ms
  48.         goto    Bucle
  49. Decrementa
  50.         decf    CCPR1L,1
  51.         call    Demora_50ms
  52.         goto    Bucle
  53.  
  54.  
  55. ;**** Demora ****
  56. Demora_50ms
  57.         movlw   0xFF                    ;
  58.         movwf   Contador1               ; Iniciamos contador1.-
  59. Repeticion1
  60.         movlw   0x40                    ;
  61.         movwf   Contador2               ; Iniciamos contador2
  62. Repeticion2
  63.         decfsz  Contador2,1             ; Decrementa Contador2 y si es 0 sale.-        
  64.         goto    Repeticion2             ; Si no es 0 repetimos ciclo.-
  65.         decfsz  Contador1,1             ; Decrementa Contador1.-
  66.         goto    Repeticion1             ; Si no es cero repetimos ciclo.-
  67.         return                                  ; Regresa de la subrutina.-
  68. ;..............................................
  69.         end


hola suky, gracias por todos tus aportes, me interesa este codigo pero lo usare para controlar la velocidad de un motor mediante puente h, etc. tengo entendido que la frecuencia del pwm deberia ser 20khz para que el motor no haga ruidos audibles por el humano, me podrias ayudar???

gracias.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: MINDFIELD en 22 de Mayo de 2010, 14:33:18
Hola SUKY exelente tu aporte !! , me interesaria saber como se programa una eeprom ! , estoy empesando de 0 de nuevo jeje con esto de assembler ! y no encuentro info sobre el tema !

saludos !
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: MINDFIELD en 22 de Mayo de 2010, 14:45:50
jaja olvide de escribir la pregunta principal que queria hacer !  :oops: jeje queria preguntarte tambien si conoces mikropascal y si es asi !? que te parece para programar micros ?

gracias por tu tiempo y tu ayuda en otros momentos y espero que estes bien amigo !

saludos !
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: O7ERO en 10 de Junio de 2010, 22:56:06
En el contador de 0 - 999 Quiero colocarle dos pulsadores uno INICIO/STOP y otro PAUSE. Como hago para colocar pulsador  de INICIO/STOP yo le puse el pulsador para inicio y lo simule en elk proteus y funciono fino pero he tratado de que el mismo pulsador despues de haber iniciado el conteo automatico lo detenga y no he podido, el va a hacer que vuelva a cero y que haga falta volverlo a apretar para que inicie de nuevo.

Para inicio yo coloque btfss perguntado por el estado del pulsador para iniciar y luego volvi a pregunta btfss por el estado de pulsador para el stop,  y que va, cuando lo simulo no funciona, a veces hasta se guina el conteo.
Título: Re: Primer Programa
Publicado por: jhony85 en 11 de Junio de 2010, 08:34:08
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 (http://www.todopic.com.ar/foros/index.php?topic=23623.0) 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:
(http://img217.imageshack.us/img217/282/hardcontrolledja0.bmp)

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:
(http://img19.imageshack.us/img19/7125/controlledtz4.jpg)

Primero que nada debemos especificar con que microcontrolador estamos trabajando, esto lo realizamos es las dos primeras líneas:
Código: 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: 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: 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: 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: 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.-
 :-/


hola buenas , estoy intentando montar este primer circuito y quisiera saber si se puede sustituir el cristal por una red RC y cómo iría ésta colocada.

Saludos.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Deckblank en 17 de Junio de 2010, 03:37:39
 :shock: :shock:
Quiero llorar quiero llorar ... muchas gracias Suky ... con mas personas asi la electronica en sudamerica seria otra cosa  :D

me lei de corrido todo hasta los lcd ... en cerca de 2 horas ... tu tuto es una pasta  :-/ :-/ :-/

 :afro: sos un grosso
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 17 de Junio de 2010, 19:07:11
Muchas gracias por los comentarios!  ;-)

jhony85, se puede hacer lo que necesitas, primeramente debes indicarselo al microcontrolador configurando adecuadamente la palabra de configuración (FUSES).


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Hormiga en 22 de Julio de 2010, 02:31:56
Hola suky la verdad que no he podido realizar comunicación serial con pic 16f84a a 115200BPS, lo otro me puedes explicar por favor como recibir RX tramas fbus

Gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 22 de Julio de 2010, 11:16:11
Hola suky la verdad que no he podido realizar comunicación serial con pic 16f84a a 115200BPS, lo otro me puedes explicar por favor como recibir RX tramas fbus

Gracias

Prueba con un  microcontrolador que tenga módulo UART, sino muy dificil....



Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: JebusITO en 28 de Agosto de 2010, 20:41:29
buena stardes, soy nuevo en el foro y estoy intentado segir paso a paso este tutorial, peor tengo varias dudas, la primera:

Como simplificas esta fórmula:

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

segundo, en el mplab ide y el proteus usando el codigo para hacer titilar el led funciona:

#
Demora_150ms
#
movlw 0xFF ;
#
movwf Contador1 ; Iniciamos contador1.-
#
Repeticion1
#
movlw 0xC3 ;
#
movwf Contador2 ; Iniciamos contador2
#
Repeticion2
#
decfsz Contador2,1 ; Decrementa Contador2 y si es 0 sale.-
#
goto Repeticion2 ; Si no es 0 repetimos ciclo.-
#
decfsz Contador1,1 ; Decrementa Contador1.-
#
goto Repeticion1 ; Si no es cero repetimos ciclo.-
#
return ; Regresa de la subrutina.-
#
 
#
end


pero si deseo aumentar el tiempo  por ejemplo a FF en ambos contadores, el proteus me dice lo siguiente al inicar la emulacion:


PiC16 Load: Program or eeprom data has a invalid adress (2000) hasta el 2003 for this device y luego el wathdog comienza el reseteo del micro cada poco mas de 0.5seg gracias por entenderme :)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 28 de Agosto de 2010, 21:23:37
buena stardes, soy nuevo en el foro y estoy intentado segir paso a paso este tutorial, peor tengo varias dudas, la primera:

Como simplificas esta fórmula:

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

Hay que sumar los 1 y los 2.  :mrgreen:


Para lo segundo, no debería de haber ningún problema con cambiar solamente el valor de los contadores, revisa con calma para deterninar si no cambiaste otra cosa.  :?


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: JebusITO en 29 de Agosto de 2010, 00:47:21
buena stardes, soy nuevo en el foro y estoy intentado segir paso a paso este tutorial, peor tengo varias dudas, la primera:

Como simplificas esta fórmula:

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

Hay que sumar los 1 y los 2.  :mrgreen:


Para lo segundo, no debería de haber ningún problema con cambiar solamente el valor de los contadores, revisa con calma para deterninar si no cambiaste otra cosa.  :?


Saludos!


Gracias por responder, pero igual sigo con dudas, al sumar los "1 y los 2" obtengo la siguiente fórmula:
4+(0xXX)*[(0xYY-1)*(3)+7]+[(0xYY-1)*(3)+8]

muy diferente ala que tu muestras

[0xXX*((0xYY - 1)*3 + 7) + 5] Tcy

y en cuanto a la rutina de retardo, no no modifico sino el segundo contador, ya que descargue las simlaciones que amablemente compartiste con nosotros y sigo con lo mismo asi cambie al siguiente numero hexadecimal me genera el mismo error,  o si le resto a 0xC2 sigue con el problema :S
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 29 de Agosto de 2010, 11:30:08
Es cierto  :oops: Si simplificamos a esa ecuación, con simple matemática se llega a:

sub = [(0xXX+1)*((0xYY - 1)*3 + 7) + 5] Tcy


El problema es que falta un -1 en la original, debe ser:

Tsub = 2 + 1 + 1 + (0xXX-1)*[1 + 1 + (0xYY - 1)*(1 + 2) + 2 + 1 + 2] + [1 + 1 + (0xYY - 1)*(1 + 2) + 2 + 2 + 2] ciclos

Y eso si da:

sub = [(0xXX)*((0xYY - 1)*3 + 7) + 5] Tcy

Que es lo correcto.

Lo otro, tiene que ser problema del simulador, no veo otro problema.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: JebusITO en 01 de Septiembre de 2010, 20:19:55
Todo funcionando bien :D
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 13 de Septiembre de 2010, 14:41:39
(http://img412.imageshack.us/img412/4624/0106.gif)

100.000 visitas!  :-/ Este 16F84A sigue rompiendo records!!! Pero con ayuda del 16F628  :mrgreen:  (http://img84.imageshack.us/img84/3881/bangef.gif)  :D :D
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: solapower en 15 de Septiembre de 2010, 14:33:41
suki:
Estoy siguiendo este tema atentamente pero me encuentro que al instalar  el ConfigPic  me dice que mehace falta el .NET Framework  V 1.1.4322 y cuando accede a internet para descargarlo entra en una pàgina donde no está la version mencionada, he instalado versiones superiores de Net, pero el setup sigue con el mismo mensaje.
Alguna idea ?

Saludos
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 15 de Septiembre de 2010, 15:52:59
suki:
Estoy siguiendo este tema atentamente pero me encuentro que al instalar  el ConfigPic  me dice que mehace falta el .NET Framework  V 1.1.4322 y cuando accede a internet para descargarlo entra en una pàgina donde no está la version mencionada, he instalado versiones superiores de Net, pero el setup sigue con el mismo mensaje.
Alguna idea ?

Saludos

Si ejecutas en .exe (dentro de la carpeta bin) ocurre lo mismo?

Intento compilarlo con VB.NET para probar.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: solapower en 16 de Septiembre de 2010, 05:59:45
Gracias por tu respuesta Suky:

Ejecutando el exe desde la carpeta bin funciona perfectamente.

Gracias de nuevo
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: zaratustra_x en 01 de Octubre de 2010, 19:44:05
Saludos Suky

Muchas gracias por tomarte el tiempo de hacer este post.

Quiero felicitarte por tu trabajo y agradecerte por el todo el esfuerzo que has hecho.

Había estado buscando tutoriales para aprender a programar pics y me topé con tu post.

Gracias por comentar tu trabajo tan detalladamente para que los novatos podamos entender el

mundo de los microcontroladores.

Sigue adelante.

Saludos desde México.

 :-/
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: bryan394 en 15 de Diciembre de 2010, 00:18:28
hola necesito ayuda en esto!! por favor!!
nesecito resolver esto pero nose como hacerlo sin usar ninguna funcion de division.. solo restas o sumas..

Elaborar un programa (fuente) en lenguaje ensamblador para el PIC16F84A que reciba información binaria de 5 bits en el puerto A y devuelva en un visor de siete segmentos la letra P indicando que el número recibido es primo, caso contrario el visor muestra la letra H indicando que no es primo.

bueno solo necesto la parte de :
Elaborar un programa (fuente) en lenguaje ensamblador para el PIC16F84A que reciba información binaria de 5 bits y determine si es binario o no... por favor!! necesito ayuda urgente!! :(
Título: Re: Busco informacion para configurar PIC16F84A en modo timer
Publicado por: MARTINMARCELO_PER en 28 de Diciembre de 2010, 12:08:08
Hola.
Conozco poco del tema, en realidad soy ingeniero agrónomo, disculpen mi ignorancia en el tema.
Pero requiero información sobre el tema ya que estoy diseñando un experimento, con "cangilones" donde debo registrar pulsos en el tiempo, que deben ser guardados por un lapso de tiempo (datalogger), y cargados a la computadora.
Viendo este foro he aprendido algo. y me he enganchado con el tema.
Mi pregunta es: ¿cuando armo el circuito, cuales serian los pasos para configurar el PIC, de forma  de generar y registrar los imputs de interes (Pulsos y tiempo entre pulsos)? Tambien quisiera saber como configurar el reset, y el ahorro de energia ya que solo registrara durante las lluvias.
Un millon de gracias. y disculpen mi ignorancia.   
   
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: c@Lic_0 en 09 de Febrero de 2011, 12:13:49
hola necesito ayuda en esto!! por favor!!
nesecito resolver esto pero nose como hacerlo sin usar ninguna funcion de division.. solo restas o sumas..

Elaborar un programa (fuente) en lenguaje ensamblador para el PIC16F84A que reciba información binaria de 5 bits en el puerto A y devuelva en un visor de siete segmentos la letra P indicando que el número recibido es primo, caso contrario el visor muestra la letra H indicando que no es primo.

bueno solo necesto la parte de :
Elaborar un programa (fuente) en lenguaje ensamblador para el PIC16F84A que reciba información binaria de 5 bits y determine si es binario o no... por favor!! necesito ayuda urgente!! :(


Pues mira si solamente son 5 bits como maximo llegaras al numero 32, como entre entre el 1 y el 32 no hay demasiados numeros primos (seran unos 10 numeros primos) puedes utilizar tablas para guardas los numeros primos comprendidos entre este rango, una vez que tengas tu dato binario de 5 bits simplemente lo comparas con tu tabla y verificas si es primo o no :-/ :-/, bueno esa la forma mas sencilla :D :D ahora si tu dato binario tiene mas de 5 bits eso ya es otra cosa y ahi si ya tienes que usar divisiones sucesivas para hallar si el numero es primo o no :P :P
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: falflores en 27 de Febrero de 2011, 02:37:25
Hola zuky, excelente material, sumamente didáctico, muchas gracias por compartirlo, queria preguntarte ¿Sabes programar en C, basic o algún otro software de alto nivel?
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 28 de Febrero de 2011, 11:39:52
Hola! Muchas gracias por los comentarios. Si, se programar en C y algo de C++. En el foro hay un par de tutoriales y librerias, igualmente por aquí puedes encontrar casi todo lo compartido:  www.micros-designs.com.ar



Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: zaratustra_x en 02 de Abril de 2011, 20:03:56
Saludos


Suky:
He estado haciendo el ejemplo para inicializar el LCD con el 16F84A siguiendo tu tutorial.

Al final del mismo escribiste que no lo pudiste simular en proteus.

Bueno, leyendo otros foros y el datasheet te comento que si pude

Despues de:
   movlw   LCD_BUS_4_2           ;Vamos a configurar el LCD 4 bits y 5x7 pixeles <D7 D6 D5 D4> = 0x28 con corrimiento
   call LCD_COMANDO         ;Enviamos el comando al LCD

Escribimos:

                movlw   LCD_ON            ;Encendemos la pantalla
           call LCD_COMANDO         ;Enviamos el comando al LCD

donde LCD_ON tiene el valor 0x0C que es el comando para encender la pantalla.

Despues de encenderlo utilizo el comando para limpiar el LCD (0x01) y despues el comando para parpadear el cursor(0x0F) y todo perfecto

El LCD en proteus enciende y empieza a parpadear  :)

Muchas gracias por tu tutorial

 :-/   :-/   :-/
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Olinqui en 08 de Abril de 2011, 04:32:59

Hola a todos soy muy nuevito en esto de los micro controladores PIC hoy estoy trabajando con el 16F84A pero me surgió una duda tengo un código para encender un led con un pulsador y el temporizador lo mantiene encendido 5 seg y después apaga. El tema es que si el pulsador se mantiene presionado los 5 seg corren a partir de que este se suelta y lo que quiero es que el temporizador trabaje independiente sin importar el tiempo que se mantenga presionado el pulsador este es mi código.


 MONITOR   btfsc   PORTA,Pulsador   ; Revisa si es 0 si es asi salta una línea
   goto   Apagar      ; Esta a 1 Apagamos Led
   bsf   PORTB,Led      ; Manda un 1 al registro Led y enciende
   goto   DEMORA      ; Salto a Demora
   goto   MONITOR      ; Revisa nuevamente la condición del Pulsador
Apagar   bcf   PORTB,Led      ; Manda un 0 al registro Led y lo apaga
   goto   MONITOR      ; Revisa nuevamente la condición del Pulsador



Según yo la demora debería ser independiente al monitor del pulsador ya que está en una línea de código más abajo pero no me funciona y no doy con el error haber si me pueden ayudar
Gracias de antemano si me pudieran orientar me serviría mucho para entender mejor el funcionamiento de estos bichitos PIC`s

Adjunto el código completo tal vez el error este en otra parte.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 08 de Abril de 2011, 09:30:23
En teoría si, al pulsar comienza la demora. Pero en hardware real tienes el problema del efecto rebote que puede generarte esos inconvenientes. Puedes esperar 20ms y testear nuevamente como para saber si realmente se ha pulsado o soltado el boton.

Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: emiro99 en 16 de Abril de 2011, 23:37:11
Saludos a todos,
disculpen una pregunta, pero tengo una duda con este pic16F628, ¿Puedo utlizar un módulo comparador y el módulo PWM al mismo tiempo?.  :?

Es que este PIC es nuevo para mi  :-/

De antemano gracias por su valiosa ayuda.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 17 de Abril de 2011, 11:16:31
Hola! Si es el módulo comparador analógico y el módulo CCP en modo PWM, si sin ningún inconveniente. Ahora el módulo CCP en modo comparación y el módulo CCP en modo PWM, no. Éste PIC solo dispone de un módulo CCP, puede cambiar por un PIC16F883, ect.



Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: emiro99 en 30 de Abril de 2011, 13:13:57
Gracias, este foro es lo máximo.
Encuentro respuestas a casi todo!!

Y quiero mostrarles un dato que encontré en microchip, contiene las directivas  _config para cada PIC y como guardar y restaurar registros tras una interrupción incluyendo el PCLATCH.

pero no puedo adjuntar el archivo. :x

Lo subí en otro servidor:

http://depositfiles.com/files/ssadfuyvr
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tazma en 03 de Mayo de 2011, 05:09:07
hola mi pregunta es la siguiente como y que tengo que usar para empezar a programar pic  desde el principio
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 03 de Mayo de 2011, 10:07:59
hola mi pregunta es la siguiente como y que tengo que usar para empezar a programar pic  desde el principio

Lee con detenimiento el primer mensaje.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tazma en 03 de Mayo de 2011, 10:35:35
hola mi pregunta es la siguiente como y que tengo que usar para empezar a programar pic  desde el principio

Lee con detenimiento el primer mensaje.


Saludos!

vaya pues is que tienes razon me voy a poner con el tema gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tazma en 03 de Mayo de 2011, 12:58:54
hola perdonarmi ignorancia llevo casi 3 horas leiendo y ahora queria practicar un poco con el mplab pero ya de entrada me surje una duda cuando voy a empezar el codigo hay que poner lo siguiente 
1. ; #### encabezado #### aqui es donda tengo la duda son asyeriscos lo que hay que poner ?
2.

salu2
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Fer_TACA en 03 de Mayo de 2011, 13:11:00
Deberias de empezar asi:

1.; **** Encabezado **** esta es una linea de comentarios. Tdo lo que esta despuesdel ";" el compilador lo trata asi y no genera codigo. Te sirve como ayuda para saber que programas es. Ejemplo:  Encabezado puede ser "Mi primer programa

2.list p=16F84A  ; Se indica el tipo de micro que vas a utilizar
3.#include P16F84A.inc; Se incluyen los registros de micro utilizado  ya predefinidos
4.__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC; Sirve para configurar los fuses del micro como: si vas aproteger la meoria para que no se pueda leer, activar o no el watchdog, el tipo de oscilador,....

A partir va tu programa

F.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tazma en 03 de Mayo de 2011, 13:19:24
Deberias de empezar asi:

1.; **** Encabezado **** esta es una linea de comentarios. Tdo lo que esta despuesdel ";" el compilador lo trata asi y no genera codigo. Te sirve como ayuda para saber que programas es. Ejemplo:  Encabezado puede ser "Mi primer programa

2.list p=16F84A  ; Se indica el tipo de micro que vas a utilizar
3.#include P16F84A.inc; Se incluyen los registros de micro utilizado  ya predefinidos
4.__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC; Sirve para configurar los fuses del micro como: si vas aproteger la meoria para que no se pueda leer, activar o no el watchdog, el tipo de oscilador,....

A partir va tu programa

F.

ok gracias seguire particando  y leiendo
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Fer_TACA en 03 de Mayo de 2011, 13:20:52
En el primer post tienes un indice de un monton de ejemplos donde puedes ver la estructura de como realizar los programas.

Mirate unos cuantos ejemplos simples y veras que no es complicado
F.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: pentax33 en 02 de Junio de 2011, 06:45:28
Hola

    En los primeros posts estan los ejemplos de la interrupciones, hay uos pasos que no ser el porque.

    En el momento de guradr los valores de W y STATUS se realizan una serie de cambios de nibbles, que no ser ver el porque, pudiendo salvar directamente el valor de cada registro.

Gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 02 de Junio de 2011, 10:20:24
Es para no modificar el estado del registro STATUS.


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: beto1234 en 04 de Julio de 2011, 07:58:27
 Amigo Suky lo que me gustaría para agregar a este gran tutorial seria como manejar las memorias del pic, por ejemplo para almacenar información.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 04 de Julio de 2011, 10:12:25
Amigo Suky lo que me gustaría para agregar a este gran tutorial seria como manejar las memorias del pic, por ejemplo para almacenar información.

Agregue, no hay ningun problema!


Saludos
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Charlie Martinez en 20 de Julio de 2011, 03:36:35
Holaaaa....disculpen   he hecho el primer proyecto que esta en el tema...no tuve problema en comprender la logica del ASM, por lo que fue facil pasarlo al simulador, pero a la hora de compilar me marca 3 errores

list p=16F84A
#include p16F84A.inc
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

esto menciona en la parte inferior
0004 Error: Unrecognized instruction

quiza tenga que ver donde instale el programa que fue la opcion que esta por default
Podrian ayudarme??? es el segundo que trato de hacer ....comienzo a frustrarme  jeje muchas gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: reparamadrid en 26 de Julio de 2011, 10:57:34
 :-/ :-/
Muchas gracias xD







Fontaneros (http://www.repara-madrid.es/fontaneria.html)
Piscinas (http://www.aqualudens.com)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Correia en 27 de Julio de 2011, 00:11:14
buenas noches suky tu tutorial es muy bueno, me gustaria preguntarte algo sobre el PIC16F628A hize la programacion de 4 semaforos de tres colores cada uno como un semaforo ordinario, y una pregunta este fusil  _INTOSC_OSC_NOCLKOUT significa que el oscilador interno de 4Mhz que posee el microcontrolador ha sido activado y funcionara con el, asi como el tmr0 si es configurado como temporizador funcionara con el, por lo que a su vez los pines 15 y 16 de 16F628A pueden ser usados como salida digital para prender algun led? me gustaria su respuesta.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 27 de Julio de 2011, 12:46:01
buenas noches suky tu tutorial es muy bueno, me gustaria preguntarte algo sobre el PIC16F628A hize la programacion de 4 semaforos de tres colores cada uno como un semaforo ordinario, y una pregunta este fusil  _INTOSC_OSC_NOCLKOUT significa que el oscilador interno de 4Mhz que posee el microcontrolador ha sido activado y funcionara con el, asi como el tmr0 si es configurado como temporizador funcionara con el, por lo que a su vez los pines 15 y 16 de 16F628A pueden ser usados como salida digital para prender algun led? me gustaria su respuesta.

Exactamente  ;-)
Título: Re: Mis primeros programas. Tutorial PIC16F84A
Publicado por: LU7FDV en 04 de Octubre de 2011, 13:34:28
El Módulo del Timer 0.
Idéntico al del PIC16F84.

El Módulo del Timer 1.
El Timer 1 a diferencia del Timer 0 es un contador / temporizador de 16 bits. El conteo es realizado por dos registros de 8 bits: (TMR1H (0Fh) y TMR1L (0Eh) ), estos dos registros son tanto leíbles como escribibles.
Así, el registro TMR1 se incrementa de 0000h a FFFFh y en la siguiente cuenta se reinicia en 0000h y así sucesivamente, al reciclarse se activa (en alto) la bandera TMR1IF (PIR1<0>), la cual puede ser utilizada para generar una interrupción, o bien, para ser consultada por poleo, teniendo las mismas precauciones que ya se explicaron antes para la bandera T0IF.

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.

(http://img8.imageshack.us/img8/9830/timer10.jpg)

Modo temporizador
En este modo el Timer se incrementa (si no se considera preescalador) en cada ciclo de instrucción (a la frecuencia Fosc/4). Este modo se selecciona limpiando el bit TMR1CS (T1CON<1>).
El preescalador que se puede intercalar entre el reloj Fosc/4 y el registro TMR1 puede tener sólo uno de 4 valores: 1/1, 1/2, 1/4 y 1/8.
En este caso la temporización de calcula:
Temporización = Ciclo de instrucción. (65536-TMR1) .Divisor de Frecuencia
Vemos que la máxima temporización posible es con TMR1 = 0, y Divisor de Frecuencia en 8, lográndose unos 524.3 ms aprox.

Modo contador
El Timer 1 también puede operar como contador, en este último caso, la entrada a contar se toma de la patita externa RB6/T1OSO/T1CKI.

Configuraciones:
El Timer 1 posee un bit para habilitación / deshabilitación, este es el bit TMR1ON (T1CON<0>) y habilita en alto.
Además, el Timer 1 posee una entrada interna de RESET, el cual puede ser activado por uno cualquiera de los módulos CCP que.
A continuación se describe el principal registro relacionado con el Timer 1 y todos sus bits, excepto los que tienen que ver con el modo contador:
Registro T1CON (10h)
(http://img9.imageshack.us/img9/1343/timer11.jpg)
bits 5:4
T1CKPS1:T1CKPS0.- Bits de selección del valor del divisor de frecuencia del preescalador:
1 1 = divisor 1/8
1 0 = divisor 1/4
0 1 = divisor 1/2
0 0 = divisor 1/1

bit 1
TMR1CS.- Bit de selección de la fuente de reloj
1 = Modo contador (fuente de reloj: patita RC0/T1OSO/T1CKI)
0 = Modo Temporizador (fuente de reloj Fosc/4)

bit 0
TMR1ON.- Bit de habilitación / deshabilitación del Timer 1:
1 = habilita Timer 1
0 = Deshabilita Timer 1



ConfigPIC traé una herramienta adicional que nos ayuda a seleccionar el preescaler y valor inicial del Timer para obtener una temporización deseada:
(http://img139.imageshack.us/img139/8141/21115051.th.jpg) (http://img139.imageshack.us/my.php?image=21115051.jpg)


hola amigo soy nuevo en programacion de pic, necesito que me den una mano tengo un proyecto que necesito bases de tiempo de 1 seg, 5seg, 1 min, agradeceria ayuda hasta pronto y gracias
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: ELECTROTHUNDER73 en 06 de Diciembre de 2011, 00:29:25
ACABO DE INGRESAR A ESTE SISTEMA Y MANDO SALUDOS DESDE LA CIUDAD DE MEXICO, ESPERANDO SER PARTE DE SU CLUB DE LECTORES
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: commo64 en 26 de Mayo de 2012, 16:46:23
Suky ,

Primero que nada felicitarte por este tutorial!

Estoy comenzando nuevamente en esto de la programacion de PIC16f84 ,mas o menos por el 2001 termine de armar un robot (monty) ,aunque algo llegue hacer luego por distintos motivos largue todo.

Hace algunos meses cansado de verlo ahi en un estante sin hacer nada (jaja) me propuse ver si por fin le encontraba la vuelta a la programacion.

Conclusion hace unas horas este post me hizo a agarrar ganas de registrarme ,oh sorpresa ya me habia registrado hace bastante! ,recupere mi contraseña y usuario y aca estoy!

Queria probar el programa para el LCD en el P16f84 (copie el programa y lo pegue en el Mplab) ,luego al compilarlo me di cuenta despues de un buen rato de buscar que en la linea 51 hay un error de tipeo ,falta una L para la palabra LCD.

Corregido esto pude compilarlo.

Ahora me pongo a armar el circuito para probarlo.

Otra vez ,felicitaciones!

Saludos

Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Suky en 26 de Mayo de 2012, 17:40:48
Gracias por el dato! Éxitos en los proyectos!!


Saludos!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: freemanman2012 en 25 de Septiembre de 2012, 09:28:15
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
  • Introducción (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201393#msg201393)
  • Mi Primer Programa, control de un led (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201396#msg201396)
  • Creación de Demoras, Led titilando (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201398#msg201398)
  • Creación de Tablas, Control Display 7 Segmentos (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201401#msg201401)
  • Direccionamiento Indirecto, Control Display 7 Segmentos (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201402#msg201402)
  • Control de varios Displays 7 Segmentos con multiplexión (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201403#msg201403)
  • Control de varios Displays 7 Segmentos con 74LS164 (http://www.todopic.com.ar/foros/index.php?topic=24720.msg213264#msg213264)
  • Interrupciones, Registros y guardado temporario de STATUS y W (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201405#msg201405)
  • Interrupción TMR0, modo Temporizador (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201407#msg201407)
  • Interrupción TMR0, modo Contador (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201408#msg201408)
  • Interrupción RB0, Control de Led (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201409#msg201409)
  • Interrupción RB4 a RB7, Control Teclado Matricial (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201410#msg201410)
  • Control del LCD, Pantalla de Cristal Liquido (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201411#msg201411)
  • Comunicación RS232 (http://www.todopic.com.ar/foros/index.php?topic=24720.msg201413#msg201413)

Todas las simulaciones hechas en proteus, aqui (http://www.mediafire.com/?rxcjmjvl1jm) (Para el PIC16F84A)



El PIC16F628A/648A

  • Introducción (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204908#msg204908)
  • Timer1 + Ejemplo (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204910#msg204910)
  • Timer2 + Ejemplo (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204912#msg204912)
  • Módulo de comunicación serie (Usart) + Ejemplo (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204913#msg204913)
  • Comparadores analógicos + Ejemplo (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204915#msg204915)
  • Módulo CCP. Introducción (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204920#msg204920)
  • Modo Captura + Ejemplo: Medir Frecuencia (http://www.todopic.com.ar/foros/index.php?topic=24720.msg204920#msg204920)
  • Modo Comparación + Ejemplo: Señal de frecuencia variable (http://www.todopic.com.ar/foros/index.php?topic=24720.msg207734#msg207734)
  • Modo PWM + Ejemplo: Señal de 2 Frecuencias distintas (http://www.todopic.com.ar/foros/index.php?topic=24720.msg207737#msg207737)
  • 2º Ejemplo PWM. Variando el Ciclo de Trabajo.- (http://www.todopic.com.ar/foros/index.php?topic=24720.msg207739#msg207739)


  • Más Información (http://www.todopic.com.ar/foros/index.php?topic=24720.msg207741#msg207741)

  • COMUNICACIÓN IR - PIC16F628 Y PIC12F629 (http://www.todopic.com.ar/foros/index.php?topic=24720.msg224696#msg224696) realizado por beto1234 (http://www.todopic.com.ar/foros/index.php?action=profile;u=21383)

 
Herramientas
Software para escribir nuestro código y compilar: MPLAB (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002)
Software para simular:  Proteus  (http://www.labcenter.co.uk/download/prodemo_download.cfm)
Una plaquita programadora.
Software para grabar nuestro PIC, se puede usar el WinPic800 (http://www.winpic800.com) o el Icprog (http://www.ic-prog.com/download.html)

:-)  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 (http://www.mediafire.com/file/ak3zio5hl2e/Para Comenzar.rar)


Datasheets

DATASHEET del PIC16F84A (http://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf)
DATASHEET del PIC16F628A/648A (http://host.nigde.edu.tr/muzam/PIC16F648A.pdf)



ConfigPIC (http://www.mediafire.com/file/z2o1jym5zzm/ConfigPIC.rar): Software para realizar el código automáticamente a partir de una interfase de configuración.
(http://img135.imageshack.us/img135/3100/54953366.th.jpg) (http://img135.imageshack.us/my.php?image=54953366.jpg)
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: donpablio en 29 de Marzo de 2013, 18:14:37
Hola necesito un poco de ayuda estoy tratando de aprender mediante este tutorial, pero quiero realizar los mismos programas para ql pic12f683 pero no puedo realizar nisiquiera el primeroel de encender un led con un pushbutton si me pueden ayudar se los agradeceria asi es como tengo el codigo:

   list          p=12F683
      #include    <p12f683.inc>
               
      __CONFIG   _FCMEN_OFF & _IESO_OFF & _MCLRE_OFF & _WDT_OFF & _INTOSCIO
                         
      org 0x00                   
               
      BSF       STATUS,RP0    ;PASANDO DE BANCO 0 A BANCO 1
      MOVLW      b'001010'      ;CARGANDO EN W
      MOVWF    TRISIO         ;CONFIGURAR TRISIO COMO W
      BCF       STATUS,RP0    ;PASANDO DEL BANCO 1 A BANCO 0
      MOVLW      b'000000'      ;GPIO APAGADO
      MOVWF      GPIO
AQUI:
      BTFSC      GPIO, 1         
      GOTO      APAGAR
      MOVLW      b'000001'
      MOVWF      GPIO
      GOTO      AQUI
      
APAGAR:
      MOVLW      b'000000'
      MOVWF      GPIO
      GOTO       AQUI
      
       END

espero y me puedan ayudar gracias de ante mano
estos son los bancos de memoria
(https://www.box.com/s/25no04zuz5pl59nk8kwv)
Título: Re: Mis primeros programas. PIC16F84A y PIC16F628A/648A
Publicado por: joseydoris en 13 de Abril de 2013, 04:02:37
Un saludo Suky:Estoy intentado hacer un receptor para un control remoto de tv,pruebo con el modulo CCP modo captura saco la lectura por el puerto A para visualizar los valores emitidos por cada tecla y no se quedan estables los valores.Quizas este errado con este modulo para esta aplicacion.Att jose
Título: AYUDA
Publicado por: Miguel_P en 12 de Septiembre de 2013, 15:56:19
Hola que tal,  necesito su ayuda si no es mucha molestia, debo hacer un asm en mplab que controle un motor hacia la izquierda, derecja, paro osea 3 pushbuttons con el pic16f84a. Y usando el l293d para inverdir el voltaje del motor, el motor es dc. el problema que tengo es que mi programa no me corre y ya he usado varios programas pero sigo sin obtener ese resultado y pues como apenas estoy iniciando en esto me cuesta un poco de trabajo entenderle.   
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: joseydoris en 13 de Septiembre de 2013, 01:21:38
Un saludo:lo puedes hacer con un l298,es uh puente H y segun los pines que utilices puedes hacerlo girar izd o der
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Citron23 en 22 de Septiembre de 2013, 11:45:36
Como dicen que es de bien nacido ser Agradecido. Muchas gracias por los tutoriales Suky ((:-))

Un Saludo  :-/
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: JAR en 02 de Junio de 2014, 14:28:40
Hola chicos.
Estoy siguiendo este tutorial en el poco tiempo que tengo, pero al empezar con los codigo, al cargarlo en Mplab, me indica un solo error y no se como solucionarlo.
Ante todo, felicitar a Suky por este fantástico tutorial y a continuación os indico el código que es el primero de Suky y el error;


; **** Encabezado ****
        list p=16F84A
   #include P16F84A.inc
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
Led      equ   0   ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
Pulsador   equ   0   ; Definimos Pulsador como el bit 0, en este caso sera para PORTA
;**** Configuracion de puertos ***
Reset   org   0x00   ; Aqui comienza el micro.-
           goto   Inicio   ; Salto a inicio de mi programa.-
           org   0x05   ; Origen del codigo de programa.-
Inicio   bsf   STATUS,RP0    ; Pasamos de Banco 0 a Banco 1.-
            movlw   b'11111'   ; Muevo 11111 a W.-
                 movwf   TRISA      ; Cargo en TRISA.-
            movlw   b'11111110'   
            movwf   TRISB
            bcf   STATUS,RP0   ; Paso del Banco 1 al Banco 0
            bcf   PORTB,Led   ; Comienza apagado.-
;**** Control de Led ****
Bucle            btfsc   PORTA,Pulsador   ; Preguntamos si esta en 0 logico.-
            goto   Apagar         ; Esta a 1 logico, Apagamos Led.-
            bsf   PORTB,Led      ; Esta a 0 logico, Encendemos Led.-
            goto   Bucle         ; Testeamos nuevamente la condicion del Pulsador.-
   
Apagar   bcf   PORTB,Led      ;Apagamos Led.-
           goto   Bucle         ;Testeamos nuevamente la condicion del Pulsador.-
   
              end




Y esta es la respuesta de Mplab

Building LED.HEX...

Compiling LED.ASM:
Command line: "C:\ARCHIV~1\MPLAB\MPASMWIN.EXE /aINHX8M /e+ /l+ /x- /c+ /rhex /p16F84A /q F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM"
Message[301] C:\ARCHIV~1\MPLAB\P16F84.INC 37 : MESSAGE: (Processor-header file mismatch.  Verify selected processor.)
Warning[205] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 5 : Found directive in column 1. (__CONFIG)
Error[113]   F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 12 : Symbol not previously defined (inicio)
Message[302] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 16 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 18 : Register in operand not in bank 0.  Ensure that bank bits are correct.

MPLAB is unable to find output file "LED.HEX". This may be due to a compile, assemble, or link process failure.

Build failed.

¿Me podríais decir que estoy haciendo mal?
Muchas gracias de antemano.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: JAR en 02 de Junio de 2014, 15:17:25
Hola chicos.
Estoy siguiendo este tutorial en el poco tiempo que tengo, pero al empezar con los codigo, al cargarlo en Mplab, me indica un solo error y no se como solucionarlo.
Ante todo, felicitar a Suky por este fantástico tutorial y a continuación os indico el código que es el primero de Suky y el error;


; **** Encabezado ****
        list p=16F84A
   #include P16F84A.inc
__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
Led      equ   0   ; Definimos Led como el bit cero de un registro, en este caso PORTB.-
Pulsador   equ   0   ; Definimos Pulsador como el bit 0, en este caso sera para PORTA
;**** Configuracion de puertos ***
Reset   org   0x00   ; Aqui comienza el micro.-
           goto   Inicio   ; Salto a inicio de mi programa.-
           org   0x05   ; Origen del codigo de programa.-
Inicio   bsf   STATUS,RP0    ; Pasamos de Banco 0 a Banco 1.-
            movlw   b'11111'   ; Muevo 11111 a W.-
                 movwf   TRISA      ; Cargo en TRISA.-
            movlw   b'11111110'   
            movwf   TRISB
            bcf   STATUS,RP0   ; Paso del Banco 1 al Banco 0
            bcf   PORTB,Led   ; Comienza apagado.-
;**** Control de Led ****
Bucle            btfsc   PORTA,Pulsador   ; Preguntamos si esta en 0 logico.-
            goto   Apagar         ; Esta a 1 logico, Apagamos Led.-
            bsf   PORTB,Led      ; Esta a 0 logico, Encendemos Led.-
            goto   Bucle         ; Testeamos nuevamente la condicion del Pulsador.-
   
Apagar   bcf   PORTB,Led      ;Apagamos Led.-
           goto   Bucle         ;Testeamos nuevamente la condicion del Pulsador.-
   
              end




Y esta es la respuesta de Mplab

Building LED.HEX...

Compiling LED.ASM:
Command line: "C:\ARCHIV~1\MPLAB\MPASMWIN.EXE /aINHX8M /e+ /l+ /x- /c+ /rhex /p16F84A /q F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM"
Message[301] C:\ARCHIV~1\MPLAB\P16F84.INC 37 : MESSAGE: (Processor-header file mismatch.  Verify selected processor.)
Warning[205] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 5 : Found directive in column 1. (__CONFIG)
Error[113]   F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 12 : Symbol not previously defined (inicio)
Message[302] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 16 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\ELECTR~1\MICROC~1\PROJEC~1\LED.ASM 18 : Register in operand not in bank 0.  Ensure that bank bits are correct.

MPLAB is unable to find output file "LED.HEX". This may be due to a compile, assemble, or link process failure.

Build failed.

¿Me podríais decir que estoy haciendo mal?
Muchas gracias de antemano.


Hola de nuevo.
Ya resolví el problema y era el siguiente: En la fila diez, (goto inicio, inicio) lo escribo en minúsculas y en la fila 12, (Inicio   bsf   STATUS,RP0), lo pongo en mayúsculas por lo que no era reconocido por el programa.
Así y todo, muchas gracias.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: purevideo en 18 de Enero de 2015, 18:57:53
Hola buenas tardes, antes que nada me gustaría decir que el post es muy interesante y me ha enseñado bastantes cosas. Feilicito al autor del post por tratar de ayudar a los que apenas estamos empezando. Dicho esto, me gustaría ver si alguien me alcara una pequeña duda que tengo, verán, decidiendo ir un poco más allá en el programa del contador se me ocurrió que además de que cuente de forma ascendente también lo haga de forma descendente, en un principio no creí que fuera tan difícil y en realidad hacer el conteo regresivo no es el problema.

El programa tiene dos botones, uno que suma y otro que resta una unidad a la variable Contador, después se suma el valor a PCL y retrona el valor del número a mostrar con un RETLW, vamos que es el mismo que está en el post. El problema que tengo es que no logro conseguir que al presionar el botón "restar" cuando contador es 0 se resté 1 y se convierta en 0xFF y el programa deja de funcionar (al menos en proteus).  He buscado por la red ejemplos para poder ver en que me equivoco y no he encontrado nada, por eso vengo aquí a ver si alguien me puede ayudar.

Este es el pedazo de código que se encarga de restar una unidad a contador:
Código: [Seleccionar]
[center].[/center]
[center].[/center]
[center].[/center]
INICIO ;Aquí inicia el programa principal
    BTFSC   PORTC,BOTONME; Como utilizo resistencia pull-up el micro recibe 1s y cuando se presiona boton hay un 0
    GOTO    MAS ; Si un 1 (no se presiona boton) entonces voy a la "función" MAS
    CALL    DEMORA_19MS ;retardo anti rebote
    BTFSC   PORTC,BOTONME
    GOTO    INICIO
    GOTO    ESCERO ; Aquí intento saber si en la variable contador hay un cero
MAS
    BTFSC   PORTC,BOTONMA
    GOTO    INICIO
    CALL    DEMORA_19MS
    BTFSC   PORTC,BOTONMA
    GOTO    INICIO
    GOTO    SUMAR
ESCERO
    MOVLW   CONTADOR ; Aquí cargo contador en W (Ej. 1)
    IORWF   0x00,0 ; Aquí hago un OR entre Wy F para saber si hay un 0 en el resultado y que active el BIT Z (en proteus nunca se activa el bit Z, también intenté DECF y nunca me marcó el BIT Z)
    BTFSC   STATUS,Z ; Si hay un 0 en el bit Z significa que no hay un cero, por lo que puedo restar normalmente; si hay un 1 significa que estoy en 0 y si resto me voy a -1
    GOTO    INICIO
RESTAR
    DECF    CONTADOR,1 ;Resto una unidad al contador
    MOVF    CONTADOR,0 ; La muevo a F
    CALL    BCD ;LLamo BCD para mostrar numero
    MOVWF   PORTB
[center].[/center]
[center].[/center]
[center].[/center]

No pongo todo el código porque es el mismo que el publicado así que solo pongo lo que agregué. Un saludo y si me equivoqué en algo tan simple, lo siento pero apenas aprendo xD.

Un saludo!
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tapi8 en 20 de Enero de 2015, 06:09:39
Bienvenido al foro Purevideo.

Deberias abrir un hilo nuevo con tu consulta en vez de seguir aqui.

Citar
El problema que tengo es que no logro conseguir que al presionar el botón "restar" cuando contador es 0 se resté 1 y se convierta en 0xFF y el programa deja de funcionar (al menos en proteus). 

Seguramente al restar 1 y darte como resultado 0XFF al ir a las tablas se te desbordan y se pierde el programa. Debes de poner como condicion que si es 0 NO reste, pasara a un numero inferior el que este a su izquierda y ese 0 pasara a ser 9.
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: milnac en 11 de Julio de 2015, 15:02:51
Citar
Reset   org   0x00   ; Aqui comienza el micro.-
   goto   Inicio   ; Salto a inicio de mi programa.-
   org   0x05   ; Origen del codigo de programa.-
Inicio

Hola Suky.
Cual es la funcionalidad de "org 0x05" si siempre va a estar saltando hasta "goto Inicio ". Veo que nunca va a tener una secuencia que incluya a "org 0x05" (Del ejemplo 1 de este tutorial).

Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 11 de Julio de 2015, 16:24:08
Bueno no es necesario suky para responderlo, esta para evitar que si por error se ejecuta una interrupcion, no produsca un comportamiento raro al no tener alguna instruccion.

Suponete

Código: ASM
  1. ORG 0x00
  2.    GOTO Inicio     ;0x00
  3. Inicio
  4.    MOVLW 0x0F   ; 0x01
  5.    MOVWF PORTB ; 0x02
  6.    MOVLW 0x10   ; 0x03
  7.    MOVWF PORTA ; 0x04
  8. ; Resto del programa.

Entonces si por equivocacion del usuario activa la interrupcion, la primer instruccion que va a ejecutar es "MOVWF PORTA" y realmente no tenes idea de lo que hay en W en ese momento.
Por eso mismo yo siempre defino los vectores de interrupcion, por mas que no lo utilize, quedando:

Código: ASM
  1. ORG 0x00
  2.    GOTO Inicio
  3.    ORG 0x04
  4.    GOTO Inicio
  5.  
  6. ; Aca Todo mi programa

Y me aseguro que nada incorrecto pueda pasar. Es una costumbre, y no afecta a nadie.

Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: SimonReed en 27 de Agosto de 2015, 15:41:01
Estimados amigos de todopic. Es primera vez que ingreso, he leido bastante en este foro y por lo cuál agradezco el que compartan con los que somos iniciantes en este maravilloso mundo de los PIC. Muchas Gracias.
Permítanme preguntar algo básico, por favor.

Estoy estudiando recien las interrupciones del 16f84, y he creado un rutina pequeña para probar dos de las 4 interrupciones de este PIC. Hay un fenómeno que no he podido dilucidar. Estoy probando la Interrupción RBIE (por activación de RB7:RB4) y cuando se debe, el programa no borra el flag INTCON,0 por programa (bcf intcon,0) cuando lo simulo no hace nada. Luego al pasar por RETFIE, tampoco pone a 1 GIE  (intcon,7). He usado MPLAB v7.2 y 7.4 y pasa lo mismo.

He usado la misma rutina para probar la Interr. INTE y funciona ok.   ¿¿¿???

Adjunto mi humilde código, a ver si alguien me da una mano.  Muchas Gracias

;Prueba dos tipos de interrupciones: cambio en RB7:RB4 ; int.externa RB0/INT
;Se ha puesto un led en A0 para verificar la interr. por in en RB7:RB4 y
;se ha puesto un led en A1 para verificar la interr. por in en RB0/INT

   list   p=16f84a
   #INCLUDE P16F84A.INC
   radix   hex
   radix   dec
;line8
porta   equ 0x05
portb   equ   0x06
trisa   equ 0x85
trisb   equ 0x86      
status   equ   0x03
optio   equ   0x81
intcon   equ 0x0b
tmr0   equ 0x01
saveW   equ 0x0c
saveSTATUS   equ 0x0d

#DEFINE   banco0   bcf   status,5
#DEFINE   banco1   bsf status,5
;---------------------------------------------------------------------
   org      0x000
   goto    ini
   org       0x04      ; Vector de interrupcion
   goto   inter      
; Inicio de programa
; -------------------- Definiciones --------------------------------
ini
   banco1            ; banco1
   movlw   b'11111111'   ; Puerta b entradas
   movwf   trisb
   movlw   b'00000000'   ; Puerta a salidas
   movwf   trisa      
   movlw   b'01000000'
   movwf   optio         
   movlw   b'10001000'   ; intcon: GIE=1, y RBIE=1  solo interr. gral y la interr. por puertas RB7:RB4   
   movwf   intcon   
   banco0            ; banco0
;   clrf   porta


;Programa Principal
;----------------------------------------------------------------------
dormir   
   nop
   nop
   goto   dormir

;Rutina Servicio Interrupciones
;----------------------------------------------------------------------
inter
   movwf   saveW      ;Guarda W y STATUS, como se recomienda
   swapf   status,0   ;Guarda W y STATUS, como se recomienda
   movwf   saveSTATUS   ;Guarda W y STATUS, como se recomienda
   
   btfsc   intcon,0   ;salta si el flag RBIF de INTCON es 0, si es 1 sigue
   goto   led0      ;(Se ha provocado un Stimulus sobre RB7. Es un high pulse de 2 cycles)
;   btfsc   intcon,1   ;salta si el flag INTF (RB0/INT) es 0, si es 1 sigue
;   goto   led1
;   btfsc   intcon,2   ;salta si el flag TOIF (TMR0) es 0, si es 1 sigue.
;   call    led2
   bsf      porta,0
   swapf   saveSTATUS,0
   movwf   status
   swapf   saveW,1
   swapf   saveW,0
    bcf      intcon,0
   retfie

;Subrutinas de Interrupción
;----------------------------------------------------------------------
led0
   btfsc   porta,0      ;se verifica si led en puerta A0 está encendido
   goto    led0_off   ;se apaga si está encendido
   bsf      porta,0
   swapf   saveSTATUS,0   ;Se recuperan los registros W y STATUS
   movwf   status         ;Se recuperan los registros W y STATUS
   swapf   saveW,1         ;Se recuperan los registros W y STATUS
   swapf   saveW,0         ;Se recuperan los registros W y STATUS
   bcf      intcon,0      ;SE PIDE BORRAR EL FLAG DE LA INTERR., PERO NO FUNCA EN LA SIMULACIÓN MPLAB V.7.2, V7.4
   retfie               ;SE SALE DE LA INTERR, Y GIE DE INTCON NO VUELVE A 1, SE QUEDA EN 0.
led0_off
   bcf      porta,0
   swapf   saveSTATUS,0
   movwf   status
   swapf   saveW,1
   swapf   saveW,0
;   movlw   b'10001000'
;   movwf   intcon
   bcf      intcon,0
   retfie


led1
;   btfsc   porta,1
;   goto    led1_off
;   bsf      porta,1
;   bcf      intcon,1
;   retfie
led1_off
;   bcf      porta,1
;   bcf      intcon,1
;   retfie
end
Título: Re: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 27 de Agosto de 2015, 17:52:26
Bueno varias cosas sobre tu programa, todavia no concernientes a tu problema:

Código: ASM
  1. radix   hex
  2.    radix   dec

No tiene sentido repetir el radix, el radix hace que lo que tome sea decimal/hexa o lo que sea.

Código: ASM
  1. radix hex
  2. MOVLW 10
  3. ; W = 32 decimal = 10 hexa
  4.  
  5. radix dec
  6. MOVLW 10
  7. ; W= 10 decima = A hexa

Todo esto:

Código: ASM
  1. porta   equ 0x05
  2. portb   equ   0x06
  3. trisa   equ 0x85
  4. trisb   equ 0x86      
  5. status   equ   0x03
  6. optio   equ   0x81
  7. intcon   equ 0x0b
  8. tmr0   equ 0x01

Es redundante, ya esta definido en el P16F84A.INC. lo unico que esta hecho en mayusculas MOVWF TRISA y tienen los mismos nombres que en el DATASHEET, al igual que los bits ejemplo INTCON,T0IF es mas facil de recordar que un INTCON,2

Algo que tal ves no parece pero si tenes 3 interrupciones como tenes vos, no tiene sentido repetir lo de recuperar el STATUS y W 3 veces.

Código: ASM
  1. inter
  2.    movwf   saveW      ;Guarda W y STATUS, como se recomienda
  3.    swapf   status,0   ;Guarda W y STATUS, como se recomienda
  4.    movwf   saveSTATUS   ;Guarda W y STATUS, como se recomienda
  5.    
  6. ;   btfsc   intcon,0   ;salta si el flag RBIF de INTCON es 0, si es 1 sigue
  7. ;   call   led0      ;(Se ha provocado un Stimulus sobre RB7. Es un high pulse de 2 cycles)
  8.    btfsc   intcon,1   ;salta si el flag INTF (RB0/INT) es 0, si es 1 sigue
  9.    call   led1
  10.    btfsc   intcon,2   ;salta si el flag TOIF (TMR0) es 0, si es 1 sigue.
  11.    goto    led2
  12.    bsf      porta,0
  13. fin_interrupcion
  14.    swapf   saveSTATUS,0
  15.    movwf   status
  16.    swapf   saveW,1
  17.    swapf   saveW,0
  18.    retfie
  19.  
  20.  
  21. led1
  22.    btfsc   porta,1
  23.    goto    led1_off
  24.    bsf      porta,1
  25.    bcf      intcon,1
  26.    return
  27. led2
  28.    btfsc   porta,1
  29.    goto    led1_off
  30.    bsf      porta,1
  31.    bcf      intcon,1
  32.    goto    fin_interrupcion

Ahi te puse 2 ejemplos, uno con goto y otro con CALL (no esta correcto el codigo pero es para que veas la forma del goto y call, lo de adentro de led1 y led2 fue un copy paste). Observa que hay un solo punto de salida de la interrupcion (un solo retfie y ahi se recuperan los valores de STATUS y W)
El CALL te permite ver todas las interrupciones si es que hay 2 activas y luego salir, mientras que con el GOTO vas a procesar una, y luego cuando intente activar nuevamente las interrupciones ( RETFIE ) va a entrar nuevamente.
En un programa comun donde tenes codigo en el tu loop principal, no podes hacer lo que hiciste, es decir usar el RETFIE sin devolver los valores a STATUS y W. En este ejemplo no afecta en nada por que tu loop principal tiene 2 NOPs y no se modifica ninguna bandera o W. Pero en un programa que si tenga codigo estas obligado. Otra cosa. LO ULTIMO debe ser esas instrucciones, luego de eso no deberia ir nada que afecte a W o a STATUS.

Aunque esto te paresca capricho mio es mas facil de recordar lo que te voy a decir a continuacion
Esto:

Código: ASM
  1. swapf   saveW,F
  2.    swapf   saveW,W

es mas facil de recordar que esto:

Código: ASM
  1. swapf   saveW,1
  2.    swapf   saveW,0

Donde F indica que el resultado va al registro y W a W obviamente. Creo que esto te va a hacer la vida mas facil a vos y a mi.

-----------------------------------

Por ultimo, ahora si la solucion de tu problema.
Las interrupciones externas del PORTB siempre se comportaron de la misma manera. Yo pienso que esta mal, pero hay que tenerlo en cuenta.
Cuando ocurre una interrupcion por cambio de nivel del pin, se activa el flag de interrupcion. La unica manera de poder borrar ese flag es LEYENDO el puerto, recien ahi te permite borrarlo.
Entonces si vos no lees el PORTB el flag RBIF se mantiene en 1, cuando actua el RETFIE y pone el GIE a 1, hace que vuelva a entrar a la interrupcion. En tu caso estaria siempre entrando a la interrupcion ( es decir GIE = 0 por que esta dentro de la misma siempre, igual que en tu caso)
Siguiendo el ejemplo que di antes:

Código: ASM
  1. led0
  2.    movf   PORTB     ; Leo puerto
  3.    bcf      intcon,0    ; borro flag
  4.    ; Ahora si el codigo que debe hacer la interrupcion
  5.  
  6.    btfsc   porta,0      ;se verifica si led en puerta A0 está encendido
  7.    goto    led0_off   ;se apaga si está encendido
  8.    bsf      porta,0
  9.    return
  10. led0_off
  11.    bcf      porta,0
  12.    return
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: Christian Manuel Hernande en 18 de Octubre de 2015, 22:28:42
HOLA AMIGO BUENAS NOCHES ESPERO ME PUEDAS AYUDAR , OYE MI PROFESOR ME PIDIO UN PROGRAMA EN EL PIC 16F628 EL CUAL ESTA CONECTADO DIRECTAMENTE A UN DISPLAY DE CATODO COMUN  SIN DECODIFICADOR NI NADA ESTA DIRECTO CONECTADO EL DISPLAY POR EJEMPLO EL PIN "A" DEL DISPLAY ESTA CONECTADA AL PUERTO RB0  ,EL PIN "B" ESTA CONECTADO A RB1 Y ASI SUCESIVAMENTE , EL CHISTE ES QUE ME PIDIO UN PROGRAMA CON EL CUAL YO MUESTRE EL NUMERO 4 EN EL DISPLAY ME PODRAS AYUDAR A HACERLO ,GRACIAS AMIGO APENAS ME ADENTRO EN ESTE MUNDO DEL PIC.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 18 de Octubre de 2015, 23:16:47
Hola Christian.

Primero unas cosas, intenta no escribir todo en mayuscula, creo que hasta se dificulta leerlo de esa forma.
Y con respecto al codigo, si te podemos ayudar. Si el profesor te lo dio para que lo hagas es para que aprendas. De nada sirve que te demos el codigo completo. Pero aun asi te podemos indicar algo y si ya tenes un codigo realizado y no te funciona, aun mas facil va a ser orientarte.

Aunque posteaste aca, quiero preguntarte algunas cosas:

- ¿En que lenguaje de programacion te pidieron que lo hagas? ASM? C? Basic?
- El programa que pedis es super facil, asi como lo describiste de solo encender un 4 es muy muy muy muy facil. Me atrevo a decir que solo necesitas unas 10 instrucciones de ASM, 2 mas si es que queres los vectores de reset/interrupcion y tal ves 1 mas por la palabra de configuracion (la cual te lo genera solo el MPLAB).

Asi que ... que deberias saber... Si vas por Assembler que es lo que trata este post, vas a tener algo asi:


Código: [Seleccionar]
#include "p16f628a.inc"

; Bits de configuracion , te lo da el MPLAB X

Principal:
          ; Aca la configuracion del puerto B como salida, mira el datasheet y seguro que te da el codigo para ponerlo todo como digitales, unas 7 maximo creo

          ; Aca pongo el valor del puerto, 2 instrucciones

Loop:
          GOTO Loop      ; Loop infinito que no hace mas nada

En resumen, los bits de configuracion como dije ya 2 veces, te los da el MPLAB X, solo te vas abajo tenes unas pestañas, elegis Configuration Bits, y ahi seleccionas los bits de configuracion.
La parte de la configuracion, andate al datasheet , en I/O Ports tenes el puerto B, buscalo y lee ahi que tiene explicado para que sno cada codigo, sino te vas al final de lo del puerto B y tenes todas los registros y bits que afectan al puerto B. Luego vas a tener que buscar en el PDF registro por registro y activar los bits necesarios. ( Solo tenes que cargar el TRISB, asi que se reduce a 3 instrucciones )
La parte que le das el valor al puerto, le pones un 1 al bit que queres que encienda en tu display. Si por ejemplo queres que se encienda la seccion C del display, pones un 1 en RB2, y directamente para no ir bit a bit poniendo unos y ceros, lo haces todo junto con:

Código: [Seleccionar]
MOVLW 0b11111111 ; Aca numero en binario, hexa, lo que sea.
MOVWF PORTB

Finalemente un loop infinito que se quede ahi para siempre. Ya que va a saltar siempre al GOTO.
Si no haces este proyecto con lo que te di, te deberia dar el codigo completo por que es muy simple y la idea es que aprendas.

Finalmente:

Configuracion : 3 instrucciones
Cargar el puerto: 2 instrucciones
Loop: 1 instruccion

6 instrucciones y completaste tu programa.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: SIberiano56 en 26 de Octubre de 2015, 22:03:12
Hola, disculpe las molestias, soy nuevo en esta pagina y no se como publicar una pregunta, necesito hacer lo siguiente, estoy haciendo un codigo para una maqueta de un ascensor de tres pisos, planta baja, primer y segundo piso, en cada piso hay un sensor conectados a los pines RA1, RA2, Y RA3, ya tengo mi codigo armado, pero quiero simularlo en el mplab, no consigo simular el hecho de que se active el sensor en el pin RA1 con la ventana de estimulos, si puedo realizar una interrupcion por RB0 que se da cuando se abre la puerta de la cabina, alguien sabe como puedo realizar el estimulo por el puerto A? Desde ya, muchas gracias!!
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 26 de Octubre de 2015, 23:14:56
Seria bueno que pusieras que PIC estas usando, si es un PIC con conversor analogico digital tenes que recordar que para que el micro sea capas de leer las entradas necesitas pasar las entradas a digitales, ya que en el reset todos los pines que poseen el nombre ANx pasan a ser analogicos, y si los lees, lees un 0, imagino que por eso no podes usar el estimulo para cambiar de valor.
Pero de la misma forma que haces el estimulo del puertoB, lo harias con el puerto A, lo unico que se me ocurre es esa diferencia.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: SIberiano56 en 27 de Octubre de 2015, 23:26:16
Hola, gracias por responder, estoy usando un 16f628a, y tengo deshabilitado los comparadores del puerto a,
;movlw    0x07
;movwf    CMCON

con esas instrucciones y con la palabra de configuracion __CONFIG 3F10 que segun mi profe ya indica que deshabilitamos los comparadores.

desde ya muchas gracias!

Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: maryenita en 05 de Marzo de 2016, 08:19:10
Que buenos tus tutoriales, gracias por compartir tus conocimientos, estoy recién empezando con Microcontroladores se hace muy difícil a veces poder entender ciertos instrucciones.-

Gracias
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: tidustag en 01 de Mayo de 2016, 01:20:04
Qué tal soy nuevo en este foro y es muy genial la verdad, quisiera , si es posible, que me den alguna orientación sobre un problema que tengo, es el siguiente:

Se necesita un ventilador extractor para un baño y que cumpla con los siguientes requerimientos:

-cuando se cierre la puerta de dicho  baño, se debe de encender el ventilador de 220Vac

-cuando la puerta del baño se abre(después de haber estado cerrado) el ventilador tendrá que  permanecer encendido por tiempo de 3 minutos.
  si en ese tiempo se cierra y abre la puerta se  reiniciará la cuenta de 3 minutos para luego desconectar el ventilador.

-durante dicho tiempo se titilará un led a razón de 1 segundo.


Creo que es necesario usar interrupción externa por RB0, gracias de antemano, saludos!
Título: Re: Mis primeros programas. Manual PIC16F84A
Publicado por: gera13 en 04 de Junio de 2017, 23:55:59
disculpa suki,
si podrias habilitar las imagenes donde esta el hardware necesario y el diagrama para hacer el contador de varios digitos porfavor
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: jorgebermudez_ en 05 de Junio de 2017, 01:13:40
El link de los programas en Proteus esta caído
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: aries en 20 de Noviembre de 2018, 18:54:02
Hola
Suky por favor resubir el archivo con las simulaciones hechas en Proteus, para el PIC16F84A.
Igualmente está caído el link con las Directivas _CONFIG que colocó emiro99 en la página 9

Muchas gracias.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: paberi90 en 04 de Septiembre de 2019, 12:06:52
Buenos días, estoy implementado un contador de 2 dígitos con 3 pulsadores ascendente, descendente y reset, funciona casi perfecto, necesito que los display inicien prendidos en cero cero, pero solo se encienden al iniciar el conteo.

Por favor alguien que me ayude a modificar el código y saber si se puede migrar a 16f628a

Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: paberi90 en 04 de Septiembre de 2019, 12:09:20
Buenos días, ya lo solucione tan pronto lo tenga listo lo subiré para compartirlo a quien lo necesite.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 04 de Septiembre de 2019, 14:20:25
El problema es simple.....

El codigo de mostrar unicamente se ejecuta cuando incrementa, decrementa, etc. Y ahi esta el problema.

Tu loop principal deberia:
 - Leer los botones
 - Cambiar el contador en caso de que sea necesario
 - Mostrar

De esa forma siempre se muestra...
Aunque esto trae unos ciertos problemas, como que la lectura de los botones no deben ser bloqueantes (quedarse encerrados en un loop).

Si vos logras que tanto leer lso botones, como cambiar el contador no demore demasiado sea si tenes presionado el boton por siempre, entonces no vas a tener problemas. y vas a poder visualizar el 000.

La otra forma que libera de estos problemas es usar las interrupciones de un timer, y que en el timer se maneje el tiempo de cada display.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: paberi90 en 04 de Septiembre de 2019, 22:50:10
Amigo gracias por contestar pero le cuento que me estas hablando en chino  :( pues lo que tengo lo he encontrado en una pagina y otra y pues si te das cuenta en el codigo tengo desactivado el __config pues me salen errores al compilar y no tengo la menor idea de como solucionarlo, te agradezco la ayuda que me puedas dar.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: KILLERJC en 05 de Septiembre de 2019, 07:59:40
Amigo gracias por contestar pero le cuento que me estas hablando en chino  :( pues lo que tengo lo he encontrado en una pagina y otra y pues si te das cuenta en el codigo tengo desactivado el __config pues me salen errores al compilar y no tengo la menor idea de como solucionarlo, te agradezco la ayuda que me puedas dar.

Considero que darte el codigo (debido que hay que cambiar casi todo) no significa ningun aprendizaje. Deberias intentar entender el codigo y una ves que lo entiendas modificarlo.

Yo no tengo ningun problema que me preguntes cuales son tus dudas respecto al codigo, pero no te va a servir nada si yo lo hago. No es para no hacerlo, es para tu propio bien.
Título: Re:Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A
Publicado por: dakarlcts en 18 de Abril de 2022, 08:33:12
Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A



Buenas, se que el tema es muy antiguo pero, ¿podrías actualizar los link de las simulaciones?

Mil gracias!! :-/