Autor Tema: Problema a la hora de comunicar por Puerto SERIE (UART)  (Leído 1565 veces)

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

Desconectado pchevriere

  • PIC10
  • *
  • Mensajes: 1
Problema a la hora de comunicar por Puerto SERIE (UART)
« en: 11 de Noviembre de 2009, 10:41:47 »
Hola a todos y gracias de antemano.

Estoy programando un PIC16F628A para controlar la maqueta de un pequeño ascensor desde el PC.

Desde el PC le envío uno de los siguientes caracteres para que entienda lo siguiente:
A - Activar el sistema.
P - Parar el sistema.
D - Para que el PIC envíe el estado de sus entradas y salidas (PORTA y PORTB).

Las dos primeras funciones las entiende y las cumple perfectamente, pero la última (D) sólo la ejecuta cuando el sistema está parado. Cuando está activo parece que ni siquiera entra en la interrupción.

Les dejo la parte del código a ver si detectan algún fallo y me pueden echar un cable.

Gracias de antemano.



;****************************************************************************************   
;**                        DECLARACIONES E INICIO DEL PROGRAMA                                                           **
;****************************************************************************************

INCLUDE      <P16F628A.INC>
LIST      P=16f628A       ;Procesador utilizado.
LIST      R=hex           ;Trabajo en numeracion hexadecimal.
__CONFIG    _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF





;*********************************   MAPA DE MEMORIA   **********************************
dato          equ   0x24
activo   equ    0x25
A              equ   0x26
P              equ   0x27
D              equ   0x28

CBLOCK   0x29
   W_Temp         ;guarda el valor del WREG durante la interrupción.
   Status_Temp      ;guarda el valor del STATUS durante la interrupción.
   Pclath_Temp      ;guarda el valor del PCLATH (Program counter) durante la int.
ENDC




;*************************************   INICIO   ***************************************
                                       
reset         ORG    0x00        ; El programa comienza en la dirección 0.
      GOTO    inicio        

      ORG      0x04        ; Cuando se da una interrupción, vamos a la rutina RSI
      GOTO   RSI          ; (RUTINA DE SERVICIO DE INTERRUPCIÓN)
                                                   
      ORG 0x05
      inicio


;************************************   CONFIGURACIONES   ***********************************


;.......1. Configuración de puertos I/O.................................... ..................
   Bank1                             ; Cambiamos al banco 1 de memoria.   
        MOVLW   b'11000011'     ; 4 entradas (RA1, RA0, RA7 Y RA6 = pulsadores de llamada),
   MOVWF   TRISA             
       


        MOVLW   b'11110010'    ; 4 entradas (Sensores REED)
      MOVWF   TRISB         ; 2 salidas (RB3 no se usará, RB2 se usará como TX)
                     
      Bank0                 ; Cambiamos al banco 0 de memoria.     

      MOVLW    b'11111111'    ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
      MOVWF    PORTA
      MOVLW    b'11111001'    ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
      MOVWF    PORTB
       
      BCF    PORTA,2         ;paro el motor hacia abajo
                BCF    PORTA,3         ;paro el motor hacia arriba


;[...]

;.......3. Habilitamos las interrupciones ....................................................

      BSF      INTCON,GIE       ; Habilitamos permiso global de las interrupciones.
      BSF      INTCON,PEIE       ; Que sean interrupciones para periféricos no controlados con INTCON.
      
      Bank1            ; Cambiamos al BANCO 1.
      BSF      PIE1, RCIE      ; Habilitamos las interrupciones para RECEPCIÓN DE DATOS.
      Bank0            ; Volvemos al BANCO 0.


;.......4. Configuración de la conexión serial................................................
   
      Bank1           ; Cambiamos al BANCO 1.
      BCF    TRISB,2           ; Configura el pin RB2 (TX) como salida
      BSF    TRISB,1           ; Configura el pin RB1 (RX) como entrada
      Bank0                        ; Volvemos al BANCO 0.

      BSF      RCSTA,SPEN       ; Habilita el puerto serial
      BSF      RCSTA,CREN       ; Enable continuous reception

      Bank1                   ; Cambiamos al banco 1 de memoria.   
      BSF      TXSTA,TXEN       ; Enable transmit
      BSF      TXSTA,BRGH       ; Select high baud rate
                         ; Trabajamos a 4 Mhz y 9600 bauds -> 25,
                         ; (Si fuera 2400 bauds -> 103)
      MOVLW   .25             ; 9600 baud @ 4 MHz
      MOVWF   SPBRG   
      Bank0                   ; Volvemos al  banco 0 de memoria.


;.......5. Inicialización de registros .......................................................   

      CLRF   activo          ;inicialmente mantenemos inactivo el proceso.
      
      MOVLW   0x41          ;Asignamos al registro A su valor en Hexadecimal (ASCII).
      MOVWF   A

      MOVLW   0x50          ;Asignamos al registro P su valor en Hexadecimal (ASCII).
      MOVWF   P

      MOVLW   0x44          ;Asignamos al registro D su valor en Hexadecimal (ASCII).
      MOVWF   D

;*******************************************************************   
;**                                   RUTINA PRINCIPAL                                 **
;*******************************************************************


principio nop
    
   BTFSS    activo,1   ;salta la siguiente linea si se solicita activar el proceso.
    GOTO     parada     ;si no, esperamos.

;[...]

GOTO principio


;***********************************************************
;**                               RUTINA DE PARADA                                    **
;***********************************************************

;Esta subrutina inicializa los puertos I/O para parar el sistema

parada   nop
      MOVLW    b'11111111'    ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
      MOVWF    PORTA
      MOVLW    b'11111111'    ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
      MOVWF    PORTB
       
      BCF    PORTA,2          ;paro el motor hacia abajo
        BCF    PORTA,3          ;paro el motor hacia arriba
      GOTO principio


;=========================================================================
;==                              RUTINA DE ATENCIÓN A LA INTERRUPCIÓN                                                              ==
;==                                        "RECEPCIÓN DE DATOS"                                                                               ==
;=========================================================================
   
;   Creamos una rutina que se encargue de recibir los datos de la UART.

RSI:   
;.........................................................................................
;             1. Guardamos la configuración del sistema para dejarla como estaba       
;                          antes de la interrupción                        
                                                                                 
      MOVWF   W_Temp          ; Guarda el valor de W en W_Temp                       
      MOVF   STATUS,W      ; Guarda el valor de STATUS en W                       
      MOVWF   Status_Temp      ; Guarda el valor de STATUS en Status_Temp         
      MOVF   PCLATH,W      ; Guarda PCLATH en WREG                           
      MOVWF   Pclath_Temp      ; Guarda el valor de PCLATH                     
      CLRF   PCLATH         ; Selecciona el PC en la pos 0                     
;.........................................................................................
      
;.......2. Comprobamos que la interrupción fue correcta...................................   
      Bank0               ; Nos colocamos en eL banco 0, por si a caso.
      BTFSS   PIR1,RCIF      ; ¿la interrupción ha sido provocada por RECEPCIÓN UART?
      GOTO   FIN_RSI         ; Si es que si, saltamos la linea y la atendemos.
                        ; Si no, vamos al final.

;.......3. Rescatamos el dato que recibimos................................................                           
      MOVF    RCREG,W       ; si hay dato, lo movemos a W y
      MOVWF    dato          ; luego lo guardamos en "dato"


;.......4. Enviamos lo recibido............................................................   
      Bank1               ; Cambiamos al BANCO 1                
      EsperaUart      
      BTFSS    TXSTA,TRMT      ; Testeamos hasta que el registro de transmisión       
      GOTO    EsperaUart      ; quede libre.
      Bank0               ; Volvemos al BANCO 0
 
      MOVF   dato,W        
      MOVWF   TXREG         ; Enviar lo que hay en W por la UART
;..........................................................................................

;.......5. Observamos qué es lo que se solicita............................................   
      SUBWF   A,0            ; Si la letra recibida por UART es A --> Activamos el proceso.
      BTFSC   STATUS,Z
      BSF      activo,1

      MOVF    dato,W
      SUBWF   P,0            ; Si la letra recibida por UART es P --> Paramos el proceso
      BTFSC   STATUS,Z
      BCF      activo,1

      MOVF    dato,W
      SUBWF   D,0            ; Si la letra recibida por UART es D --> Enviamos datos
      BTFSS   STATUS,Z
      GOTO   FIN_RSI         ; Si no, vamos al final de la RSI.


      ;ENVIAMOS DATOS  ****************************************************************
      
            ;.......... Primero enviamos CABECERA ('H')........................
            Bank1               ; Cambiamos al BANCO 1                
            EsperaUartH      
            BTFSS    TXSTA,TRMT      ; Testeamos hasta que el registro de transmisión       
            GOTO    EsperaUartH      ; quede libre.
            Bank0               ; Volvemos al BANCO 0
      
            MOVLW   0x48           ; Mueve el valor 48hex (H) al acumulador.
            MOVWF   TXREG         ; Enviar lo que hay en W por la UART
            ;..................................................................   
      
      
            ;............... Enviamos el PORTA ................................
             Bank1               ;Cambiamos al BANCO 1
            EsperaUart1
            BTFSS    TXSTA,1         ; Testeamos hasta que el registro de transmisión       
            GOTO    EsperaUart1      ; quede libre.
            Bank0               ; Volvemos al BANCO 0
      
            MOVF   PORTA,0         ; Mueve el estado del PORTA al W.
            MOVWF   TXREG         ; Enviar lo que hay en W por la UART
            ;..................................................................   
      
            ;................ Luego enviamos el PORTB ......................

            Bank1      ;Cambiamos al BANCO 1                   
             EsperaUart2            
            BTFSS    TXSTA,1;       Testeamos hasta que el registro de transmisión       
            GOTO    EsperaUart2      ; quede libre.
            Bank0      ; Volvemos al BANCO 0
      
            MOVF   PORTB,0         ; Mueve el estado del PORTB al W.
            MOVWF   TXREG         ; Enviar lo que hay en W por la UART
            ;..................................................................   

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

FIN_RSI
      
         Bank0            
         MOVF   Pclath_Temp,W      ;devolvemos el valor anterior del PCLATH
         MOVWF   PCLATH            
         MOVF   Status_Temp,W      ;devolvemos el valor anterior del STATUS
         MOVWF   STATUS            
         SWAPF   W_Temp,F         ;devolvemos el valor anterior del WREG
         SWAPF   W_Temp,W               

         BCF      PIR1,RCIF         ; Limpio la bandera de la interrupción del UART
         RETFIE               ;Regresamos

;========================================================================================