SoloCodigo
		Programación Específica => Microcontroladores => Mensaje iniciado por: Pegasux en Lunes 22 de Diciembre de 2008, 12:47
		
			
			- 
				Muy buenas. Tengo un dispositivo con un 16F876 en el que he desarrollado dos codigos, uno consiste en manejar teclado y pantalla, esto me funciona bien, el otro consiste en enviar unos datos sencillos por el puerto serie, tambien me funciona bien, pero cuando junto los codigos, osea, primero pido los datos y luego intento enviarlos, la parte de pedirlos funciona bien, pero la parte de enviarlos funciona mal, el caso es que por separado todo funciona bien y si lo junto deja de funcionar. He probado a modificar los valores de los registros principales y reescribirlos con los datos que habia al principio, para hacer como una especie de "reset" en caliente, pero sigue igual, creo que una solucion seria conseguir una especie de reset en caliente sin que pierda los datos de la ram y que la parte de enviar funcione como cuando esta sola. No es que sea una solucion muy buena, pero no se me ocurre otra cosa, y haciendolo como creo que deberia ser no funciona. ¿Alguien puede ayudarme?
 
 Gracias y un saludo.
- 
				Buenas tardes Pegasux, serias tan amable de subir tu codigo?, unificado, tal como lo tienes y no funciona, puede aver algun inconveniente de variables o algo que se esta pasando por alto, si subes el codigo lo puedo revisar y darte una mano para encontrar el inconveniente. Un Abrazo y Felicidades para estas fiestas!!  :beer:
			
- 
				Muchas gracias por tu respuesta, Jonathan, y felices fiestas a ti y a todos los del foro!! El tema va por lo que tu dices, he descubierto que si meto un valor erroneo a proposito, sale el tipico mensaje de error y vuelve a pedir el mismo dato, pero entonces la parte de la transmision funciona bien, luego alguna variable tiene que haber por ahi que falla....
 
 Un saludo muy gordo.
- 
				Gracias por los saludos!.. en este 2009 tengo pensado subir un par de proyectos al foro!.. asi empezamos el año nuevo con todo!... 
 El tema seguro es con variables, mas aun analizando la prueba que hiciste.. revisa bien las variables y direccion de memorias, si no encuentras el problema subis el codigo y vemos... voy a estar atento. Un abrazo! Feliz navidad! :beer:
- 
				Muchas gracias de nuevo, Jonathan!! Pues me he pasado ayer toda la tarde revisando y no encuentro nada, las variables de memoria las declaro todas seguidas en el programa principal. Lo que si he observado es que si introduzco los valores por teclado muy rapido funciona bien, pero si los introduzco a una velocidad normal ya va mal... no se si esto servira de algo, asi que voy a colgar el codigo, es bastante extenso, pero puede que otros ojos lo vean mejor que los mios..  Hay subrutinas que no pongo porque es evidente lo que hacen y ocuparia mucho mas el codigo:
 
 
 ;      ZONA DE DATOS
 
 GUARDA_W   EQU   0X20         ; variables para guardar los registros
 GUARDA_S   EQU 0X21
 GUARDA_FSR   EQU   0X22
 
 
 PDel0      EQU   0x24
 PDel1      EQU   0x25
 PDel2      EQU   0x26
 
 R_ContA      EQU   0x27            ; Contadores para los retardos.
 R_ContB      EQU   0x28
 R_ContC      EQU   0x29
 
 ASCII_H      EQU   0x2A
 ASCII_M      EQU   0x2B
 ASCII_L      EQU   0x2C
 HEXADECIMAL   EQU   0x2D
 HEXADECIMAL_X   EQU   0X2E
 ASCII1      EQU   0X2F
 ASCII2      EQU   0X30
 
 INNER      EQU   0x31      ;delay variable mS
 OUTER      EQU   0x32      ;delay variable mS
 Digito      EQU   0x33
 
 
 CBLOCK   0X40   ; aqui esta el status de lo enviado
 startdelimiterst
 lenght_hst
 lenght_lst
 apiidentifierst      ; desde aqui se calcula el checksum
 frameidst            ;
 statusst      ; (ack/nack)
 checksumst
 FF
 CHECK
 ENDC
 
 
 CBLOCK   0X50   ; aqui estan los datos enviados
 startdelimitertx
 lenght_htx
 lenght_ltx
 apiidentifiertx      ; desde aqui se calcula el checksum
 frameid            ;
 address_htx         ;
 address_ltx         ;   CHECKSUM
 optionstx         ;
 dato1tx            ;
 dato2tx            ; hasta aqui
 checksumtx
 datotx
 rc_reg         ; 0x5C
 ENDC
 
 
 
 CBLOCK   0x5F   ; aqui estaran los datos recibidos
 counter
 startdelimiter
 lenght_h
 lenght_l
 apiidentifier
 saddress_h
 saddress_l
 rssi
 options
 dato1
 dato2
 checksum
 cuenta_timer1            ; 0x5B
 posicion_cursor
 ENDC
 
 CBLOCK 0x6E
 TEMPORAL
 CONTADOR      ; todo esto sirve para los comandos AT
 MEMORIA
 MEMORIA2
 MEMORIA3
 MEMORIA4
 MEMORIA5
 MEMORIA6
 teclapulsada   ; almacena la tecla actual pulsada
 pulsaciones      ; pulsaciones que quedan para finalizar
 centenas
 decenas
 unidades
 velocidad      ; velocidad en hexadecimal
 tipo         ; tipo
 circ         ; circunstancia
 flujo         ; sirve para saber en que punto nos encontramos
 
 ENDC
 
 
 processor 16F876
 
 LIST   P=16F876   ;Se indica el modo de procesador
 
 INCLUDE   <P16f876.inc>   ;se incluye la definicion de los
 ;registros internos
 
 
 
 __config 3D31
 
 
 
 ;----------------------------------------------------------------------------
 
 
 org    0x00      ;vector de inicio
 goto    INICIO
 
 
 org    0x04      ;despues del vector de interrupcion
 goto   ServicioInterrupcion
 
 
 
 
 ;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
 ;----------------------------------------------------------------------------
 
 INICIO
 
 call   configura_micro
 
 call    inicializa_lcd
 
 call   MuestraBien
 
 call   PDelay      ; retardo de 2 segundos
 
 otratipo
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 
 call   PideTipo
 
 movlw   0x01
 movwf   pulsaciones      ; inicializamos pulsaciones maximas
 
 clrf   flujo      ; esta en tipo --> flujo=0
 
 movlw   0xFF      ; ponemos a algo distinto de 0
 movfw   centenas
 movfw   decenas
 movfw   unidades
 
 otra
 call    Teclado_Inicializa
 
 call   Habilita_Int_Teclado
 
 sleep
 
 ; mira si tiene que volver a dormir o no
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otratipo      ; si, borra
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    fintipo      ; si, pasa a lo siguiente
 
 call   Retardo_100ms
 goto otra
 
 fintipo
 
 ;********************************************************************
 
 otravel
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 call   PideVel
 
 movlw   0x03
 movwf   pulsaciones      ; inicializamos pulsaciones maximas
 
 movlw   0x01
 movwf   flujo         ; esta en velocidad --> flujo=1
 clrf   centenas
 clrf   decenas
 clrf   unidades
 
 call   Cursor_on
 otra2
 call    Teclado_Inicializa
 
 call   Habilita_Int_Teclado
 
 sleep
 
 ; mira si tiene que volver a dormir o no
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otravel      ; si, borra
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    FinVel      ; si, va a calcular
 
 
 call   Retardo_100ms
 goto    otra2
 
 FinVel
 
 ; metemos el valor de la velocidad en dato1tx
 
 
 movfw   velocidad
 movwf   dato1tx
 
 
 ;********************************************************************
 
 otracirc
 
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 call   PideCirc
 
 movlw   0x01
 movwf   pulsaciones      ; inicializamos pulsaciones maximas
 
 movlw   0x02
 movwf   flujo      ; esta en circunstancia --> flujo=2
 
 movlw   0xFF
 movwf   centenas
 movwf   decenas
 movwf   unidades   ; para que sea erroneo si no se mete nada
 
 call   Cursor_on
 otra3
 call    Teclado_Inicializa
 
 call   Habilita_Int_Teclado
 
 sleep
 
 ; mira si tiene que volver a dormir o no
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otracirc      ; si, borra
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    FinCirc      ; si, va a calcular
 
 
 call   Retardo_100ms
 goto    otra3
 
 
 FinCirc
 
 
 call   montadato2tx
 
 ;*******************************************************************
 ;*******************************************************************
 ;*******************************************************************
 ;*******************************************************************
 ;
 ; ya esta todo metido, nos preparamos para transmitir
 ;
 
 call   configura_micro
 
 ;**************************
 
 call   Borra_home
 
 call    INITX         ; inicializamos la transmision
 
 call   SET125K         ; micro a 125Kbps
 
 retransmitir
 
 movlw   0X40         ; dirección de memoria RAM a escribir.
 movwf   counter         ; el TX STATUS que manda el Xbee
 
 call   BORRAAPIST
 
 call   RX            ; nos preparamos para recibir por interrupciones
 
 call   APITX
 
 call   Retardo_10ms   ; tiempo reducido al maximo
 
 call   MUESTRAAPIST
 
 
 LeeVelocidad
 
 banksel   PORTA
 bcf     PORTA,2         ;Desactiva LCD
 
 call   LeeTecla
 movwf   teclapulsada
 
 bsf   STATUS,RP0   ;banco 1
 
 movlw   b'00000000'         ; deshabilita interrupciones
 movwf   INTCON
 
 bcf         STATUS,RP0      ; banco 0
 
 ;*******************************************************
 ; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
 
 ; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
 ; antes de calcular el valor de la velocidad en hexadecimal
 
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otravel         ; si, repite
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    calcular_vel      ; si, va a calcular
 
 ; no es ni A ni B
 ; almacena lo tecleado
 ;
 goto    continuavel   ; esta bien, continua
 
 error_vel
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 call   Cursor_off
 call    MensVelInc
 call   PDelay      ; retardo 2 segundos
 
 goto otravel   ; vuelve a pedir la velocidad
 
 
 continuavel
 decf   pulsaciones
 
 movlw   0x02
 subwf   pulsaciones,0      ; es centenas?
 btfsc   STATUS,Z         ;
 goto    mete_centenas      ; si, lo guarda
 
 
 movlw   0x01
 subwf   pulsaciones,0      ; es decenas?
 btfsc   STATUS,Z         ;
 goto    mete_decenas      ; si, lo guarda
 
 
 movlw   0x00
 subwf   pulsaciones,0      ; es unidades?
 btfsc   STATUS,Z         ;
 goto    mete_unidades      ; si, lo guarda
 
 ; si llega aqui es que se ha pasado, no hace nada y
 ; espera a que se  pulse A o B
 
 goto finesperavel
 
 mete_centenas
 movfw   teclapulsada
 movwf   centenas
 
 goto fincalcula
 
 mete_decenas
 movfw   teclapulsada
 movwf   decenas
 
 goto fincalcula
 
 mete_unidades
 movfw   teclapulsada
 movwf   unidades
 
 goto fincalcula
 
 calcular_vel      ; llega aqui si se pulsa B
 ; aqui mira si son 1, 2 o 3 digitos pulsados y organiza los datos
 ; si pulsaciones es 0 es que ha metido 3 datos, si es 1 ha metido 2 datos
 
 
 movlw   0x00
 subwf   pulsaciones,0   ; pulsaciones-0=pulsaciones --> afecta al flag Z
 btfsc   STATUS,Z         ; ha metido 3 digitos?
 goto    bienmetido         ; si, esta bien ordenado
 ; no, hay que reordenar los 2 datos
 
 movlw   0x01         ; ha metido 2?
 subwf   pulsaciones,0   ;
 btfss   STATUS,Z         ; ha metido 2 digitos?
 goto    error_vel         ; no, esta mal
 
 ; si, hay que ordenarlos
 movfw   decenas
 movwf   unidades
 
 movfw   centenas
 movwf   decenas      ; ya esta ordenado
 clrf   centenas   ; centenas tiene que ser 0
 
 bienmetido   ; a partir de aqui hay que pasar los 3 bytes a un solo valor
 clrf   velocidad
 ;   centenas
 movlw   0x00
 subwf   centenas,0      ; centenas-0 --> afecta al flag Z
 btfsc   STATUS,Z      ; centenas es 0?
 goto   metedecenas      ; si, centenas es 0
 ; no, centenas no es 0
 movlw   d'100'
 addwf   velocidad         ; valor+100
 
 metedecenas   ; multiplica las decenas por 10 (bucle)
 movlw   0x0B
 movwf   TEMPORAL   ; reutilizo esta variable como contador
 bucle
 decf   TEMPORAL
 btfsc   STATUS,Z      ; es 0?
 goto    meteunidades   ; si, guarda el resultado
 
 ; no, sigue en el bucle
 movfw   decenas
 addwf   velocidad,1         ; decenas+decenas
 goto    bucle
 
 ; ya esta almacenado en valor
 
 meteunidades   ; solamente hay que sumar las unidades
 
 movfw   unidades
 addwf   velocidad,1
 
 
 ;   en valor tenemos el resultado de la velocidad en hexadecimal
 ;    si es mayor de 120 esta mal
 
 movlw   0x79         ; 121
 subwf   velocidad,0      ; velocidad-121 = negativo
 btfsc   STATUS,C      ; si C=0 es negativo --> salta
 goto    error_vel      ; la velocidad esta mal --> repetir
 
 movlw   0xA            ; 10
 subwf   velocidad,0      ; velocidad-10 = negativo
 btfss   STATUS,C      ; si C=1 es positivo --> bien
 goto    error_vel      ; si C=0 es negativo --> error
 
 ; la velocidad esta bien
 
 goto   finesperavel
 
 ;****************************************************
 fincalcula
 
 movfw   teclapulsada
 call   hextoascii
 movfw   ASCII2
 call    LCD_DATOS       ; Visualiza caracter
 finesperavel
 return
 
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 
 LeeTipo
 
 banksel   PORTA
 bcf     PORTA,2         ; Desactiva LCD
 
 call   LeeTecla
 movwf   teclapulsada   ; guardamos la tecla pulsada
 
 bsf   STATUS,RP0   ;banco 1
 
 movlw   b'00000000'         ; deshabilita interrupciones
 movwf   INTCON
 
 bcf         STATUS,RP0      ; banco 0
 
 ;*******************************************************
 ; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
 
 ; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
 ; antes de calcular el valor de la velocidad en hexadecimal
 
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otratipo      ; si
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    mete_unidades_tipo      ; si
 
 ; no es ni A ni B
 ; almacena lo tecleado
 
 decf   pulsaciones
 
 movlw   0x00
 subwf   pulsaciones,0      ; es unidades?
 btfss   STATUS,Z         ;
 goto    finespera_tipo      ; no, no hace nada
 
 movfw   teclapulsada   ; si
 movwf   unidades      ; guarda unidades
 
 goto fincalcula_tipo   ; pinta la letra y vuelve al sleep
 
 
 mete_unidades_tipo    ; llega aqui si pulsa correctamente B
 ; solo puede haber 1 digito, 0, 1 o 2
 
 movlw   0x01
 subwf   pulsaciones,0      ; ha pulsado solo B?
 btfsc   STATUS,Z         ; si, Z estara a 1
 goto    error_tipo      ; no, no hace nada
 
 movlw   0x03   ; comprueba si es mayor de 2
 subwf   unidades,0   ; unidades-3 = negativo
 btfsc   STATUS,C   ; si C=0 es negativo --> salta
 goto    error_tipo   ; el tipo esta mal --> repetir tipo
 
 movfw   unidades   ; el tipo esta bien, lo almacena
 movwf   tipo      ; en tipo
 
 goto    finespera_tipo
 
 
 
 error_tipo
 
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 call   Cursor_off
 call    MensTipoInc
 call   PDelay      ; retardo 2 segundos
 
 ;            call   Borra_home
 
 goto otratipo   ; vuelve a pedir el tipo
 
 ;****************************************************
 fincalcula_tipo
 
 movfw   teclapulsada
 call   hextoascii
 bsf     PORTA,2         ; activa LCD
 movfw   ASCII2
 call    LCD_DATOS       ; Visualiza caracter
 finespera_tipo
 
 return
 
 ;************************************************************************
 
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 ;************************************************************************
 
 LeeCirc
 
 banksel   PORTA
 bcf     PORTA,2         ;Desactiva LCD
 
 call   LeeTecla
 movwf   teclapulsada   ; guardamos la tecla pulsada
 
 bsf   STATUS,RP0   ;banco 1
 
 movlw   b'00000000'         ; deshabilita interrupciones
 movwf   INTCON
 
 bcf         STATUS,RP0      ; banco 0
 
 ;*******************************************************
 ; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
 
 ; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
 ; antes de calcular el valor de la velocidad en hexadecimal
 
 movlw   0x0A
 subwf   teclapulsada,0      ; es A?
 btfsc   STATUS,Z         ;
 goto    otracirc      ; si
 
 movlw   0x0B
 subwf   teclapulsada,0      ; es B?
 btfsc   STATUS,Z         ;
 goto    mete_unidades_circ      ; si
 
 ; no es ni A ni B
 ; almacena lo tecleado
 
 decf   pulsaciones
 
 movlw   0x00
 subwf   pulsaciones,0      ; es unidades?
 btfss   STATUS,Z         ;
 goto    finespera_circ      ; no, no hace nada
 
 movfw   teclapulsada   ; si
 movwf   unidades      ; guarda unidades
 
 goto fincalcula_circ   ; pinta la letra y vuelve al sleep
 
 
 mete_unidades_circ    ; llega aqui si pulsa correctamente A o B
 ; solo puede haber 1 digito, 0, 1 o 2
 
 movlw   0x0A   ; comprueba si es mayor de 9
 subwf   unidades,0   ;unidades-A = negativo
 btfsc   STATUS,C   ; si C=0 es negativo --> salta
 goto    error_circ   ; el tipo esta mal --> repetir mensaje
 
 movfw   unidades   ; el tipo esta bien, lo almacena
 movwf   circ      ; en tipo
 
 goto    finespera_circ
 
 
 error_circ
 
 call   Borra_home
 movlw   0x80            ;Direccion caracter
 call    LCD_REG
 call   Cursor_off
 call    MensCircInc
 call   PDelay      ; retardo 2 segundos
 
 call   Borra_home
 
 goto otracirc   ; vuelve a pedir el tipo
 
 ;****************************************************
 fincalcula_circ
 
 movfw   teclapulsada
 call   hextoascii
 bsf     PORTA,2         ; activa LCD
 movfw   ASCII2
 call    LCD_DATOS       ; Visualiza caracter
 
 finespera_circ
 
 return
 
 ;************************************************************************
 
 
 ServicioInterrupcion
 
 ;   GUARDAR WREG, STATUS, FSR EN LA PILA
 
 
 MOVWF   GUARDA_W
 SWAPF   STATUS,W
 MOVWF   GUARDA_S
 SWAPF    FSR,W
 MOVWF   GUARDA_FSR
 
 bcf         STATUS,RP0      ; banco 0
 
 btfss      PIR1,RCIF      ; ha sido por recepcion?
 goto       otras          ; no, mira otras interrupciones
 
 bcf         PIR1,RCIF      ; si, borra el bit de aviso
 
 ; escribimos en ram con direccionamiento indirecto
 
 call   escribeindir      ; pinta en pantalla lo recibido
 
 goto    finirq
 
 otras      ; aqui ponemos las otras interrupciones   (teclado)
 
 bcf   STATUS,RP0   ;banco 0
 
 movlw   0x00
 subwf   flujo,0         ; mira a ver si es 0
 btfsc   STATUS,Z      ; si es velocidad (1) o circunstancia (2), salta
 goto    estaentipo
 
 movlw   0x01
 subwf   flujo,0         ; mira a ver si es 1
 btfss   STATUS,Z      ; si es velocidad (1), salta
 goto    estaencirc
 
 goto   estaenvel
 
 estaentipo
 call   LeeTipo
 goto    finirq
 
 estaenvel
 call     LeeVelocidad
 goto    finirq
 
 estaencirc
 call   LeeCirc
 
 goto    finirq
 
 
 finirq
 
 ; RECUPERAMOS DE LA PILA
 
 MOVF   GUARDA_FSR,W
 MOVWF FSR
 SWAPF GUARDA_S,W
 MOVWF STATUS
 SWAPF   GUARDA_W,W
 
 retfie
 
 
 
 INCLUDE <MENSAJES_P.INC>
 INCLUDE <MICRO.INC>
 INCLUDE <CONVIERTE.INC>
 INCLUDE <LCD.INC>
 INCLUDE <RETARDOS.INC>
 INCLUDE <COMUNICACION.INC>
 INCLUDE <TECLADO_3X4.INC>
 INCLUDE <API.INC>
 INCLUDE <AT.INC>
 
 
 END