TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: kapotik en 24 de Marzo de 2016, 21:24:37

Título: comunicacion serial por sof en 16f877a
Publicado por: kapotik en 24 de Marzo de 2016, 21:24:37
Buenas, en esta oportunidad recurro al foro por que necesito tener 3 puertos seriales en el 16f877a, ya se como hacer funcionar el que tiene por harware, pero no me funciona el que intento hacer por sof, estoy usando el codigo para el 16f84a de la editorial rama, que ya lo he probado y me funciona muy bien, pero al migrar el mismo codigo al f877a no me funciona, estoy casi seguro de que estoy configurando mal el pic pero no me doy cuenta donde, le dejo el codigo y los archivos .INC para ver si me hechan una manito. gracias

PD: estoy usando el puerto D0 como rx y D1 como tx

Código: [Seleccionar]
;************************************ RS232_11.asm **************************************
;
;
; SISTEMA DE GOBIERNO DESDE ORDENADOR: Desde el teclado de un ordenador se desea comandar
; el movimiento de una estructura móvil, según la siguiente tabla:
;
;    TECLA (Por ejemplo)        MOVIMIENTO
;    -------------------        ----------
;            t                Adelante
;            b                Atrás
;            a                Izquierda
;            l                Derecha
;         Espacio            Parada
;
; La pulsación de cualquiera de estas teclas activa el estado de las salidas correspondiente
; RB3 (Adelante), RB2 (Atrás), RB1 (Izquierda), RB0 (Derecha) y apaga el resto.
;
; El movimiento que se está realizando aparece reflejado en un mensaje en el visualizador LCD
; del sistema y también en la pantalla del ordenador.
;
; El programa debe permitir modificar facilmente en posteriores revisiones en el hardware de
; la salida. Es decir, para activar las salidas conviene utilizar el direccionamiento por bit
; en lugar de por byte (utilizar instrucciones "bsf" y "bcf", en lugar de "mov..").


    LIST           P=16F877A
    INCLUDE        <P16F877A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _LVP_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK   0x0C
    TeclaPulsada                       ; Va a guardar el contenido de la tecla pulsada.
    MensajeApuntado                    ; Va a guarda la dirección del mensaje apuntado.
    ENDC

#DEFINE  SalidaAdelante     PORTB,3    ; Define dónde se sitúan las salidas.
#DEFINE  SalidaAtras        PORTB,2
#DEFINE  SalidaIzquierda    PORTB,1
#DEFINE  SalidaDerecha      PORTB,0

TECLA_ADELANTE    EQU    't'           ; Código de las teclas utilizadas.
TECLA_ATRAS       EQU    'b'
TECLA_IZQ         EQU    'a'
TECLA_DER         EQU    'l'
TECLA_PARADA      EQU    ' '           ; Código de la tecla espaciadora, (hay un espacio,
                                       ; tened cuidado al teclear el programa).
CONF_ADCON1     EQU b'00000110' ; Configuracion PORTA E/S digital
; ZONA DE CÓDIGOS ********************************************************************

    ORG    0

movlw 7
movwf CMCON ; CMCON=7 inhibir los comparadores
;**** Configuracion de puertos ****



        bsf STATUS,RP0 ; Ir banco 1
    movlw b'00000000' ; valor  portA
        movwf PORTA
        movlw b'00000000' ; valor  portB 0 SALIDA---1 ENTRADA
        movwf PORTB
        movlw b'00000000'       ; valor  portC
        movwf PORTC
        movlw b'00000001'       ; valor  portD
        movwf PORTD
        movlw b'00000000'       ; valor  portE
        movwf PORTE
        bcf   OPTION_REG,7 ; Pull up habilitadas
        bcf STATUS,RP1

    movlw  CONF_ADCON1 ; Configurar el PORTA como digital
        movwf  ADCON1

       
        bcf STATUS,RP0 ; Ir banco 0
    bcf STATUS,RP1

Inicio
    call    RS232_Inicializa

Principal
     bsf     PORTB,0
    call    RS232_LeeDato         ; Espera a recibir un carácter.
    call    TesteaTeclado
    goto    Principal



; Subrutina "TesteaTeclado" -------------------------------------------------------------
;
; Testea el teclado y actúa en consecuencia.

TesteaTeclado
    movwf    TeclaPulsada              ; Guarda el contenido de la tecla pulsada.
    xorlw    TECLA_ADELANTE            ; ¿Es la tecla del movimiento hacia adelante?
    btfsc    STATUS,Z
    goto     Adelante                  ; Sí, se desea movimiento hacia adelante.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_ATRAS               ; ¿Es la tecla del movimiento hacia atrás?
    btfsc    STATUS,Z
    goto     Atras                     ; Sí, se desea movimiento hacia atrás.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_IZQ           ; ¿Es la tecla del movimiento hacia la izquierda?
    btfsc    STATUS,Z
    goto     Izquierda                 ; Sí, se desea movimiento hacia la izquierda.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_DER                 ; ¿Es tecla del movimiento hacia la derecha?
    btfsc    STATUS,Z
    goto     Derecha                   ; Sí, se desea movimiento hacia la derecha.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_PARADA              ; ¿Es la tecla de parada?.
    btfss    STATUS,Z
    goto     Fin                       ; No es ninguna tecla de movimiento. Sale.
Parado
    bcf      SalidaAdelante            ; Como se ha pulsado la tecla de parada se
    bcf      SalidaAtras               ; desactivan todas las salidas.
    bcf      SalidaIzquierda
    bcf      SalidaDerecha
    goto     Visualiza
Adelante
    bcf      SalidaAtras
    bsf      SalidaAdelante
    bcf      SalidaIzquierda
    bcf      SalidaDerecha
    goto     Visualiza
Atras
    bcf      SalidaAdelante
    bsf      SalidaAtras
    bcf      SalidaIzquierda
    bcf      SalidaDerecha
    goto     Visualiza
Izquierda
    bcf      SalidaAdelante
    bcf      SalidaAtras
    bsf      SalidaIzquierda
    bcf      SalidaDerecha
    goto     Visualiza
Derecha
    bcf      SalidaAdelante
    bcf      SalidaAtras
    bcf      SalidaIzquierda


; Según el estado de las salidas visualiza el estado del sistema en el visualizador LCD y en
; el monitor del ordenador.

Visualiza
 

Fin    return

    INCLUDE  <RS232.INC>
    INCLUDE  <RETARDOS.INC>
    ;INCLUDE  <RS232MEN.INC>
        END

Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 24 de Marzo de 2016, 23:19:33
Lo que hiciste aca:

Código: ASM
  1. CBLOCK   0x0C
  2.     TeclaPulsada                       ; Va a guardar el contenido de la tecla pulsada.
  3.     MensajeApuntado                    ; Va a guarda la dirección del mensaje apuntado.
  4.     ENDC

Es decir darle un valor inicial al CBLOCK, lo tenes que hacer en todos los demas tambien, ejemplo de 1 de los archivos:

Código: ASM
  1. CBLOCK
  2.                 RS232_ContadorBits
  3.                 RS232_Dato
  4.                 ENDC

Sino todos esos CBLOCK apuntarian desde el 0x00, es decir que RS232_ContadorBits estaria accediendo a la memoria 0x00. y RS232_Dato a 0x01
Una cosa mas... Veo que pensas usar 3 puertos seriales, los cuales 2 son por soft, y si es asi no creo que funcione correctamente. Y seria bastante complejo hacer algo que funcione y no pierda datos, en realidad vas a tener que crear un programa usando un timer y monitorear ambas entradas. Realmente no se por que necesitas tantos, pero lo mas simple seria buscar un micro con mas UART (aunque esto te va llevar un PIC24 con 64 pines SMD), sino de ultima un micro con 2 UART por HW y 1 por soft, siendo el de software el de menor "importancia" , por que estas arriesgando perder bastantes datos al hacerlo por software. Ahora si no te importa perder datos, entonces dale para adelante.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: tapi8 en 25 de Marzo de 2016, 06:30:01
Si y un apunte mas:

 CBLOCK  0x0C
    TeclaPulsada                       ; Va a guardar el contenido de la tecla pulsada.
    MensajeApuntado                    ; Va a guarda la dirección del mensaje apuntado.
    ENDC

CBLOCK  0X20 no puedes ponerlo en 0X0C. Esta solo vale para el 16f84.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 25 de Marzo de 2016, 15:15:19
gracias muchachos por su ayuda, ya lo tengo funcionando gracias a ustedes  ((:-))

KILLERJC:

1º: quiero controlar mi casa desde todos los medios posibles, para eso tengo un modem GSM, un modulo bluetooth, y un modulo wifi, los tres se comunican por puerto serial, por eso los 3 puertos seriales.

2º: voy bien o como se hace, digo los equipos profecionales, usan micros con 3 puertos o hay otra manera de hacerlo.

3º: no entiendo muy bien a que te referis con que si no me importa perder datos, que significaria perder datos, por ejemplo que si estoy esperando el comando "ACTIVA", me llegaria "ACT" O "VA"?, o directamente no recivir nada, me podrias ampliar la idea?

4º: que micro puedo conseguir que no sea smd, 40 pines....a y que pueda programarlo con el Pickit 2, con dos puertos seriales por HW, en donde vivo no hay mucha variedad, y si tubiera que pasar como decis a un 18f, podria seguir programandolo en asembler?

saludos
Kapotik
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 25 de Marzo de 2016, 19:21:39
Citar
3º: no entiendo muy bien a que te referis con que si no me importa perder datos, que significaria perder datos, por ejemplo que si estoy esperando el comando "ACTIVA", me llegaria "ACT" O "VA"?, o directamente no recivir nada, me podrias ampliar la idea?

El problema esta en como realizas el soft. Pueden ser de varios tipos por ejemplo el tuyo que pregunta por el valor de la entrada, usa un delay para saber luego que entra y asi por 8 bits, puede que no funcione correctametne y pierdas justamente alguna letra o letras. Me explico con cosas sobre el tiempo.

PRINCIPAL:

               CALL  LEE_RS232_SOFT
               CALL  OTRAS_RUTINAS
               GOTO PRINCIPAL

Un programa seria algo asi donde esas Otras rutinas pueden ser muchas cosas. Ahora suponete que entro al CALL LEE_RS232 y no habia nada en el puerto lo cual salio, y luego entro a Otras_rutinas que se tarda 1 segundo en salir para ser exagerado y que veas donde esta el problema.

Por 1 segundo (en realidad lo que tarde lo que exista depues de esa lectura) vos estas inhabilitando a tu programa el recibir mensajes. Lo cual si aunque sea tarda un poco como para que la rutina RS232 pierda el valor de start ese dato se deberia descartar. Ahora imaginate esto con 2 UART, lo mas simple a hacer es:

PRINCIPAL:

               CALL  LEE_RS232_SOFT1
               CALL  LEE_RS232_SOFT2
               CALL  OTRAS_RUTINAS
               GOTO PRINCIPAL

Y si.. pero ahora mientras recibe por mi primer UART por software, no va a estar recibiendo por la segunda. Por eso mismo decia que si no te importa perder datos. La solucion es crear una sola rutina que tenga en cuenta ambas entradas, que esto es lo complicado, pero.... volvimos al problema de antes!

Casos en los que esto NO te va a afectar es que:

- Sea unicamente el PIC quien decida cuando recibir, es decir que el PIC le avise el bluetooth o wifi o lo que sea que le envie datos y ahi recibirlos, pero que sino no envien nada.
- Tambien que lo unico que te importe sea transmitir. y no recibir.

Si por ejemplo el bluetooth/wifi/GSM ( que tengas conectado a la UART por soft) jamas pero jamas  te va a enviar un dato sin que vos se lo pidas entonces adelante, pero recorda que mientras tengas que recibir no podes dejar de hacerlo o no te vas a poner a hacer otra cosa. No recuerdo como es que funcionan estos modulos, pero imagino que si alguien intenta por ejemplo parearse con el bluetooth deberia avisarle solo el bluetooth al PIC para que este responda. Con lo cual deberias estar "alerta". Pero como decia si el PIC actua como maestro y que unicamente va a recibir cuando este lo dicte, no tendrias problemas.

Otra forma de realizarlo es que tengas 2 UART por HW. Y una sola por Soft, entonces la recepcion podes moverla al PORTB,0 que tiene interrupcion por flancos y con un timer ver los tiempos ( en ves de delays) y hacer una maquina de estados. De esa forma las 3 recepciones estan realizadas por Interrupciones. Obviametne debera tener mayor prioridad la del PORTB,0 por los tiempos.

Podrias haber realizado lo mismo con el RB4 a RB7 y tener las 2 UART por soft ( siempre hablo de recepcion que es lo que presente complicacion ), Y actuar en consecuencia de la misma forma que antes. Espero que me entiendas a que me refiero.

La otra es que por ejemplo uses al menos 1 con otro tipo de comunicacion ( I2C, SPI ) siempre y cuando sea posible obviamente.

Citar
4º: que micro puedo conseguir que no sea smd, 40 pines....a y que pueda programarlo con el Pickit 2, con dos puertos seriales por HW, en donde vivo no hay mucha variedad, y si tubiera que pasar como decis a un 18f, podria seguir programandolo en asembler?

Acabo de ver la pagina de Microchip, y lamentablemetne en 8 bits no existe NADA actualmente con 2 UART y estan previsto como futuros lanzamientos micros con 2 UART y hasta con 5 UART
Aun asi casi todo SMD, que creo que te conviene mas si aprendes a usar el ICSP. ( No creo que lo soporte el Pickit2 eso si )

Pero tenes PIC24 que poseen 2 UART y son DIP, mas de 2 UART te vas a SMD. ( Seguro que varios de estos si le da soporte el Pickit2 )

Todos los PICs pueden ser programados en ASM, lo que si cambia la arquitectura, asi como en los PIC16 tenes bancos, en lso PIC18 tambien pero esta organizado de una forma mas lineal. Y en los dsPIC / PIC24 aun mejor , por ejemplo otro cambio el reloj del PIC24 y dsPIC se divide por 2 y no por 4 como en los PIC16/PIC18, aunque aumenta la complejidad y cambia bastante como es para realizar el ASM de micros de 16bits frente a los de 8bits, los de 16bits como se basa en gcc es algo mas "nominal" a otro ASM de otro micro ( atmel / ARM ) al menos en sus directivas. Pero si te compras una bestia de estas ni renegaria con ASM..

Aca un link cuando me puse a jugar con ASM en XC16, usando XC16 como base, lo cual me daba un par de ventajas. Y sin sobrecargas por que todo estaba realizado en ASM incluso le habia quitado al rutina de inicio de C.
http://www.todopic.com.ar/foros/index.php?topic=45240.msg376311#msg376311

Resumiendo:

No es estrictamente necesario tener varias UARTs, solo tenes que tener en cuenta que esos problemas de tiempos pueden suceder, y la mejor forma de actuar es hacerlo a traves de interrupciones ( y no como el codigo que pasaste que usa delays ). Si transportas ese codigo a las interrupciones creo que vas a estar bien. Tambien intentaria usar una velocidad no muy grande en esas UART, en la de HW si. Y tratar de usar el micro con la mayor velocidad posible.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 27 de Marzo de 2016, 00:56:18
te he entendido a la perfeccion!
 ahora me surgen nuevas dudas, si usara una interrupcion para cada puerto serial por sof, quiere decir que no importa en que parte este el programa en ese momento, lo deja y atiende al puerto que se este comunicando?
si es asi, que pasa con el puerto por HW, tambien tiene interrupciones, o al ser por HW ya solo lo hace, lo de atender la recepcion en cualquier momento?

y...otra...como seria en el caso de que este justo recibiendo por x puerto y se activara la otra interrupcion del otro puerto, cual tendria prioridad?, se puede asignar prioridades a las interrupciones?

leyendo por el foro el tema que me planteas, he visto que dicen que las interrupciones no se llevan muy bien con dos o mas puertos seriales, segun tu conocimiento es asi, o no deberia de darme problema.

Gracias
Saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 27 de Marzo de 2016, 02:31:10
Tenes que entender que es una interrupcion, como funciona, y el principio que tenes que tener en cuenta.

Una interrupcion esta realizada para que el micro deje de hacer lo que esta haciendo (rutina principal) y atienda otra cosa rapidamente, haga lo que tenga que hacer y salga, asi vuelve a donde estaba el programa principal, esta imagen lo explica mejor:

(http://www.puntoflotante.net/INTERRUPT-HANDLING-18F2550-2.jpg)
A la izquierda el programa principal, y la derecha la rutina de interrupcion, en ningun momento hay un GOTO a la rutina, ni un CALL, el micro se encarga de realizar esto ante un evento como puede ser un timer, un flanco , un cambio de nivel de un pin, etc siempre y cuando nosotros lo habilitamos y exista hardware para eso.

El objetivo de la interrupcion es que sea RAPIDA, es decir que entre a esa rutina, realize lo minimo que debe realizar y salga.

Citar
y...otra...como seria en el caso de que este justo recibiendo por x puerto y se activara la otra interrupcion del otro puerto, cual tendria prioridad?, se puede asignar prioridades a las interrupciones?

Continuando lo de antes tambien respondo esto, el PIC que tenes posee solo 1 vector de interrupcion, 1 sola prioridad, con lo que cuando se activa una interrupcion supongamos de la recepcion de la UART de HW, se deshabilitan las interrupciones de forma global, si a mitad del codigo de interrupcion de la UART RX, ocurre otra interrupcion como la del cambio de nivel de un pin , esta no vuelve al vector, sino espera que se llegue al RETFIE (quien activa las interrupciones ademas de ejecutar un RETURN), y cuando se habilitan de nuevo las interrupciones vuelve a entrar a la interrupcion.

Como crear una especie de prioridad en estos PICs ? es preguntar primero por lo mas importante, suponete que tenemos la interrupcion de cambio de nivel Rb4 a 7 Y la de recepcion de UART HW, esta ultima va a activarse mucho menos que las demas, por que solo entra a la interrupcion cuando TODO el dato llego es decir los 8 bits, mientras que la otra deberia ir bit por bit,  con lo cual me da mas tiempo y me conviene ponerlo al final quedando asi:


Código: [Seleccionar]
Rutina de interrupcion:
              Guardo contexto

              Flag de Rb4 a 7 activo ?
              SI: Voy a la rutina de que atienda esa interrupcion
              Flag de UART RX ?
              SI: Voy a la rutina que atiende esto.

              Devuelvo contexto
              RETFIE

De esa forma si se activan ambas, que se atienda la primera y se salga, o que se atienda la primera y luego pregunte por la segunda.

Citar
leyendo por el foro el tema que me planteas, he visto que dicen que las interrupciones no se llevan muy bien con dos o mas puertos seriales, segun tu conocimiento es asi, o no deberia de darme problema.

Voy a repetirlo una ves mas, todo esto es si es que esperas recibir datos desde MAS de 1 modulo SIN que lo pida el PIC, sino podes hacerlo como estabas haciendolo. Si es uno solo que envia por que si, entonces ponelo en la UART por HW. Los demas no importarian por que en el momento que envias, te quedas esperando por la respuesta.

Si ocurre lo que comente (que mas de 1 modulo puede enviarte mensajes sin que se lo pidas), tu desafio es crear un codigo lo suficientemente rapido que tenga en cuenta ambas entradas que pensas usar de recepcion, y actue en consecuencia para cada una de ellas. Lo recomendable es que la velocidad  de comunicacion no sea muy rapida supongamos 9600 baudios, y que tengas el cristal mas grande que puedas , 20Mhz.

Entonces en tu interrupcion no te vas a poner a ver que letra llego, o hacer cosas "complicadas", simplemente en tu interrupcion lo unico que haces es guardar datos en memoria, y que la rutina principal sea la encargada de cuando tenga tiempo tomar esos datos y usarlos.

En fin, antes de complicarte con esto, asegurate modulo por modulo que jamas te envia algo sin que vos envies algo antes. Que en la mayoria de los casos es asi, y tal ves nos estamos llendo muy lejos y contemplando cosas que no pueden pasar, o que simplemente ni siquiera te puede interesar que es lo que te envia el otro modulo. Yo lo nombre para que lo tengas en cuenta y no como algo que si o si ocurra.

Tal ves decidis que no importa si perdes algun dato, por que pensas preguntar por si llego algo cada 1s por ejemplo y recien alli verificar que hay correctamente siempre y cuando el modulo lo permita.
Asi que lo primero es esto. Asi no complicamos tanto el programa.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 27 de Marzo de 2016, 21:13:51
gracias por la exelente explicacion, me a aclarado muchas cosas.

...lamentablemente la aplicacion que quiero hacer depende de estar a la escucha de los 3 puertos...voy a tratar de hacer uso de mis neuronas y ver que me sale :)
y oviamente seguir jodiendo por aca. :D :D :D

saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 28 de Marzo de 2016, 12:09:07
...que tendria que modificar para correrlo a 20mhz?

saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 28 de Marzo de 2016, 13:38:49
...que tendria que modificar para correrlo a 20mhz?

saludos

Ponerle un cristal de 20Mhz y cambiar el FUSE de XT a HS
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 28 de Marzo de 2016, 20:00:58
No hay que modificar nada mas del codigo? 
Saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 28 de Marzo de 2016, 20:39:54
Los delays tambien, por que los delays estan realizados para cierto valor del cristal. Puede que si usas el timer cuente mas rapido asi que necesitas tenerlo en cuenta. Todo lo dependiente del reloj y que implique tiempos.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 30 de Marzo de 2016, 13:32:31
hola estoy tratando de hacer los dos puertos por sof, para ello lo que hize fue duplicar los .inc obiamente renombrando todo, pero no me funciona uno de ellos, me anda el original pero el que modifique no, pego el codigo haber si esa es la manera o no


Código: [Seleccionar]
  LIST           P=16F877A
    INCLUDE        <P16F877A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _LVP_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK   0x20
   
    TeclaPulsada                       ; Va a guardar el contenido de la tecla pulsada.
    MensajeApuntado                    ; Va a guarda la dirección del mensaje apuntado.
    ENDC

#DEFINE  SalidaAdelante     PORTB,3    ; Define dónde se sitúan las salidas.
#DEFINE  SalidaAtras        PORTB,2
#DEFINE  SalidaIzquierda    PORTB,1
#DEFINE  SalidaDerecha      PORTB,0

TECLA_ADELANTE    EQU    'a'           ; Código de las teclas utilizadas.
TECLA_ATRAS       EQU    's'
TECLA_IZQ         EQU    'd'
TECLA_DER         EQU    'f'
TECLA_PARADA      EQU    ' '           ; Código de la tecla espaciadora, (hay un espacio,
                                       ; tened cuidado al teclear el programa).
CONF_ADCON1     EQU b'00000110' ; Configuracion PORTA E/S digital
; ZONA DE CÓDIGOS ********************************************************************

    ORG    0

movlw 7
movwf CMCON ; CMCON=7 inhibir los comparadores
;**** Configuracion de puertos ****



        bsf STATUS,RP0 ; Ir banco 1
    movlw b'00000000' ; valor  portA
        movwf PORTA
        movlw b'00000000' ; valor  portB 0 SALIDA---1 ENTRADA
        movwf PORTB
        movlw b'00000001'       ; valor  portC
        movwf PORTC
        movlw b'00000001'       ; valor  portD
        movwf PORTD
        movlw b'00000000'       ; valor  portE
        movwf PORTE
        bcf   OPTION_REG,7 ; Pull up habilitadas
        bcf STATUS,RP1

    movlw  CONF_ADCON1 ; Configurar el PORTA como digital
        movwf  ADCON1

       
        bcf STATUS,RP0 ; Ir banco 0
    bcf STATUS,RP1

Inicio
    call    RS232_Inicializa
         call    R232_Inicializa

Principal
     
    call    RS232_LeeDato         ; Espera a recibir un carácter.
    call    TesteaTeclado
         call    R232_LeeDato         ; Espera a recibir un carácter.
    call    TesteaTeclad
    goto    Principal

; "Mensajes" ----------------------------------------------------------------------------
;
Mensajes
    addwf    PCL,F
MensajeParado
    DT "Sistema PARADO", 0x00
MensajeAdelante
    DT "Marcha ADELANTE", 0x00
MensajeAtras
    DT "Marcha ATRAS", 0x00
MensajeIzquierda
    DT "Hacia IZQUIERDA", 0x00
MensajeDerecha
    DT "Hacia DERECHA", 0x00

; Subrutina "TesteaTeclado" -------------------------------------------------------------
;
; Testea el teclado y actúa en consecuencia.

TesteaTeclado
    movwf    TeclaPulsada              ; Guarda el contenido de la tecla pulsada.
    xorlw    TECLA_ADELANTE            ; ¿Es la tecla del movimiento hacia adelante?
    btfsc    STATUS,Z
    goto     Adelante                  ; Sí, se desea movimiento hacia adelante.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_ATRAS               ; ¿Es la tecla del movimiento hacia atrás?
    btfsc    STATUS,Z
    goto     Atras                     ; Sí, se desea movimiento hacia atrás.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_IZQ           ; ¿Es la tecla del movimiento hacia la izquierda?
    btfsc    STATUS,Z
    goto     Izquierda                 ; Sí, se desea movimiento hacia la izquierda.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_DER                 ; ¿Es tecla del movimiento hacia la derecha?
    btfsc    STATUS,Z
    goto     Derecha                   ; Sí, se desea movimiento hacia la derecha.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_PARADA              ; ¿Es la tecla de parada?.
    btfss    STATUS,Z
    goto     Fin                       ; No es ninguna tecla de movimiento. Sale.
Parado
    bcf        SalidaAdelante            ; Como se ha pulsado la tecla de parada se
    bcf        SalidaAtras                ; desactivan todas las salidas.
    bcf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeParado
    goto    Visualiza
Adelante
    bcf        SalidaAtras
    bsf        SalidaAdelante
    bcf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeAdelante
    goto    Visualiza
Atras
    bcf        SalidaAdelante
    bsf        SalidaAtras
    bcf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeAtras
    goto    Visualiza
Izquierda
    bcf        SalidaAdelante
    bcf        SalidaAtras
    bsf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeIzquierda
    goto    Visualiza
Derecha
    bcf        SalidaAdelante
    bcf        SalidaAtras
    bcf        SalidaIzquierda
    bsf        SalidaDerecha
    movlw    MensajeDerecha
    goto    Visualiza

TesteaTeclad
    movwf    TeclaPulsada              ; Guarda el contenido de la tecla pulsada.
    xorlw    TECLA_ADELANTE            ; ¿Es la tecla del movimiento hacia adelante?
    btfsc    STATUS,Z
    goto     Adelant                  ; Sí, se desea movimiento hacia adelante.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_ATRAS               ; ¿Es la tecla del movimiento hacia atrás?
    btfsc    STATUS,Z
    goto     Atra                     ; Sí, se desea movimiento hacia atrás.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_IZQ           ; ¿Es la tecla del movimiento hacia la izquierda?
    btfsc    STATUS,Z
    goto     Izquierd                 ; Sí, se desea movimiento hacia la izquierda.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_DER                 ; ¿Es tecla del movimiento hacia la derecha?
    btfsc    STATUS,Z
    goto     Derech                   ; Sí, se desea movimiento hacia la derecha.
;
    movf     TeclaPulsada,W            ; Recupera el contenido de la tecla pulsada.
    xorlw    TECLA_PARADA              ; ¿Es la tecla de parada?.
    btfss    STATUS,Z
    goto     Fin                       ; No es ninguna tecla de movimiento. Sale.

Adelant
    bcf        SalidaAtras
    bsf        SalidaAdelante
    bcf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeAdelante
    goto    Visualiz
Atra
    bcf        SalidaAdelante
    bsf        SalidaAtras
    bcf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeAtras
    goto    Visualiz
Izquierd
    bcf        SalidaAdelante
    bcf        SalidaAtras
    bsf        SalidaIzquierda
    bcf        SalidaDerecha
    movlw    MensajeIzquierda
    goto    Visualiz
Derech
    bcf        SalidaAdelante
    bcf        SalidaAtras
    bcf        SalidaIzquierda
    bsf        SalidaDerecha
    movlw    MensajeDerecha
    goto    Visualiz
; Según el estado de las salidas visualiza el estado del sistema en el visualizador LCD y en
; el monitor del ordenador.

Visualiza
    movwf    MensajeApuntado            ; Guarda la posición del mensaje.
    movf    MensajeApuntado,W
    call    RS232_Mensaje            ; Lo visualiza en el HyperTerminal.
    return
Visualiz
    movwf    MensajeApuntado            ; Guarda la posición del mensaje.
    movf    MensajeApuntado,W
    call    R232_Mensaje            ; Lo visualiza en el HyperTerminal.

Fin    return

    INCLUDE  <RS232.INC>
    INCLUDE  <RETARDOS.INC>
    INCLUDE  <RS232MEN.INC>
    INCLUDE  <RS232a.INC>
    INCLUDE  <RS232MENa.INC>
        END


sigo probando a 4Mhz

saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 30 de Marzo de 2016, 23:03:53
No baje todas, solamente rs232 y r232, el cambio de todo es correcto creo, tampoco me puse a ver instruccion por instruccion.

Pero nuevamente tenes problemas con el inicio de los CBLOCK, al menos es lo que vi en esos 2 archivos.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 31 de Marzo de 2016, 12:09:37
ya lo modifique, pero sigue sin funcionar...
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 31 de Marzo de 2016, 13:04:51
si me funciona de forma independiente pero no los dos a la ves
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 31 de Marzo de 2016, 18:52:07
si me funciona de forma independiente pero no los dos a la ves

Y te lo dije.. Mientras uno esta recibiendo se queda encerrado en RS232.xxxxx como se llame hasta recibir la trama por completo, entonces no se esta ejecutando RS32.xxxx, Lo cual es imposible que ambos funcionen los 2 a la ves, Y ya te presente algunas soluciones. Como usar interrupciones y una maquina de estado para cada uno de las entradas.
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: kapotik en 31 de Marzo de 2016, 19:46:13
No, cuando digo que me funciona independientemente me refiero a que solo esta  programado un solo puerto, ahora cuando programo el pic para que tenga dos puertos seriales no funciona ninguno, ni siquiera recibe una vez ni nada  muerto

Saludos
Título: Re:comunicacion serial por sof en 16f877a
Publicado por: KILLERJC en 31 de Marzo de 2016, 22:33:26
Luego de mirar un poquito mas el codigo, no veo el por que no te pueden funcionar ambos. Lo que si tenes un "orden" para enviar las cosas.


Código: ASM
  1. RS232_EsperaBitStart
  2.                 btfsc   RS232_Entrada           ; Lee la entrada y espera a que sea "0".
  3.                 goto    RS232_EsperaBitStart    ; No, pues espera el nivel bajo.

Ya que eso se queda para siempre alli esperando que la entrada se ponga en 0, primero tenes que enviar al PORTD,0 un byte,finalizado ese byte es el turno del PORTC,0 el cual recibira otro byte entero y volver al PORTD,0 , mientras este uno esperando el dato el otro no va a funcionar jamas.

Intentaria quitar lo de enviar datos por ahora, y dejar las salidas con leds para saber cuando es que se activa o no.


Otro tema

Otra cosa mas que no le preste atencion es tu programa, por que dijiste que independientemente funcionaban, entonces no le preste atencion, pero ahora si:

Código: ASM
  1. movlw 7
  2.         movwf CMCON             ; CMCON=7 inhibir los comparadores

eso es del banco1 y lo estas haciendo al comienzo apuntando al banco 0.

Aunque funciona vos no estas modificando los PORTx sino los TRISx, por suerte MCHP los puso en el mismo lugar si tomas los 8bits mas bajos:

Código: ASM
  1. bsf STATUS,RP0          ; Ir banco 1
  2.         movlw b'00000000'       ; valor  portA
  3.         movwf PORTA
  4.         movlw b'00000000'       ; valor  portB                  0 SALIDA---1 ENTRADA
  5.         movwf PORTB
  6.         movlw b'00000001'       ; valor  portC
  7.         movwf PORTC
  8.         movlw b'00000001'       ; valor  portD
  9.         movwf PORTD
  10.         movlw b'00000000'       ; valor  portE
  11.         movwf PORTE

Por

Código: ASM
  1. bsf STATUS,RP0          ; Ir banco 1
  2.         movlw b'00000000'       ; valor  portA
  3.         movwf TRISA
  4.         movlw b'00000000'       ; valor  portB                  0 SALIDA---1 ENTRADA
  5.         movwf TRISB
  6.         movlw b'00000001'       ; valor  portC
  7.         movwf TRISC
  8.         movlw b'00000001'       ; valor  portD
  9.         movwf TRISD
  10.         movlw b'00000000'       ; valor  portE
  11.         movwf TRISE

Aunque funciona es un concepto equivocado.