Controlar Impresora puerto Paralelo Con PIC

Hola.
Estoy tratando de conectar una Impresora termica POS . de puerto paralelo. con Un pic 16F877.

Bueno les cuento.

He probado con una impresora LX 300, le envio unos Comandos ESC /POS, y me los recibe perfectamente, Me imprime lo quiero.

Pero el mismo programa y circuito lo pruebo con una impresora termica POS ( China).

Y no me imprime correctamente.

Si le envio a imprimir todos los caracteres del abecedario, En la Epson los imprime Correctamente, En la Termica, no imprime la K, la W, simplemente repite el caracter anterior.

SI envio ABCDEFGHIJKLMNOPQRSTUVWXYZ

LA EPSON Los imprime Correcto.

La Termica Imprime

ABCDEFFHIJJLLLPQR TTTTT


Por ejemplo el Comando de aumentar de tamano de caracter

[Name] Set double width print for all characters
[Format] ASCII ESC SO
Hex 1BH OEH
Decimal 27 14
[Description] Characters after this command in the same line will be printed double width.
This command can be canceled by enter or ESC DC4 command.

En la Epson si me duplica el tamano del caracter que le envio, Pero en la termica NO.

Y aparentemente son los Mismos Comandos.

Pueden ayudarme por favor.

Gracias



Hola de nuevo Yo.

Disculpen, en el POST anterior olvide decir que solamente conozco el Lenguaje ASSEMBLER.

Cualquier ayuda que me puedan brindar la agradecere enormente

Cesar
 
Última edición:
no manejo ensamblador pero cuando algo de eso pasa puede ser el tiempo en el que envias cada comando
puede ser que si lo haces mas lento puede digerirlo mejor o necesita que los comando sean mas rapidos
mas que nada probar la velocidad con la que envias los comandos
 
Gracias por la rapida respuesta TRILO-BYTE.

Si ya he probado con diferentes Tiempos , Desde NOP, hasta 1oo. y 200 microsegundos , pero No no me Funciona.
Lo simpatico del asunto es que con la LX 300 hace las impresiones Perfectas, recibe todos los comandos.

Bueno seguitre tirandome los pelos hasta que la haga funcionar.
Gracias de nuevo
 
nimodo asi son estas cosas de baja documentacion
lo ideal seria ver como la computadora manda la trama de datos a la impresora termica y tratar de imitar esa trama

asi le hago cuando las cosas no me salen trato de ver como el dispositivo X manda la trama o la recibe
 
asi es unos pueden poseer comandos estandar pero otras impresoras pueden tener comandos propios que hacen cosas muy particulares

un ejemplo son las LCD 16x2 casi todas son igual pero no todas

es cuestion de perseverar y se encuentran las fallas
 
DE nuevo Gracias TRilo-BYTE.

Bueno despues de despelucarme un monton, Me di cuenta que no habia conectado Correctamente el PIN de BUSY.
Luego de Conectarlo, ahora si me imprime.
Aun debo entender el manejo de los comandos ESC.
Estoy haciendo un turnero, quiero que cuando el cliente llegue al establecimiento. Pulse un switch y la impresora le entregue su numero de turno.
Ya casi lo logro.
Tan pronto lo termine y lo pruebe.lo colocare en este Post. ( en asembler) tal vez a alguien le pueda ayudar.
Hasta pronto

Gracias

cesar
 
mas que nada se agradeceria no el codigo como tal si no el algoritmo
asi es mas facil de digerir y traducir en : BASIC ,C , C++ ,Arduino ,etc.
ya que muchos en el foro no usamos los mismos lenguajes
 
DE Acuerdo.
Ahora estoy algo Ocupado ( trabajo en un Hospital ) tuve que trabajar sabado y Domingo.
Por lo tanto tan pronto tenga un descanzo posteare de nuevo. acerca de imprimir con PIC e Impresora termica.
Hasta pronto
 
Bueno, después de un duro día de trabajo, saqué un tiempo y ¡lo logré!

Logré imprimir lo que quiero con mi térmica de 58 milímetros (papel)

Es el complemento a un turnero que estoy desarrollando para un cliente.

Para más comodidad del usuario, éste solo pulsará un botón y la maquina le entregará su correspondiente turno.

Me jalé un montón los pelos, pero por fin logré entender el funcionamiento de la maquina y aprendí a interpretar los comandos ESC.

Dejo mi programa (ensamblador) ya que creo puede servir de ayuda a otras personas, puesto que para este proyectito, estuve buscando información en internet y la verdad no logré mucha.

Ojalá sirva de base a otras personas.

;; Puesto que es en ensamblador, es un poco largo el código, pero creo que es fácil de entender.
Código:
;**************************************************************
;    **************************8        A_PRINTER_5.ASM


;;;;;;;                        HAY QUE CONECTAR LAS TRS LINEAS DE (  ACK PORTD,6.... BUSY  PORTD,5    ERROR  )
;;;;;;;                        DE LO CONTRARIO NO FUNCIONA

;;;;;;                       Esta es la Forma de la impresion del Ticket
;;;;;;                        
;;;;;;                            ******************        Asteriscos
;;;;;;                        2 INTERLINEAS
;;;;;                         RESIDENCE & NATIONALITY
;;;;;;                        1 INTERLINEA
;;;;;;                            0  1                       NUMERO GRANDE
;;;;;;                        1 Espacio
;;;;;;                           YOUR TURN            MISMO TAMANO DEL NUMERO
;;;;;;                           1 ESPACIO
;;;;;;                                    
;;;;;                        ******************        Asteriscos
;;;;;                           2 ESPACIOS
                
;***************************************************************************************
;;AUTOR:  Cesar Alvarez

;; PARA MICRO IMPRESORA TERMICA 
; PAPEL 58 MILIMETROS
; PUERTO PARALELO
;
;***********************************
;;;;;;;;    CONECTOR PUERTO PARALELO

;Signal Name    Register Bit    DB-25 Pin    I/O Direction
;                   PIN Numero

;Strobe        ¬C0    1    Output
;Data Bit 0    D0    2    Output
;Data Bit 1    D1    3    Output
;Data Bit 2    D2    4    Output
;Data Bit 3    D3    5    Output
;Data Bit 4    D4    6    Output
;Data Bit 5    D5    7    Output
;Data Bit 6    D6    8    Output
;Data Bit 7    D7    9    Output
;Acknowledge    S6    10    Input
;Busy    ¬S7    11    Input
;Paper End    S5    12    Input
;Select In    S4    13    Input
;Auto Feed    ¬C1    14    Output
;Error    S3    15    Input
;Initialize    C2    16    Output
;Select    ¬C3    17    Output
;Ground    -    18-25    -

;*************************************

;**************************************

        LIST    P=16F877A    
  include<p16f877A.inc>


    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF; & _MCLRE_ON 

    CBLOCK  0x20
    UNIDADES
    DECENAS
    CONTADOR
    CONTADOR_2
    REPETIR
    DATOS
    ENDC
;******************************
#DEFINE        STROBE        PORTD,7
#DEFINE        PULSADOR    PORTC,7

    ORG    0x00
    GOTO    Inicio
;*****************************
Inicio
    CLRf    PORTA
    CLRF    PORTB
    CLRF    PORTC
    CLRF    PORTD
    CLRF    PORTE
    BSF        STATUS,RP0
    CLRF    TRISB
    BSF        TRISC,7
    CLRF    TRISE
    MOVLW    B'01100100'
    MOVWF    TRISD
    MOVLW    0x06
    MOVWF    ADCON1
    BCF        STATUS,RP0
    MOVLW    0x06
    MOVWF    ADCON1
    MOVLW    .0
    MOVWF    CONTADOR
    CLRF    CONTADOR_2
    MOVLW    .12
    MOVWF    REPETIR
    CLRF    UNIDADES
    CLRF    DECENAS

    MOVLW    H'1B'            ;Reinicia Printer
    CALL    ENVIA
    MOVLW    H'40'            ;Reinicia Printer
    CALL    ENVIA
    MOVLW    H'0A'            ;INTERLINEA
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'            ;INTERLINEA
    CALl    ENVIA

    GOTO    Principal
;****************************
Principal
    CALl    Retardo_500ms        ;ANTIRREBOTE
    BTFSS    PULSADOR
    GOTO    $-1
    BTFSC    PULSADOR
    GOTO    $-1
    MOVLW    .10                ;NUMERO DE VECES
    MOVWF    REPETIR
QQ    MOVLW    H'20'            ;ESPACIO
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    QQ
    MOVLW    .12
    MOVWF    REPETIR
WW    MOVLW    H'2A'            ;INTERLINEA
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    WW
    MOVLW    H'0A'            ;INTERLINEA
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    CALL    NATIONALITY        ; Aqui para que escriba caratetes Pequenos Normal
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'            ; Interlinea 2 Veces
    CALl    ENVIA
    MOVLW    H'1b'            ; CARACTER MAS GRANDE
    CALL    ENVIA
    MOVLW    H'21'            ;CARACTER MAS GRANDE
    CALL    ENVIA
    MOVLW    .48                ; ES EL CARACTER MAS GRANDE HASTA AHORA'011
    CALl    ENVIA

    CALL    INCREMENTA          ; Va a INCREMENTAR CONTADOR
    MOVLW    .6
    MOVWF    REPETIR
AA    MOVLW    H'20'            ;IMPRIMIR EN LA MITAD DEL TICKET        
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    AA    
    MOVF    DECENAS,W        ; DECENAS
    CALL    TABLA            ;BUSCA CODIGO
    MOVWF    PORTB            ; LO ENVIA A LA IMPRESORA  D0 a D7
    CALL    ENVIA
    MOVLW    H'20'
    CALL    ENVIA
    MOVF    UNIDADES,W        ; CONTADOR UNIDADES
    CALL    TABLA            ; BUSCA CODIGO
    MOVWF    PORTB            ; LO ENVIA A D0 a D7
    CALL    ENVIA

    MOVLW    H'0a'        ;Un ESPACIO
    CALl    ENVIA
    MOVLW    H'0A'        ;Un Espacio
    CALL    ENVIA
;******

    MOVLW    H'20'        ;ESPACIO
    CALL    ENVIA
    MOVLW    H'20'
    CALl    ENVIA
    MOVLW    H'20'
    CALL    ENVIA
    MOVLW    H'59'        ;Y
    CALl    ENVIA
    MOVLW    H'4F'        ;O
    CALL    ENVIA
    MOVLW    H'55'        ;U
    CALL    ENVIA
    MOVLW    H'52'        ;R
    CALl    ENVIA
    MOVLW    H'20'        ;ESPACIO
    CALL    ENVIA
    MOVLW    H'54'        ;T
    CALL    ENVIA
    MOVLW    H'55'        ;U
    CALl    ENVIA
    MOVLW    H'52'        ;R
    CALl    ENVIA
    MOVLW    H'4E'        ;N
    CALL    ENVIA
    MOVLW    H'0a'        ;INTERLINEA
    CALl    ENVIA
    MOVLW    H'0a'        ;INTERLINEA
    CALl    ENVIA
;****
    MOVLW    H'1b'        ;  CANCELA CARACTER GRANDE
    CALL    ENVIA
    MOVLW    H'40'        ; CANCELA CARACTER GRANDE
    CALL    ENVIA
;****
    MOVLW    .4            ;NUMERO VECES
    MOVWF    REPETIR
TT    MOVLW    H'20'        ;ESPACIO
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    TT
;****
    MOVLW    H'82'        ;R        ;;;;; buscar los codigos
    CALL    ENVIA
    MOVLW    H'65'        ;A     ;; de Las Letras que quiera
    CALL    ENVIA
    MOVLW    H'90'        ;Z        ;;imprimir
    CALl    ENVIA
    MOVLW    H'79'        ;O
    CALL    ENVIA
    MOVLW    H'4E'        ;N
    CALl    ENVIA
    MOVLW    H'20'        ;ESPACIO
    CALl    ENVIA
    MOVLW    H'83'        ;S
    CALl    ENVIA
    MOVLW    H'79'        ;C
    CALl    ENVIA
    MOVLW    H'4F'        ;I
    CALL    ENVIA
    MOVLW    H'65'        ;A
    CALL    ENVIA
    MOVLW    H'76'        ;L
    CALl    ENVIA
    MOVLW    H'20'        ;ESPACIO
    CALL    ENVIA
;***
    MOVLW    H'42'        ;B
    CALL    ENVIA
    MOVLW    H'42'        ;B
    CALl    ENVIA
    MOVLW    H'42'        ;B
    CALL    ENVIA
    MOVLW    H'42'        ;B
    CALL    ENVIA
    MOVLW    H'42'        ;B
    CALL    ENVIA
    MOVLW    H'42'        ;B
    CALL    ENVIA
    MOVLW    H'42'        ;B
    CALl    ENVIA
    MOVLW    H'42'        ;B
    CALl    ENVIA
;***
    MOVLW    H'0A'        ;INTERLINEA
    CALL    ENVIA

    MOVLW    .10            ;NUMERO VECES
    MOVWF    REPETIR
EE    MOVLW    H'20'        ;ESPACIO
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    EE
    MOVLW    .12            ;NUMERO VECES
    MOVWF    REPETIR
RR    MOVLW    H'2A'        ;ASTERISCOS
    CALL    ENVIA
    DECFSZ    REPETIR,F
    GOTO    RR
    
    MOVLW    H'0A'        ;INTERLINEA
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'
    CALl    ENVIA
    MOVLW    H'0A'        ;INTERLINEA
    CALl    ENVIA

    MOVLW    H'1B'            ;Reinicia Printer
    CALL    ENVIA
    MOVLW    H'40'            ;Reinicia Printer
    CALL    ENVIA
    GOTO    Principal

;*********************************

INCREMENTA
    MOVF    CONTADOR,W            ;CONTADOR TURNOS
    INCF    CONTADOR,F
    MOVF    CONTADOR,W
    SUBLW    .10
    BTFSS    STATUS,Z
    GOTO    ESCRIBA_UNIDADES
    CLRF    CONTADOR
    MOVF    CONTADOR,W
    MOVWF    UNIDADES
    INCF    CONTADOR_2,F
    MOVF    CONTADOR_2,W
    SUBLW    .10
    BTFSS    STATUS,Z
    GOTO    ESCRIBA_DECENAS
    CLRF    CONTADOR_2
    CLRF    DECENAS
    CLRF    UNIDADES
    ;GOTO    Principal
    RETURN
;*********************************
ESCRIBA_UNIDADES
    MOVF    CONTADOR,W
    MOVWF    UNIDADES
    RETURN
;********************
ESCRIBA_DECENAS
    MOVF    CONTADOR_2,W
    MOVWF    DECENAS
    RETURN
;********************
TABLA
    ADDWF    PCL,F
    RETLW    H'30'
    RETLW    H'31'
    RETLW    H'32'
    RETLW    H'33'
    RETLW    H'34'
    RETLW    H'35'
    RETLW    H'36'
    RETLW    H'37'
    RETLW    H'38'
    RETLW    H'39'
    

;************************
NATIONALITY
    MOVLW    .3                    ;NUMERO DE VECES A DECREMENTAR
    MOVWF    REPETIR

    MOVLW    H'20'                ;ESPACIO
    CALL    ENVIA
    DECFSZ    REPETIR,F            ; DECREMENTA
    GOTO    $-2                    ;RETORNA  ESTO ES UN BUCLE  DESCUENTA HASTA QUE CERO. y SALTA

    MOVLW    .82                ;R
    CALL    ENVIA
    MOVLW    .69                ;E
    CALl    ENVIA
    MOVLW    .83                ;S
    CALL    ENVIA
    MOVLW    .73                ;I
    CALL    ENVIA
    MOVLW    .68                ;D
    CALL    ENVIA
    MOVLW    .69                ;E
    CALl    ENVIA
    MOVLW    .78                ;N
    CALL    ENVIA
    MOVLW    .67                ;C
    CALL    ENVIA
    MOVLW    .69                ;E
    CALL    ENVIA

    MOVLW    .32                ;ESPACIO en DECIMAL
    CALL    ENVIA
    MOVLW    .38                ; SIMBOLO &
    CALl    ENVIA
    MOVLW    .32                ;ESPACIO
    CALL    ENVIA
    MOVLW    .78                ;N
    CALL    ENVIA

    MOVLW    .65                ;A
    CALL    ENVIA
    MOVLW    .84                ;T
    CALl    ENVIA
    MOVLW    .73                ;I
    CALL    ENVIA
    MOVLW    .79                ;O
    CALL    ENVIA
    MOVLW    .78                ;N
    CALL    ENVIA
    MOVLW    .65                ;A
    CALl    ENVIA
    MOVLW    .76                ;L
    CALL    ENVIA
    MOVLW    .73                ;I
    CALL    ENVIA
    MOVLW    .84                ;T
    CALL    ENVIA
    MOVLW    .89                ;Y
    CALl    ENVIA

    RETURN
;***************************************************
ENVIA
    BTFSC    PORTD,5                ; COLOCA A CERO (0) STROBE
    GOTO    $-1
    MOVWF    PORTB                ; ENVIA INFORMACION A LA IMPRESORA  D0 a D7
    BCF        STROBE
    CALL    Retardo_4micros
    BSF        STROBE                ; COLOCA A UNO (1) STROBE
    RETURN



;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
    INCLUDE    <RETARDOS.ASM>
    END

Uf; que lastima.

Hice el programa bien ordenadito, pero al subirlo se desconfiguró.
Cualquier pregunta, la contestaré con gusto.

Cesar.
 
Última edición por un moderador:
Lo de hacer una subrutina que pintase una cadena de caracteres (terminada en byte 0, por ejemplo), hubiera sido genial, por lo de hacer el código más corto ;)
 
Hola joaquin.
Si tienes Razon,
lo que pasa es que para entenderlo bien lo desarrolle de esta manera ( paso a paso) ahora lo debo hacer mas corto.
La verdad es que me costo entender estos comandos ESC.
Pero ya para el trabajo final . lo acortare.
Ahora le estoy sumando un display 7 segmentos.
De forma que el cliente pueda ver cual numero le correspondera, antes de tomar el ticket.
La idea es que si el cliente ve que hay mucha cola delante de el. Pueda decidir si espera o vuelve otro dia. de esta manera nadie pierde tiempo ( por que ahora hasta los minutos tienen precio )

Cesar
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Bueno, como usted lo quería.
Aquí esta el programa para controlar una impresora de puerto paralelo (Térmica Microprinter) con un PIC.

Al oprimir el pulsador la impresora mostrará:

Una línea de asteriscos.
Una línea nombre del establecimiento.
Una línea consecutivo del contador de turnos.
Una línea mensaje (YOUR TURN)
Una línea mensaje (CIUDAD)
Una línea de asteriscos.

Es difícil subir el código ya que se desordena, pero creo que de todas maneras esta bastante fácil de entender,
Recuerde: Todo lo escrito después del punto y coma son comentarios. (No hacen parte del programa.)
Bueno, me falta grabar el contador en EEPROM para que no se borre por falta de corriente.

Ojala les sirva.
Código:
;    ************************************        
;                                                    LEE EL ;PULSADOR ESCRIBE MENSAJE  INCREMENTA CONTADOR
        LIST    P=16F876A    
  include<p16f876A.inc>


    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF; & _MCLRE_ON 

    CBLOCK    0x20
    CONTADOR
    CONTADOR_2
    UNIDADES
    DECENAS
    NUMERADOR
    CONTADOR_CARACTERES
    DATOS
    APUNTA_CARACTER        
    CODIGO_CARACTER        
    REPETIR            
    DATO_A_ENVIAR        
    LCD_GuardaDato        
    LCD_GuardaTRISB
    AUXILIAR_1
    AUXILIAR_2
    ENDC


CARACTERES_POR_LINEA    EQU    .16                    ; Número de caracteres por línea de la IMPRESORA.

#DEFINE  STROBE                PORTA,0
#DEFINE  BUSY                PORTA,1
#DEFINE  RESET                PORTA,3
#DEFINE     PULSADOR            PORTA,4
#DEFINE     ACKNOWLEDGE        PORTA,5    
#DEFINE  PUERTO_IMPRESORA    PORTB                        ; visualizar. POR PUERTO PARALELO

; ZONA DE CÓDIGOS ********************************************************************

    ORG    0


Inicio

    CLRf    PORTA
    CLRF    PORTB
    CLRF    PORTC
    BSF        STATUS,RP0
    MOVLW    B'00111010'
    MOVWF    TRISA
    MOVLW    B'00000000'
    MOVWF    TRISB
    MOVLW    B'00000000'
    MOVWF    TRISC
    MOVLW    0x06
    MOVWF    ADCON1
    BCF        STATUS,RP0
    MOVLW    0x06
    MOVWF    ADCON1
    MOVLW    .0
    MOVWF    CONTADOR
    MOVLW    .0
    MOVWF    CONTADOR_2
    MOVLW    .12
    MOVWF    REPETIR

;*********************

    MOVLW    H'1B'            ;Reinicia Printer
    CALL    IMPRIME    
    MOVLW    H'40'            ;Reinicia Printer
    CALL    IMPRIME    
    MOVLW    H'0A'
    CALl    IMPRIME    
    GOTO    Principal
;************************************
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Principal

    CALl    Retardo_100ms
    BTFSS    PULSADOR
    GOTO    $-1
    BTFSC    PULSADOR
    GOTO    $-1
;*******************
    MOVLW    MensajeA            ;ASTERISCOS
    CALl    LEA_MENSAJES
    MOVLW    H'0A'
    CALl    IMPRIME                ;INTERLINEA

    MOVLW    Mensaje0            ;NOMBRE ESTABLECIMIENTO
    CALl    LEA_MENSAJES
    MOVLW    H'0A'
    CALL    IMPRIME                ;INTERLINEA

    MOVLW    H'1B'                ;CARACTER GRANDE
    CALL    IMPRIME
    MOVLW    H'21'
    CALL    IMPRIME
    MOVLW    .48
    CALL    IMPRIME

    MOVLW    .6
    MOVWF    REPETIR
AAA

    MOVLW    H'20'
    CALL    IMPRIME
    DECFSZ    REPETIR,F
    GOTO    AAA

    CALL    INCREMENTA

    MOVF    DECENAS,W
    CALL    IMPRIME
    MOVF    UNIDADES,W
    CALL    IMPRIME

    MOVLW    H'0A'
    CALL    IMPRIME
    MOVLW    H'0A'
    CALL    IMPRIME


    MOVLW    Mensaje1            ;MENSAJE  SU TURNO
    CALL    LEA_MENSAJES

    MOVLW    H'1b'                   ;  CANCELA CARACTER GRANDE
    CALL    IMPRIME
    MOVLW    H'40'                ; CANCELA CARACTER GRANDE
    CALL    IMPRIME

    MOVLW    H'0A'
    CALL    IMPRIME
    MOVLW    Mensaje2
    CALL    LEA_MENSAJES
    MOVLW    H'0A'
    CALL    IMPRIME

    MOVLW    MensajeA
    CALL    LEA_MENSAJES

    MOVLW    H'0A'
    CALL    IMPRIME
    MOVLW    H'0A'
    CALL    IMPRIME
    MOVLW    H'0A'
    CALL    IMPRIME
    GOTO    Principal
;***************************************    
INCREMENTA


    INCF    CONTADOR,F
    MOVF    CONTADOR,W
    SUBLW    .10
    BTFSS    STATUS,Z
    GOTO    IMPRIMA_UNIDADES
    CLRF    CONTADOR
    INCF    CONTADOR_2,F
    MOVF    CONTADOR_2,W
    SUBLW    .10
    BTFSS    STATUS,Z
    GOTO    IMPRIMA_DECENAS
    CLRF    CONTADOR
    CLRF    CONTADOR_2
    CLRF    UNIDADES
    CLRF    DECENAS
    RETURN
;*************************
IMPRIMA_UNIDADES


    MOVF    CONTADOR,W
    CALL    TABLA
    MOVWF    UNIDADES

    MOVF    CONTADOR_2,W
    CALL    TABLA
    MOVWF    DECENAS
    RETURN
;*************************
IMPRIMA_DECENAS


    MOVF    CONTADOR_2,W
    CALL    TABLA
    MOVWF    DECENAS
    MOVLW    .0
    MOVWF    CONTADOR
    MOVF    CONTADOR
    CALL    TABLA
    MOVWF    UNIDADES
    RETURN
;************************

MENSAJES_A_IMPRIMIR


Mensajes


    addwf    PCL,F
MensajeA


    DT    "       ***********       ",0x00
Mensaje0

                                               ; Posición inicial del mensaje 0.
    DT "   ALVAREZ  ELECTRONICS  ",0x00        ; CESAR    ", 0x00
Mensaje1

                                            ; Posición inicial del mensaje 1.
    DT "   YOUR TURN   ", 0x00    

Mensaje2

                                            ; Posición inicial del mensaje 2.
    DT "     BELIZE   BELMOPAN    ", 0x00

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

LEA_MENSAJES

    movwf    APUNTA_CARACTER                    ; Posición del primer carácter del mensaje.;
    movlw    MENSAJES_A_IMPRIMIR                ; Halla la posición relativa del primer carácter;
    subwf    APUNTA_CARACTER,F                ; del mensaje respecto de etiqueta "Mensajes".
    decf    APUNTA_CARACTER,F                ; Compensa la posición que ocupa "addwf PCL,F".;

IMPRIME_OTRO_CARACTER


    movf    APUNTA_CARACTER,W
    call    MENSAJES_A_IMPRIMIR                ; Obtiene el código ASCII del carácter a
    movwf    CODIGO_CARACTER                    ; Guarda el valor de 

    movf    CODIGO_CARACTER,F                ; Lo único que hace es posicionar flag Z. 

    btfsc    STATUS,Z                        ; que sea "0x00", que es código     
    goto    FIN                                ; de mensaje, sale fuera.

NO_ULTIMO_CARACTER


    call    IMPRIME                            ; Visualiza el carácter ASCII leído.
    incf    APUNTA_CARACTER,F                ; Apunta a la posición del siguiente 

    goto    IMPRIME_OTRO_CARACTER            ; dentro del mensaje.
FIN


    MOVLW    H'0A'
    CALl    IMPRIME    
    RETURN                        

;********************************************
IMPRIME            

    BTFSC    BUSY
    GOTO    $-1    
    movwf    PUERTO_IMPRESORA            ; Envía el dato ala IMPRESORA
    BCF        STROBE
    CALL    Retardo_4micros
    BSF        STROBE
    return
;**********************************
TABLA


    ADDWF    PCL,F
    RETLW    H'30'
    RETLW    H'31'
    RETLW    H'32'
    RETLW    H'33'
    RETLW    H'34'
    RETLW    H'35'
    RETLW    H'36'
    RETLW    H'37'
    RETLW    H'38'
    RETLW    H'39'

    INCLUDE  <RETARDOS.ASM>
    END
    
;*****************************************************************

Cesar
 
Última edición por un moderador:
La mejor forma de publicar código en este foro, es mandarlo en forma de texto, naturalmente, pero... sin usar caracteres de tabulación.

Cambia las propiedades de tu editor de programas, para que no use esos caracteres, y en su lugar, que emita caracteres blancos normales al pulsar la tecla de tabulación.

Y... cuando pongas el código en el mensaje, lo seleccionas con el ratón y pulsas el botón que pone PHP. Así, saldrá con colorines y formateado con letra monoespaciada.

Por otra parte... creo que el código se puede reducir un poquito más ;) Voy a ver si tengo el ensamblador instalado...
 
Última edición por un moderador:
Una pregunta...

En el inicio tienes puesto esto:
PHP:
    MOVLW   0x06
    MOVWF   ADCON1
    BCF     STATUS,RP0
    MOVLW   0x06
    MOVWF   ADCON1
¿Para qué haces eso? Es decir, sé que estás en el bank 1 e inicializas el valor de ADCON1, pero, luego cambias al bank 0, y repites la instrucción. ¿Por qué?

Otra cosa... ¿Puedes publicar el código que falta de retardos.asm?
 
Última edición por un moderador:
Pues... el caso es que lo puedes aprovechar para indicar a ADCON0 que toda operación A/D está desactivada. Pero bueno, también puede quedar así.

Estoy reescribiendo el código porque me hará falta para gestionar una impresora DMP-3000, pero antes lo publicaré por aquí, a ver qué te parece.
 
Esta es mi versión. No la he probado con la impresora, pero con el simulador sí funciona.

Lo interesante de este código es el uso de macros, para reducir la escritura de código.

Y otro detalle curioso: los textos a imprimir están empaquetados de dos en dos, en ristras de 14 bits (con la ayuda de la directiva 'da'), en la zona de memoria del programa, lo que implica que hay que hacer un procedimiento especial para poder acceder a ella (normalmente sólo se accede a la zona de memoria de datos).

Y... conociendo la arquitectura de los PIC... resulta que es igual de enrevesado que el resto de la arquitectura de estos microcontroladores. Por esta razón, nadie lo usa y en su lugar se crean tablas con retlw. Pero está aquí porque es una buena forma de ver cómo ahorrar espacio de memoria al máximo.

PHP:
;*******************************************************************************
; A_PRINTER_6.ASM
;
; Impresión de tiques.
;
; Autor: Joaquín Ferrero
; Fecha: 23 julio 2014
;
; Para micro impresora térmica, por puerto paralelo. Papel de 58 mm
;
; Atención: Hay que conectar las dos líneas siguientes
;   STROBE
;   BUSY
;
; Funcionamiento:
;   Lee el pulsador
;   Escribe el mensaje
;   Incrementa el contador
;
; Formato del tique:
; +--------------------------+
; |        ***********       | [ asteriscos ]
; |                          |
; |                          |
; |                          |
; |    EMPRESA               |
; |                          |
; |      0  1                | [ NÚMERO EN GRANDE ]
; |                          |
; |                          |
; | YOUR TURN                | [ MISMO TAMAÑO DEL NÚMERO ]
; |                          |
; | RESIDENCE & NATIONALITY  |
; |                          |
; |                          |
; |        ***********       | [ asteriscos ]
; |                          |
; |                          |
; |                          |
; +--------------------------+
;
; Indentación: 4 spaces
; MPASM v5.56
;

;*******************************************************************************
; Listado y condiciones de ensamblado

    processor   16F876A                     ; 4 Mhz
    radix       dec
    errorlevel  -302                        ; Turn off banking message


;*******************************************************************************
; Bibliotecas

    include p16f876a.inc

    extern  Retardo_100ms,Retardo_4µs

;*******************************************************************************
; Fusibles

    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF; & _MCLRE_ON


;*******************************************************************************
; Definiciones globales

;*******************************************************************************
; Conector puerto paralelo
;
;Signal Name    Register Bit    DB-25       E/S dirección (desde PIC)
;
;¬Strobe       ¬A0              1           Output    Dato disponible
;Data Bit 0     B0              2           Output    Dato
;Data Bit 1     B1              3           Output
;Data Bit 2     B2              4           Output
;Data Bit 3     B3              5           Output
;Data Bit 4     B4              6           Output
;Data Bit 5     B5              7           Output
;Data Bit 6     B6              8           Output
;Data Bit 7     B7              9           Output
;Acknowledge                   10           Input     Impresora procesó dato o está en línea
;¬Busy         ¬A1             11           Input     Está escribiendo/Fuera de línea/Procesando código de control
;Paper End                     12           Input     No hay papel
;Select In                     13           Input     Impresora en línea preparada para recibir
;¬Line Feed                    14           Output    Hace un FF (expulsa la hoja)
;Error                         15           Input     Impresora fuera de línea
;Reset                         16           Output    Inicializar impresora
;¬Select                       17           Output    Poner impresora en línea (si no hay error)
;Ground         -              18-25

#DEFINE  ¬STROBE            PORTA,RA0
#DEFINE  BUSY               PORTA,RA1
#DEFINE  PULSADOR           PORTA,RA4
#DEFINE  PUERTO_IMPRESORA   PORTB

;*******************************************************************************
; Macros
; Imprimir una cadena de bytes terminada en 0x00 almacenados en el programa
imprime_msg     macro   direccion
                movlw   high(direccion)     ; Byte alto
                movwf   PRINT_STRING_ADDR_H
                movlw   low(direccion)      ; Byte bajo
                movwf   PRINT_STRING_ADDR_L
                call    print_string
                endm

; Imprimir un carácter
imprime_chr     macro   caracter
                movlw   caracter
                call    print_chr
                endm


;*******************************************************************************
; Espacio de memoria compartida
                udata_shr

CONTADOR1   res 1                           ; contadores de visitas. Byte bajo
CONTADOR2   res 1                           ; Byte alto


;*******************************************************************************
; Vectores
VECcode         code    0x0000

                nop                     ; 0x0000  (Este nop es necessario para operar con ICD)
                goto    Inicio          ; 0x0001  (Inicio de programa)
                nop                     ; 0x0002
                nop                     ; 0x0003
                goto    _ISR            ; 0x0004  (Rutina de interrupción)

; Rutina de interrupción
ISRcode         code
_ISR:           retfie

; Programa principal
PRGcode         code
Inicio:
; Inicialización del hardware
                banksel PORTA           ; bank 0
                clrf    PORTA
                clrf    PORTB
                bcf     ADCON0, ADON    ; desactivar todo A/D

; Inicialización de las variables
                clrf    CONTADOR1
                clrf    CONTADOR2

; Definiciones de las E/S
                bsf     STATUS, RP0     ; bank 1
                movlw   B'00000110'     ; E/S analógicas como digitales
                movwf   ADCON1
                movlw   B'00111010'     ; 0: salida. 1: entrada
                movwf   TRISA
                movlw   B'00000000'
                movwf   TRISB

; Iniciar impresora
                bcf     STATUS, RP0     ; bank 0
                bsf     ¬STROBE         ; no hay carácter a imprimir
;
                imprime_chr     H'1B'
                imprime_chr     '@'
                call    Retardo_100ms       ; Esperar estabilización
                call    Retardo_100ms
                call    Retardo_100ms
                call    Retardo_100ms
                call    Retardo_100ms
                imprime_chr     "\n"

; Bucle principal. Siempre en bank 0
Principal:

; Bucle de espera de la pulsación de PULSADOR
Espera_pulsacion:
                call    Retardo_100ms       ; Esperar la pulsación del pulsador
                btfss   PULSADOR            ; ¿Botón pulsado?
                goto    Espera_pulsacion    ; No, esperar

Espera_no_pulsacion:
                call    Retardo_100ms       ; Esperar la suelta del pulsador
                btfsc   PULSADOR            ; ¿Botón levantado?
                goto    Espera_no_pulsacion ; No, esperar

; Incrementa contador de visitas
                incf    CONTADOR1,F         ; incrementar unidades
                movf    CONTADOR1,W
                sublw   10                  ; ¿hemos llegado a diez?
                btfss   STATUS,Z
                goto    Imprimir_tique      ; no

                clrf    CONTADOR1           ; poner a cero las unidades
                incf    CONTADOR2,F         ; incrementar decenas
                movf    CONTADOR2,W
                sublw   10                  ; ¿hemos llegado a diez?
                btfss   STATUS,Z
                goto    Imprimir_tique      ; no

                clrf    CONTADOR2           ; poner a cero las decenas

; Impresión del tique
Imprimir_tique:
                imprime_msg     msg_asteriscos
                imprime_chr     "\n"
                imprime_chr     "\n"
                imprime_msg     msg_empresa
                imprime_chr     "\n"

                imprime_chr     H'1B'       ; activa letra grande
                imprime_chr     '!'
                imprime_chr     16+32

                imprime_msg     msg_espacios

                movf    CONTADOR2,W         ; leemos las decenas actuales
                addlw   '0'
                call    print_chr

                movf    CONTADOR1,W         ; leemos las unidades actuales
                addlw   '0'
                call    print_chr

                imprime_chr     "\n"
                imprime_chr     "\n"

                imprime_msg     msg_su_turno

                imprime_chr     H'1B'       ; cancela letra grande
                imprime_chr     '!'
                imprime_chr     0

                imprime_chr     "\n"

                imprime_msg     msg_lugar
                imprime_chr     "\n"

                imprime_msg     msg_asteriscos
                imprime_chr     "\n"
                imprime_chr     "\n"
                imprime_chr     "\n"

                goto    Principal


; ******************************************************************************
; Subrutinas

; ------------------------------------------------------------------------------
; print_string
;
; Impresión de una cadena de bytes terminada en 0x00.
;
; La cadena está almacenada en la zona de memoria del programa Flash.
;
; Se sale quedando en el bank 0.
;

; Variables
print_string_mem:   udata_shr

PRINT_STRING_ADDR_H res 1                   ; Puntero a cadena a pintar
PRINT_STRING_ADDR_L res 1
PRINT_STRING_BYTE_H res 1                   ; bytes que leemos de
PRINT_STRING_BYTE_L res 1                   ; la memoria del programa

; Código
print_string_code:  code

print_string:
                banksel EEADRH              ; bank 2
                movf    PRINT_STRING_ADDR_H, W
                movwf   EEADRH
                movf    PRINT_STRING_ADDR_L, W
                movwf   EEADR

                bsf     STATUS, RP0         ; bank 3
                bsf     EECON1, EEPGD       ; Acceso a memoria de programa

print_loop:
                bsf     EECON1, RD          ; Iniciar acceso
                nop                         ; espera obligada
                nop
                bcf     STATUS, RP0         ; bank 2
                incfsz  EEADR, F            ; incrementar byte bajo
                goto    print_read_bytes
                incf    EEADRH, F           ; incrementar byte alto

; Leemos dos bytes, que contienen 14 bits, que son dos caracteres de 7 bits, que
; es la forma de empaquetar la información que tiene la directiva 'da'.
print_read_bytes:
                movlw   0x7F
                andwf   EEDATA, W           ; byte bajo, menos el bit más alto
                movwf   PRINT_STRING_BYTE_L ; guardar
                rlf     EEDATA, W           ; rotar byte bajo y en C queda bit 7
                rlf     EEDATH, W           ; que se mete como bit 0 en byte alto
                movwf   PRINT_STRING_BYTE_H ; guardar

                bcf     STATUS, RP1         ; bank 0

;                movf    PRINT_STRING_BYTE_H, W
                                            ; truco: W ya tiene el byte, así que
                                            ; sólo hay que ver si es 0. Hacemos
                                            ; un test directo del registro
                addlw   0
                btfsc   STATUS, Z           ; ¿Se acabó?
                return                      ; Sí
                call    print_chr           ; impresión

                movf    PRINT_STRING_BYTE_L, W
                btfsc   STATUS, Z           ; ¿Se acabó?
                return                      ; Sí
                call    print_chr           ; impresión

                banksel EECON1              ; bank 3
                goto    print_loop          ; repetir


; ------------------------------------------------------------------------------
; print_chr
;
; Impresión de un carácter (un byte).
;
; Se supone que estamos en el bank 0.
;

print_chr:
                btfsc   BUSY                ; ¿Impresora ocupada?
                goto    $-1                 ; sí, seguir esperando
                movwf   PUERTO_IMPRESORA    ; Envía el dato a la impresora
                bcf     ¬STROBE             ; Señalar que hay un dato disponible
                call    Retardo_4µs
                bsf     ¬STROBE
                return


; ******************************************************************************
; Datos y mensajes
; Ancho impresora:  |123456789012345678901234567890|
msg_asteriscos: da  "       ***********\n",0
msg_empresa:    da  "   ALVAREZ  ELECTRONICS\n",0
msg_espacios:   da  "      ",0
msg_su_turno:   da  "   YOUR TURN\n", 0
msg_lugar:      da  "     BELIZE   BELMOPAN\n", 0


;*******************************************************************************

; El archivo con los retardos es incorporado por el make
; por lo que no hace falta la instrucción siguiente.
;    include retardos.asm

                end
PHP:
;*******************************************************************************
; retardos.asm
;
; Retardos de espera.
;
; Autor: Joaquín Ferrero.
; Fecha: 23 julio 2014
;

;*******************************************************************************
; Listado y condiciones de ensamblado

    processor   16F876A                     ; 4 Mhz
    radix       dec
    errorlevel  -302                        ; Turn off banking message


;*******************************************************************************
; Bibliotecas

    include p16f876a.inc

    global  Retardo_100ms,Retardo_4µs

; ----------------------------------------------------------------------------------------------------
; Espera = 100ms
; Frecuencia de reloj = 4Mhz
;
; Espera real = 0.1 segundos = 100000 ciclos
; Error = 0.00 %

Retardo_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code:       code

Retardo_100ms:
                                    ;99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop:
                    decfsz  Retardo_100ms_d1, f
                    goto    $+2
                    decfsz  Retardo_100ms_d2, f
                    goto    Retardo_100ms_loop

                                    ;3 ciclos
                    goto    $+1
                    nop

                                    ;4 ciclos (incluyendo la llamada)
                    return

; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
; mar 22 jul 2014 19:22:23 CEST
; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

; ----------------------------------------------------------------------------------------------------
; Espera = 4us
; Frecuencia de reloj = 4Mhz
;
; Espera real = 4e-06 segundos = 4 ciclos
; Error = 0.00 %

Retardo_4µs:
                                    ;4 ciclos (incluyendo la llamada)
                    return

; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
; ./delay_pic.pl -s Retardo_4µs 4Mhz 4us
; mar 22 jul 2014 19:28:23 CEST
; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

        end
 
Última edición por un moderador:
Atrás
Arriba