uControl
Septiembre 08, 2010, 07:40:20 *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: « 1 2 3   Ir Abajo
  Imprimir  
Autor Tema: Mis primeros programas con PIC16F84A y PIC16F628A  (Leído 24261 veces)
0 Usuarios y 1 Visitante están viendo este tema.
Suky
Administradores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2084


PIC32, voy por ti! >:(


WWW
« Respuesta #30 : Abril 24, 2009, 08:59:22 »

Primero que nada felicitar al trabajo que ha realizado Leon Pic al pasar el tutorial a este foro, que en su momento no pude. Reconocer su esfuerzo en multiplicar las opciones de encontrarlo, para aquellos que se inician en el desarrollo de aplicaciones con PIC en lenguaje asm.  Wink
Y ahora voy agregar el funcionamiento del módulo CCP del PIC16F628A más ejemplos como se ha venido haciendo.
En línea

  Neuquén-Argentina 

InfoPIC
Suky
Administradores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2084


PIC32, voy por ti! >:(


WWW
« Respuesta #31 : Abril 24, 2009, 09:00:43 »

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:
  • Modo captura: Permite capturar el valor que tiene en registro TMR1 cuando ocurre un evento especial en la terminal RB3/CCP1.
  • Modo comparación: Permite comparar el valor de 16 bits del TMR1 con un valor previamente definido en los registros CCPRL1H y CCPR1L
  • Modo PWM: Permite generar señales digitales moduladas en ancho de pulso

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:

  • 0000   Captura/Comparación/PWM deshabilitados
  • 0100   Captura cada transición de bajada
  • 0101   Captura cada transición de subida
  • 0110   Captura cada cuarta transición de subida
  • 0111   Captura cada 16 transiciones de subida
  • 1000   Comparación, pone salida cada coincidencia
  • 1001   Comparación, limpia salida cada coincidencia
  • 1010   Comparación, genera interrupción cada coincidencia (Se setea bit CCP1IF, salida inalterada)
  • 1011   Comparación, dispara evento especial (Se setea bit CCP1IF , resetea TMR1(TMR1IF inalterado) )
  • 11xx   Modo PWM

 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:
  • Cada transición de bajada
  • Cada transición de subida
  • Cada cuarta transición de subida
  • Cada dieciseisava transición de subida
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:


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:
  • Se debe configurar el CCP1 como entrada a través del registro TRISB
  • El Timer1 debe estar en modo temporizador o modo contador sincronizado
  • Al cambiar el modo de captura hay que tener inhabilitadas las interrupciones y borrar el flag para evitar interrupciones espúreas.
  • Si el pin RB3/CCP1 es configurado como salida, se deberá tener en cuenta que una escritura al puerto B puede causar una condición de captura.
En línea

  Neuquén-Argentina 

InfoPIC
Suky
Administradores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2084


PIC32, voy por ti! >:(


WWW
« Respuesta #32 : Abril 24, 2009, 09:02:23 »

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.
Periodo(s)=(4/20MHz).CCPR1
Frecuencia(Hz)=1/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.


Hardware necesario:


Código: (asm)
; **** Encabezado ****
list p=16f628A ; list directive to define processor
#include <p16f628A.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON

;**** Definicion de variables ****
Msb equ 0x20 ; Guarda Byte alto de Captura para enviar por RS232
Lsb equ 0x21 ; Guarda byte bajo de Captura para enviar por RS232
Contador1 equ 0x22 ; Para demora
Contador2 equ 0x23 ; Para demora
;**** Definiciones para el ensamblador ****

;**** Definición de macros ****
; Se envia la data de un registro a PC.-
Putreg macro Registro
movfw Registro
call RS232_EnviaDato
endm

;/////////////////////////////////
;**** Inicio del Micro ****
Reset.
org 0x00 ; Aquí comienza el micro.-
goto Inicio ; Salto a inicio de mi programa.-

; **** Programa Principal ****
org 0x05
Inicio
bsf STATUS,RP0 ; Banco 1
movlw b'00001010' ; RB1 entrada, RB2 salida, RB3 entrada.
movwf TRISB
movlw 0x04
movwf TXSTA ; Configura modo asincrono, baud rate de alta velocidad
movlw 0x81 ; Configura velocidad a 9600 baudios con cristal de 20 Mhz
movwf SPBRG
bsf     TXSTA,TXEN ; Habilita transmision
bcf STATUS,RP0 ; Banco 0.-
bsf RCSTA,SPEN ; Habilitacion puerto serie

movlw b'00000001' ; Se selecciona TMR1, preescaler de 1/1, modo temporizador.-
movwf T1CON
movlw b'00000101' ; Se configura CCP modo captura cada flanco de subida.-
movwf CCP1CON
Bucle
bcf PIR1,CCP1IF ; Borramos bandera
btfss PIR1,CCP1IF ; Testeamos bandera.-
  goto $-1 ; Si no se activo seguimos esperando
bcf PIR1,CCP1IF ; Se activo, la borramos.-
clrf TMR1H ; Borramos Timer1.-
clrf TMR1L ;
btfss PIR1,CCP1IF ; Volvemos a testear bandera.-
goto $-1 ; No se activo, seguimos esperando.-
movfw CCPR1L ; Copiamos el valor capturado.-
movwf Lsb
movfw CCPR1H
movwf Msb
Putreg Msb ; Enviamos lo guardado en el registro Msb.-
Putreg Lsb ; Enviamos lo guardado en el registro Lsb.-
call Demora_30ms
  goto Bucle ;
;..............................................
;**** Rutinas ****
;**** Se envia Dato ****
RS232_EnviaDato
bsf STATUS,RP0 ; Banco 1
btfss   TXSTA,TRMT  ; chequea si esta listo
goto $-1 ; Esperamos  a que se desocupe.-
bcf STATUS,RP0 ; Banco 0
movwf   TXREG ; envia Dato.-
return
;...............................................
; *** 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


* Frecuencia.rar (67.19 KB - descargado 111 veces.)
En línea

  Neuquén-Argentina 

InfoPIC
Suky
Administradores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2084


PIC32, voy por ti! >:(


WWW
« Respuesta #33 : Abril 24, 2009, 09:05:12 »

    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:
    • RB3/CCP1 Se pone en alto
    • RB3/CCP1 Se pone en Bajo
    • RB3/CCP1 no cambia
    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

    Configuraciones:
    • El pin RB3/CCP1 debe configurarse como salida limpiando el bit TRISB<3>
    • El Timer 1 debe estar corriendo en modo temporizador (o en modo contador sincronizado)
    • Al limpiar el registro CCP1CON el latch de salida de la patita RB3/CCP1 se forza a su valor “default” de cero.
    • En el modo “interrupción software” no se realiza ninguna acción en el pin RB3/CCP1.
    • El modo “Special Event Trigger” ocurre inmediatamente al igualarse el par de registros TMR1H, TMR1L al par de registros CCPR1H, CCPR1L. El par de registros TMR1H, TMR1L no se resetean hasta el próximo flanco ascendente del clock de Timer1. Esto permite que el registro CCPR1 sea un registro de periodo programable para el Timer1

    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:

    [/list]
    Código: (asm)
    ; **** Encabezado ****
    list p=16f628A ; list directive to define processor
    #include <p16f628A.inc> ; processor specific variable definitions
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON

    ;**** Definicion de variables ****
    decre equ 0 ; Pulsador para decrementar periodo
    incre equ 1 ; Pulsador para incrementar periodo

    ;/////////////////////////////////
    ;**** Inicio del Micro ****
    Reset.
    org 0x00 ; Aquí comienza el micro.-
    goto Inicio ; Salto a inicio de mi programa.-

    ; **** Programa Principal ****
    org 0x05
    Inicio
    movlw 0x07 ; Para deshabilitar comparadores analogicos.-
    movwf CMCON
    bsf STATUS,RP0 ; Banco 1
    bsf TRISA,decre ; Como entrada.-
    bsf TRISA,incre ; Como entrada.-
    bcf TRISB,3 ; RB3 como Salida.
    bcf STATUS,RP0 ; Banco 0.-
    movlw b'00000001' ; Se selecciona TMR1, preescaler de 1/1, modo temporizador.-
    movwf T1CON
    movlw 0x80 ; Inicia periodo de comparacion a mitad de rango.-
    movwf CCPR1H
    movlw 0x00
    movwf CCPR1L
    movlw b'00001000' ; Se configura CCP modo comparación, setea salida con coincidencia.-
    movwf CCP1CON
    clrf TMR1H ; Comenzamos generacion de señal.-
    clrf TMR1L
    Bucle
    bcf PIR1,CCP1IF ; Borramos bandera
    btfss PIR1,CCP1IF ; Testeamos bandera.
      goto $-1 ; Si no se activo seguimos esperando
    bcf PIR1,CCP1IF ; Se activo, la borramos.
    movlw b'00000001' ; Invertimos ultimo bit, para pasar de setear a resetear...
    xorwf CCP1CON,1 ; o viceversa.-
    clrf TMR1H ; Reseteamos cuenta Timer1.
    clrf TMR1L ;
    btfsc PORTA,decre ; Testea pulsador para decrementar periodo.-
    call Decrementa
    btfsc PORTA,incre ; Testea pulsador para incrementar periodo.-
      call Incrementa
    goto Bucle ;
    ;..............................................
    ;**** Rutinas ****
    Decrementa
    decf CCPR1L,1 ; Decrementa parte baja.-
    comf CCPR1L,w ; Carga el negado a W, si CCPR1L=0xFF -> W=0x00.-
    btfss STATUS,Z ; Si W=0x00 decrementamos parte alta.-
    return ; No.-
    decf CCPR1H,1 ; Decrementa parte alta.-
    return
    ;..............................................
    Incrementa
    incf CCPR1L,1 ; Incrementa parte baja.-
    btfss STATUS,Z ; CCPR1L=0x00?
    return ; No.-
    incf CCPR1H,1 ; Si, incrementa parte alta
    return

    ;...............................................
    end
    « Última modificación: Abril 24, 2009, 09:08:54 por Suky » En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #34 : Abril 24, 2009, 09:10:05 »

    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:


    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:
    • Se borra el TMR2
    • Se pone a “1” el pin CCP1
    • Se pasa el valor del CCPR1L al CCPR1H (para evitar glitch)

    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

    PeriodoPWM=(PR2+ 1).4.Tosc.TMR2 Preescaler

    FrecuenciaPWM=1/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>.

    CTPWM=(CCPR1L:CCP1CON<5:4>).Tosc.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á:

    CTPWM=2^n.Tosc.TMR2 Preescaler

    Sin embargo, dependiendo del valor de Ciclo de trabajo máximo (CT_PWM) deseado, no será posible realizar las [latex]2^{n}[/latex] 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:

    ResolucionPWM=log(CTPWM/Tosc.TMR2 Preescaler)/ 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).


    Secuencia de configuración del PWM
    A continuación se resumen los pasos para realizar la configuración inicial del PWM:
    • Establecer el periodo del PWM escribiendo al registro PR2.
    • Establecer el Ciclo de Trabajo del PWM escribiendo al registro CCPR1L y a los bits CCP1CON<5:4>.
    • Configurar como salida el pin CCP1, limpiando el bit TRISB<3>.
    • Configurar el preescalador del Timer 2 y habilitar el Timer 2, escribiendo al registro T2CON.
    • Configurar el módulo CCP1 para operación PWM. Poniendo en alto los bits CCP1CON <2:3>.
    En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #35 : Abril 24, 2009, 09:14:31 »

    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:

    Código: (asm)
    ; **** Encabezado ****
    list p=16f628A ; list directive to define processor
    #include <p16f628A.inc> ; processor specific variable definitions
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON

    ;**** Definicion de variables ****
    Flags equ 0x20 ; Registro para guardar banderas.-

    Selec equ 0 ; Bit para indicar seleccion(Selec=1->500Hz; Selec=0->2kHz).-
    ;**** Definiciones para el ensamblador ****
    #define Signal Flags,Selec


    ;/////////////////////////////////
    ;**** Inicio del Micro ****
    Reset.
    org 0x00 ; Aquí comienza el micro.-
    goto Inicio ; Salto a inicio de mi programa.-

    ; **** Programa Principal ****
    org 0x05
    Inicio
    bsf STATUS,RP0 ; Banco 1
    bsf TRISB,0 ; Como Entrada.-
    bcf TRISB,3 ; RB3 como Salida.
    bcf STATUS,RP0 ; Banco 0.-
    movlw b'00000110' ; Se selecciona TMR2, preescaler de 1/16.-
    movwf T2CON
    bsf STATUS,RP0 ; Banco 1
    movlw 0x7C ; Inicia periodo de 500Hz.-
    movwf PR2
    bcf STATUS,RP0 ; Banco 0.-
    bsf Signal
    movlw 0x3E ; Ciclo de trabajo 50%
    movwf CCPR1L
    bsf CCP1CON,CCP1X
    bcf CCP1CON,CCP1Y
    bsf CCP1CON,CCP1M3 ; Configura modulo CCP modo PWM.-
    bsf CCP1CON,CCP1M2
    Bucle
    btfss PORTB,0 ; Testea si se quiere cambiar de Frecuencia.-
    goto $-1 ; No se quiere cambiar.-
    btfss Signal ; A cual cambiar?
    goto Cambiar500Hz
    Cambiar2kHz
    bsf STATUS,RP0 ; Banco 1
    movlw 0x1E
    movwf PR2
    bcf STATUS,RP0 ; Banco 0
    bcf Signal ; Señal de 2kHz
    movlw 0x0F ; Ciclo de trabajo 50%
    movwf CCPR1L
    goto Bucle ;

    Cambiar500Hz
    bsf STATUS,RP0 ; Banco 1
    movlw 0x7C ; Inicia periodo de 500Hz.-
    movwf PR2 ; Señal de 500 Hz.-
    bcf STATUS,RP0 ; Banco 0.-
    bsf Signal
    movlw 0x3E ; Ciclo de trabajo 50%
    movwf CCPR1L
    goto Bucle
    ;...............................................
    end
    En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #36 : Abril 24, 2009, 09:21:45 »

    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:


    Código: (asm)
    ; **** Encabezado ****
    list p=16f628A ; list directive to define processor
    #include <p16f628A.inc> ; processor specific variable definitions
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON

    ;**** Definicion de variables ****
    Contador1 equ 0x20 ;
    Contador2 equ 0x21 ;

    decre equ 0 ; Pulsador para decrementar Ciclo de Trabajo
    incre equ 1 ; Pulsador para incrementar Ciclo de Trabajo


    ;/////////////////////////////////
    ;**** Inicio del Micro ****
    Reset.
    org 0x00 ; Aquí comienza el micro.-
    goto Inicio ; Salto a inicio de mi programa.-

    ; **** Programa Principal ****
    org 0x05
    Inicio
    bsf STATUS,RP0 ; Banco 1
    bsf TRISB,incre ; Como Entrada.-
    bsf TRISB,decre ; Como Entrada.-
    bcf TRISB,3 ; RB3 como Salida.
    bcf STATUS,RP0 ; Banco 0.-
    movlw b'00000110' ; Se selecciona TMR2, preescaler de 1/16.-
    movwf T2CON
    bsf STATUS,RP0 ; Banco 1
    movlw 0x1E ; Señal de 2kHz
    movwf PR2
    bcf STATUS,RP0 ; Banco 0
    clrf CCPR1L ; Ciclo de trabajo 0%
    bcf CCP1CON,CCP1X
    bcf CCP1CON,CCP1Y
    bsf CCP1CON,CCP1M3 ; Configura modulo CCP modo PWM.-
    bsf CCP1CON,CCP1M2
    Bucle
    btfsc PORTB,decre ; Testea si se quiere reducir CT.-
    goto Decrementa
    btfsc PORTB,incre ; Testea si se quiere aumentar CT.-
    goto Incrementa
    goto Bucle
    Incrementa
    incf CCPR1L,1
    call Demora_50ms
    goto Bucle
    Decrementa
    decf CCPR1L,1
    call Demora_50ms
    goto Bucle


    ;**** Demora ****
    Demora_50ms
    movlw 0xFF ;
    movwf Contador1 ; Iniciamos contador1.-
    Repeticion1
    movlw 0x40 ;
    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
    En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #37 : Abril 24, 2009, 09:24:48 »

    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)

    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:


    Código: (asm)
    ; **** Encabezado ****
    list p=16F84A
    #include P16F84A.inc
    __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
    ;**** Definicion de variables ****
    Display1 equ 0x0C ; Valor que luego de convertido se enviara al Display 1
    Display2 equ 0x0D ; Valor que luego de convertido se enviara al Display 2
    Display3 equ 0x0E ; Valor que luego de convertido se enviara al Display 3
    DataEnviar equ 0x0F ; Dato convertido a codigo 7 Segmentos a enviar
    ContBits equ 0x10 ; Para controlar el envio de bits

    Desc equ 0 ; Definimos Pulsador descendente.-
    Asc equ 1 ; Definimos Pulsador ascendente.-
    BClock equ 0 ; Pin reloj del 74LS164
    BData equ 1 ; Pin data del 74LS164
    BReset equ 2 ; Pin Reset del 74LS164
    Pto equ 0 ; Bit punto, Con este indicamos si se muestra punto.-

    Resett org 0x00 ; Aquí comienza el micro.-
    goto Inicio ; Salto a inicio de mi programa.-

    ;**** Tabla de conversion BCD a 7 Segmentos ****
    ; Se coloca al inicio para asegurar ubicacion en Pagina.-
    org 0x05 ; Origen del código de tabla.-
    BCD7SEG: ; retlw b'abcdefg0'  para display catodo comun
    addwf PCL,1 ; Se incrementa el contador del programa.-
    DT 0xFC , 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6

    ;**** Programa principal ****
    ;**** Configuracion de puertos ****
    Inicio bsf STATUS,RP0 ; Pasamos de Banco 0 a Banco 1.-
    movlw b'11111000' ; RB7 como entrada y los demas como salida.-
    movwf TRISB
    bcf STATUS,RP0 ; Paso del Banco 1 al Banco 0
    clrf Display1
    clrf Display2
    clrf Display3
    bsf PORTB,BReset ; Habilitamos 74LS164.-
    bcf PORTB,BData
    bsf PORTB,BClock ; Seteamos Clock.-

    goto ActualizoDisplays

    ;**** Testeo de Pulsador ****
    Testeo
    btfss PORTA,Desc ; Testeamos si esta a 1 logico.-
    goto Descender ; No
    btfss PORTA,Asc ; Testeamos si esta a 1 logico.-
    goto Ascender
    goto Testeo ; Si, Testeamos nuevamente.-



    ;**** Rutinas ****
    Descender
    btfss PORTA,Desc ;
    goto $-1 ; Esperamos hasta que se suelte.-
    decf Display1,1 ; Decremento Display1.
    movlw d'255' ; Si paso de 0 a 255...
    subwf Display1,0 ; decremento Display2
    btfss STATUS,Z ;
    goto ActualizoDisplays ; no es 255
    movlw d'9'
    movwf Display1 ; Si, cargo 9.-
    decf Display2,1 ; Decremento Display2.-
    movlw d'255' ; Si paso de 0 a 255...
    subwf Display2,0 ; decremento display3
    btfss STATUS,Z ;
    goto ActualizoDisplays ; No es 10.-
    movlw d'9'
    movwf Display2 ; Si, cargo 9.-
    decf Display3,1 ; Decremento Display3.-
    movlw d'255' ; Si paso de 0 a 255...
    subwf Display3,0
    btfss STATUS,Z
    goto ActualizoDisplays ; No es 10.-
    movlw d'9'
    movwf Display3 ; Si, cargo 9.-
    goto ActualizoDisplays
    ;.........................................................
    Ascender
    btfss PORTA,Asc ;
    goto $-1 ; Esperamos hasta que se suelte.-
    incf Display1,1 ; Incremeto Display1.
    movlw d'10' ; Si es 10 reseteo e incremento Display2
    subwf Display1,0 ;
    btfss STATUS,Z ;
    goto ActualizoDisplays ; no es 10
    clrf Display1 ; Si, reseteo.-
    incf Display2,1 ; Incremento Display2.-
    movlw d'10' ; Si Decena = 10, reseteo e incremento Display3
    subwf Display2,0 ;
    btfss STATUS,Z ;
    goto ActualizoDisplays ; No es 10.-
    clrf Display2 ; Si, reseteo.-
    incf Display3,1 ; Incremento Display3.-
    movlw d'10' ; Si es 10 Reseteo.-
    subwf Display3,0
    btfss STATUS,Z
    goto ActualizoDisplays ; No es 10.-
    clrf Display3 ; Si, reseto
    goto ActualizoDisplays
    ;...................................................
    ActualizoDisplays
    movfw Display1
    call BCD7SEG ; Convertimos BCD a codigo 7 Segmentos.-
    movwf DataEnviar ; Cargamos dato a enviar devuelto x BCD7SEG.-
    call EnviaDato
    movfw Display2
    call BCD7SEG ; Convertimos BCD a codigo 7 Segmentos.-
    movwf DataEnviar ; Cargamos dato a enviar devuelto x BCD7SEG.-
    bsf DataEnviar,Pto ; A ejemplo cargamos punto a enviar.-
    call EnviaDato
    movfw Display3
    call BCD7SEG ; Convertimos BCD a codigo 7 Segmentos.-
    movwf DataEnviar ; Cargamos dato a enviar devuelto x BCD7SEG.-
    call EnviaDato
    goto Testeo
    ;**** Se envia Dato a los registros de desplazamiento ****
    ;-----------------------------------------------------------------------------------------
    ; 1º se envia el LSB, luego se va rotando a la derecha y se envian los bits de mayor peso.-
    ;-----------------------------------------------------------------------------------------
    EnviaDato
    movlw d'8' ; Número de bits a transmitir.
    movwf ContBits
    EnviaBit ; Comienza a enviar datos.
    btfss DataEnviar,0 ; ¿Es un "1" el bit a transmitir?
    bcf PORTB,BData ; No, pues envía un "0".
    btfsc DataEnviar,0 ; ¿Es un "1" el bit a transmitir?
    bsf PORTB,BData ; Si, Transmite un "1".
    bcf PORTB,BClock ; Clock=0.-
    nop
    bsf PORTB,BClock ; Clock=1.-
    rrf DataEnviar,1 ; Rota para envia siguiente bit.-
    decfsz ContBits,1 ; Comprueba si es el último bit.
    goto EnviaBit ; No es el último bit repite la operación.
    return ; Retornamos.-
    ;.................................................................................
    end

    « Última modificación: Mayo 20, 2009, 01:12:58 por Suky » En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #38 : Mayo 20, 2009, 01:13:17 »

    Bueno, ahora que ya se ha terminado la explicación de los módulos del micro, les dejo un programita que realice para facilitar las configuraciones.
    Es una interface gráfica donde se puede establecer las configuraciones del microcontrolador y luego generar el código en asm para ser agregado en el proyecto de Mplab. En este hilo se hace la presentación del mismo.  Wink

    Saludos!!!
    En línea

      Neuquén-Argentina 

    InfoPIC
    Suky
    Administradores
    PIC24F
    *****
    Desconectado Desconectado

    Sexo: Masculino
    Mensajes: 2084


    PIC32, voy por ti! >:(


    WWW
    « Respuesta #39 : Octubre 26, 2009, 05:48:14 »

    Cartel de Leds en ASM.
    Aquí voy a mostrar una forma sencilla de hacer un cartel de leds en asm que tendrá algunas limitaciones, pero entendiendo como es el funcionamiento y el esfuerzo de ustedes podrán romper esas barreras!  Grin
    Para mostrar un ejemplo sencillo vamos a usar una tabla para guardar el mensaje a mostrar y una sola variable (8 bits) para indicar el largo y control de la posición a enviar. Por ello el largo del mensaje estará restringido a 255 bytes que se reducen en 6 por la posición de la tabla en la memoria de programa.-
    La forma de guardar cada letra del mensaje será la siguiente:

    Cada byte indica una columna de la letra, donde un 0 es led apagado y 1 led encendido.
    Nota: Es una forma de hacerlo, la cual la aprendí del amigo BrunoF en uno de sus tantos aportes  bang

    Luego el mensaje puede ser mayor al cartel utilizado para mostrarlo así que es necesario efectuar un desplazamiento del mensaje sobre el cartel o lo que es lo mismo desplazar el cartel sobre el mensaje.
    Para ello se utilizará una variable que indica la posición inicial dentro del mensaje, en la cual comienza a mostrarse en el cartel. Como deseamos que el mensaje sea rotativo el problema se presenta en las últimas posiciones donde se debe mostrar la parte final del mensaje y empezar a mostrar el inicio Tongue Lo que hacemos es dividir en 2 la forma de mostrar el mensaje, cuando Posición Inicial + Largo del Cartel sea menor a Largo del mensaje y cuando sea mayor:


    Bueno, más o menos se ha explicado como vamos a trabajar con el mensaje, ahora se debe entender como va a funcionar el multiplexo de los leds. Vamos a realizar la multiplexación por filas, ósea que vamos a seleccionar una fila y vamos a actualizar sus valores por medio de registros de desplazamientos. El tiempo de actualización no debe superar los 20ms!
    Para actualizar usaremos una variable que indique que fila ha de actualizarse, por ejemplo para actualizar la fila uno la variable FilaActual será 00000001. Ahora para saber que valores tenemos que mandar a los registros de desplazamiento iremos tomando cada una de las columnas (PosicionEnviar) a actualizar, aremos un AND con FilaActual y determinaremos si enviar un 1 o un 0.-
    ( PosicionEnviar (AND) FilaActual ) = FilaActual?
          Si -> Enviamos un 1
          No-> Enviamos un 0


    Hardware para simulación:



    Código:
    ; CARTEL DE LEDS. de 32x8.
    ; Si las letras son de 8x8, maxima cantidad de letras en el mensaje 31.-

    ; **** Encabezado ****
     list p=16F628A   ; Microcontrolador utilizado.-
     #include P16F628A.inc    ; Definicion de registros SFR.-
     __CONFIG   _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF
    ;**** Definicion de Variables ****
    CBLOCK 0x20       ; En esta posicion se declaran los registros de usuario (GPR)
    STATUS_Temp   ; Registro para guardar temporalmete STATUS
    W_Temp   ; Registro para guardar temporalmete W
    Banderas ; Registro para almacenar banderas.-
    FilaActual ; Fila Actual a refrescar.-
    PosicionInicial ; Posicion inicial dentro del mensaje a visualizar en el cartel.- (Entre 0 y LargoMsj-1)
    PosicionEnviar ; Posicion del registro a enviar.-
    CuentaRefrescos ; Cuenta la cantidad de refrescos realizados.
    LargoCartel ; Guarda largo del cartel.- 32
    LargoMsj ; largo del mesaje a visualizar-> Max 249 Bytes.-Para aumentar modificar manejo de tabla.-
    TempH ; Temporal para guardar calculos matemáticos.-
    TempL ; Temporal...
    VelMovimiento ; Para fijar velocidad de movimiento.-
    ENDC
    Velocidad equ d'4' ; Para fijar velocidad de desplazamiento.-
    kbhit_tiempo equ 0 ; Bandera que indica que han pasado 2ms.-
    kbhit_cuadro equ 1
    BData equ 0
    BClock equ 1
    Strobe equ 2

    ;**** Inicio del Microcontrolador ****
    Reset
         org    0x00
         goto Inicio ; Salto a inicio del programa.-
    ;**** Vector de Interrupcion ****
         org    0x04
         goto    Inicio_ISR ; Atiendo Interrupcion.-
    ;**** Mensaje a Mostrar *****
    org 0x05
    Mensaje
    addwf PCL,1 ; Se incrementa el contador del programa.-
    DT 0x38, 0x7C, 0xFE, 0x82, 0x82, 0x82, 0x44, 0x00 ; C
    DT 0x60, 0xF4, 0x94, 0x94, 0xFC, 0xF8, 0x00, 0x00 ; a
    DT 0xFC, 0xFC, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00 ; r
    DT 0x04, 0xFE, 0xFE, 0x84, 0x40, 0x00, 0x00, 0x00 ; t
    DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e
    DT 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; l
    DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio
    DT 0x78, 0xFC, 0x84, 0x48, 0xFE, 0xFE, 0x00, 0x00 ; d
    DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e
    DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio
    DT 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; l
    DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e
    DT 0x78, 0xFC, 0x84, 0x48, 0xFE, 0xFE, 0x00, 0x00 ; d
    DT 0x88, 0x9C, 0x94, 0xF4, 0x64, 0x00, 0x00, 0x00 ; s
    DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio
    DT 0x8C, 0x9E, 0xFE, 0xFA, 0x62, 0x00, 0x00, 0x00 ; S
    DT 0x7C, 0xFC, 0x80, 0x80, 0xFC, 0xFC, 0x00, 0x00 ; u
    DT 0xFE, 0xFE, 0x10, 0x38, 0x64, 0xC4, 0x80, 0x00 ; k
    DT 0x04, 0x8C, 0xB8, 0x70, 0x30, 0x08, 0x04, 0x00 ; y
    DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio
    DT 0x82, 0xC1, 0xA1, 0x91, 0xCE, 0x00, 0x00, 0x00 ; 2
    DT 0x80, 0x86, 0x85, 0x89, 0x71, 0x00, 0x00, 0x00 ; 5
    DT 0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ; /
    DT 0x81, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 ; 1
    DT 0x7E, 0x81, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00 ; 0
    DT 0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ; /
    DT 0x7E, 0x81, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00 ; 0
    DT 0x8E, 0x91, 0x51, 0x71, 0x1E, 0x00, 0x00, 0x00 ; 9
    DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio
    ;**** Programa principal ****
    Inicio
    ;---- Configuraciones ----
         bsf     STATUS,RP0  ; Banco 1.-
         movlw   0xF8
         movwf   TRISA   ;eeeeesss
         movlw   0x00
         movwf   TRISB   ;ssssssss
         movlw   0xDF
         movwf   OPTION_REG  ; Pull-Up deshabiltado, , Timer0|interno, 1:1
         bcf     STATUS,RP0  ; Banco 0.-
         movlw   0x07    ; Configuro Comparador Analogico
         movwf   CMCON   ; V1in-=GND, V1in+=GND, C1out=Off| V2in-=GND, V2in+=GND, C2out=Off
    clrf PORTA
    clrf PORTB
         movlw   0x4D
         movwf   T2CON   ; Timer2: Pre=1:4, Post=1:10

    movlw Velocidad ; Cargamos velocidad de desplazamiento.-
    movwf VelMovimiento
    movlw d'32' ; Cargamos largo del cartel.-
    movwf LargoCartel
    movlw d'232' ; Cargamos largo del mensaje.-
    movwf LargoMsj
    clrf PosicionInicial
    clrf Banderas
    movlw 0x01
    movwf FilaActual
    movlw 0x08
    movwf CuentaRefrescos

         clrf    PIR1    ; Limpiamos Banderas
         bsf     STATUS,RP0  ; Banco 1.-
         bsf     PIE1,TMR2IE ; Habilitamos interrupcion por Timer2
         bcf     STATUS,RP0  ; Banco 0.-
         bsf     INTCON,GIE  ; Habilitacion general de interrupciones
         bsf     INTCON,PEIE ; Habilitacion de interrupciones Perifericas

    Bucle
    btfss Banderas,kbhit_tiempo ; Se espera a que pasen 2 ms.-
    goto $-1
    bcf Banderas,kbhit_tiempo
    call ActualizarCartel ; Se actuliza fila del cartel.-
    goto Bucle


    ;**************************************************************************
    ;**** Rutina de servicio de Interrupcion ****
    Inicio_ISR
    ;---- Guardado de registro W y STATUS ----
         movwf   W_Temp  ; Copiamos W a un registro Temporario
         swapf   STATUS,W    ; Invertimos nibles de STATUS
         movwf   STATUS_Temp ; Guardamos STATUS en un registro temporal
    ;---- Interrupciones ----
         btfsc   PIR1,TMR2IF ; Interrupcion por Timer2?
         goto    ISR_TIMER2  ; Si, se trata interrupcion
    ;.............................
    Fin_ISR
    ;---- Restauramos los valores de W y STATUS ----
         swapf   STATUS_Temp,W
         movwf   STATUS
         swapf   W_Temp,f
         swapf   W_Temp,W
         retfie
    ;.......................
    ISR_TIMER2
    ; Tratamiento de Interrupcion
    decfsz CuentaRefrescos,1 ; Se refrescaron las 8 filas (Momento adecuado para realizar algun cambio.-)
    goto SetBandera ; No, seguimos..
    decfsz VelMovimiento,1 ; Si, ya pasaron 16ms x VelMovimiento?
    goto RecargarData ; No, seguimos...
    movlw Velocidad ; Recargamos Velocidad
    movwf VelMovimiento
    incf PosicionInicial ; Si, incrementamos PosicionInicial para efectuar "movimiento"
    movfw LargoMsj ; Verificamos si ya se llego al final del Mensaje.-
    subwf PosicionInicial,0
    btfss STATUS,Z
    goto RecargarData ; No, seguimos..
    clrf PosicionInicial ; Si, reseteamos PosicionInicial.-
    RecargarData
    movlw 0x01
    movwf FilaActual
         movlw 0x08
    movwf CuentaRefrescos
    SetBandera
    bsf Banderas,kbhit_tiempo ; Indicamos que han pasado 2 ms, y es necesario actualizar.-
         bcf     PIR1,TMR2IF ; Borramos bandera
         goto    Fin_ISR
    ;.......................
    ;*************************************************************************
    ActualizarCartel
    ; Es (PosicionInicial + LargoCartel <= LargoMsj)?
    clrf TempH ; Borramos Byte alto de variable de 16bits temporal.-
    bcf STATUS,C ; Aseguramos que el carry sea 0 :P
    movfw PosicionInicial ; Sumamos PosicionInicial + largoCartel.-
    addwf LargoCartel,0 ; Y lo guardamos en W.-
    movwf TempL ; Cargamos el resultado bajo en variable temporal.-
    btfsc STATUS,C ; y si hay carry incrementamos registro alto del resultado temporal.-
    incf TempH ; (Esto se da porque el resultado es mayor a 255)

    btfsc TempH,0 ; Es mayor a 255?
    goto $+4 ; (Solo lo hacemos así porque LargoMsj debe ser menor o igual a 255)
    movfw TempL ; No es mayor a 255, verficamos Byte bajo.-
    subwf LargoMsj,0
    btfss STATUS,C
    goto DividoEnDosPartes ; Es mayor...
    ;****************************************************************************
    ; Es menor...
    ; Hay que de la posicion actual sumar el largo de leds y despues comenzar a actualizar el cartel.-
    movfw TempL ; Cargamos posicion de donde comenzar a cargar mensaje.-
    movwf PosicionEnviar

    CicloEnvio
    call EnviaBit ; Se envia bits actual del byte seleccionado.-
    decf PosicionEnviar,1 ; Se decrementa direccionador del byte a enviar.-
    movfw PosicionInicial ; Es igual a la posicion inicial de donde se comienza a visualizar mensaje??
    subwf PosicionEnviar,0
    btfss STATUS,Z ;
    goto CicloEnvio ; No, seguimos con el siguiente byte.-
    goto Efectivizamos ; Ahora se habilitará Strobe para efectivizar los cambios y activaremos la Fila correspondiente.-
    ;******************************************************************************
    ; Es mayor...
    DividoEnDosPartes
    ;(LargoMsj - PosicionInicial):
    movfw PosicionInicial
    subwf LargoMsj,0
    movwf TempL ; Guardamos resultado de la resta en registro temporal.-
    ;[LargoCartel - (LargoMsj - PosicionInicial)]:
    movfw TempL
    subwf LargoCartel,0
    movwf PosicionEnviar ; Guardamos desde donde comenzamos a enviar disminuyendo hasta 1...
    CicloEnvio_1
    call EnviaBit ; Se envia bits actual del byte seleccionado.-
    decf PosicionEnviar,1 ; Se decrementa direccionador del byte a enviar.-
    movlw 0x00
    subwf PosicionEnviar,0 ; Es igual a 0x00??
    btfss STATUS,Z
    goto CicloEnvio_1
    ; Enviamos Segunda parte.-
    movfw LargoMsj
    movwf PosicionEnviar
    CicloEnvio_2
    call EnviaBit ; Se envia bits actual del byte seleccionado.-
    decf PosicionEnviar,1 ; Se decrementa direccionador del byte a enviar.-
    movfw PosicionInicial ; Es igual a la posicion inicial de donde se comienza a visualizar mensaje??
    subwf PosicionEnviar,0
    btfss STATUS,Z
    goto CicloEnvio_2 ; No, seguimos con el siguiente byte.-
    goto Efectivizamos ; Ahora se habilitará Strobe para efectivizar los cambios y activaremos la Fila correspondiente.-
    ;************************************************************************************
    EnviaBit
    decf PosicionEnviar,0 ; Cargamos posicion en W del byte a visualizar.-
    call Mensaje ; Cargamos en W el byte actual a refrescar.-
    andwf FilaActual,0 ; Hacemos ByteActual (AND) FilaActual para determinar el bit a enviar.-
    subwf FilaActual,0 ; [ByteActual(AND)FilaActual] - FilaActual, si esto es cero el bit a enviar es 1, sino 0.-
    bcf PORTA,BData ; Primero cargamos un 0.-
    btfsc STATUS,Z ; La operacion anterior es 0?
    bsf PORTA,BData ; Si, cargamos un 1 en el bit
    bsf PORTA,BClock ; Generamos clock.-
    nop ; demora
    bcf PORTA,BClock ;..
    return
    ;..........................................................
    Efectivizamos
    movlw 0xFF ; Descactivamos todas las filas.-
    movwf PORTB
    bsf PORTA,Strobe ; Efectivizamos los datos en los registros de desplazamiento.-
    nop
    bcf PORTA,Strobe
    comf FilaActual,0 ; Complementamos FilaActual para activar Fila actual a refrescar.-
    movwf PORTB
    bcf STATUS,C ;
    rlf FilaActual,1 ; Rotamos Fila actual para proxima actualizacion.-
    return

        end


    Un Video de muestra:
    <a href="http://www.youtube.com/v/K4abh9f0muM" target="_blank">http://www.youtube.com/v/K4abh9f0muM</a>

    Consideraciones para construcción real:

    Para la construcción real se debe agregar la parte de “potencia” dado que el PIC y según el registro de desplazamiento que se utilice no son capaces de manejar las corrientes necesarias, para ello se colocan transistores para el control de las filas y se agrega el ULN2803/2003 en serie a los registros de desplazamiento, una forma de hacerlo sería la siguiente:



    Y cambiar rutina de efectivizar a :
    Código:
    Efectivizamos
    clrf   PORTB ; Desactivamos todas las filas.-
    bsf PORTA,Strobe ; Efectivizamos los datos en los registros de desplazamiento.-
    nop
    bcf PORTA,Strobe
    movfw FilaActual ;Refrescamos fila actual.-
    movwf PORTB
    bcf STATUS,C ;
    rlf FilaActual,1 ; Rotamos Fila actual para proxima actualizacion.-
    return

    Otra forma:


    Pero deben tener en cuenta que para encender un led se debe enviar al registro de desplazamiento un cero!
    « Última modificación: Septiembre 01, 2010, 01:19:14 por Suky » En línea

      Neuquén-Argentina 

    InfoPIC
    Páginas: « 1 2 3   Ir Arriba
      Imprimir  
     
    Ir a:  

    Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.9 | SMF © 2006-2009, Simple Machines LLC XHTML 1.0 válido! CSS válido!

    Página creada en 0.383 segundos con 24 consultas. (Pretty URLs adds 0.018s, 2q)