Autor Tema: Mis primeros programas en ASM. PIC16F84A y PIC16F628A/648A  (Leído 604264 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Manual PIC16F84A
« Respuesta #15 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:
Diagrama de Flujo:

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
« Última modificación: 20 de Abril de 2009, 17:15:20 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Manual PIC16F84A
« Respuesta #16 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:

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

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

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

Código: 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", "#"
« Última modificación: 20 de Abril de 2009, 17:24:58 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Manual PIC16F84A
« Respuesta #17 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.

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.
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Manual PIC16F84A
« Respuesta #18 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.-
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

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

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Manual PIC16F84A
« Respuesta #20 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.
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:
  • Velocidad 9600 baudios
  • Dato de 8 bits
  • Sin Paridad
  • 1 bit de Stop

Para establecer comunicación con el microcontrolador utilizaremos el software Siow, 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)

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
No contesto mensajes privados, las consultas en el foro

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #21 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.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #22 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!
No contesto mensajes privados, las consultas en el foro

Desconectado Veguepic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2120
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #23 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
“Si la gente es buena sólo porque temen al castigo y porque esperan una recompensa, entonces verdaderamente somos un grupo lastimoso." Albert Einstein.

Saludos desde Lima , Peru    -    Hugo

Desconectado ema

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1078
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #24 en: 01 de Marzo de 2009, 17:37:56 »
Wow :shock: excelente...

Felicitaciones por aportar tanto esfuerzo a la comunidad

Desconectado Chrisbaf

  • PIC16
  • ***
  • Mensajes: 178
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #25 en: 01 de Marzo de 2009, 18:04:04 »
gracias por este excelente tutorial , sigue adelante

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas en ASM. Tutorial PIC16F628A/648A
« Respuesta #26 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
  • Conjunto reducido de instrucciones (RISC). Solamente 35 instrucciones que aprender a utilizar
  • Oscilador interno de 4MHz
  • Opera con una frecuencia de reloj externa de hasta 20 MHz (ciclo de máquina de 200 ns)
  • Memoria de programa: 2048 locaciones de 14 bits
  • Memoria de datos: Memoria RAM de 224 bytes (8 bits por registro)
  • Memoria EEPROM: 128 bytes (8 bits por registro)
  • Stack de 8 niveles
  • 16 Terminales de I/O que soportan corrientes de hasta 25 mA
  • 3 Temporizadores
  • Módulo de comunicación serie (Usart
  • Módulo CCP (captura/comparación/PWM)
  • 2 Comparadores analógicos, una referencia de voltaje programable

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:
  • Memoria de programa: PIC16F648A-4096 locaciones de 14 bits
  • Memoria de datos: PIC16F648A-Memoria RAM de 256 bytes (8 bits por registro)
  • Memoria EEPROM: PIC16F648A-256 bytes (8 bits por registro)


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


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
  • VDD: Pin de alimentación positiva. De 2 a 5,5 Vcc
  • VSS: Pin de alimentación negativa. Se conecta a tierra o a 0 Vcc
  • MCLR: Master Clear (Reset). Si el nivel lógico de este terminal es bajo (0 Vcc), el microcontrolador permanece inactivo. Este Reset se controla mediante la palabra de configuración del PIC
  • OSC1/CLKIN: Entrada de oscilador externo
  • OSC2/CLKOUT: Salida del oscilador. Dependiendo de cómo se configure puede proporcionar una salida de reloj por medio de este pin

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.
 

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.



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:

« Última modificación: 30 de Julio de 2009, 14:52:13 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #27 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.


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
 

« Última modificación: 30 de Julio de 2009, 14:53:57 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #28 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.


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)
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:
« Última modificación: 10 de Julio de 2009, 19:04:27 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6759
Re: Mis primeros programas. Tutorial PIC16F84A
« Respuesta #29 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:

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
  67.  
No contesto mensajes privados, las consultas en el foro


 

anything