Autor Tema: Problema comunicacion rs232  (Leído 2141 veces)

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

Desconectado lluiset

  • PIC10
  • *
  • Mensajes: 3
Problema comunicacion rs232
« en: 29 de Marzo de 2005, 16:21:00 »

Buenas este es mi primer post y espero ir no muy a saco con la pregunta.
Veamos estoy intentando comunicar un pic16f873a con el PC, el pc le envia una trama de 4 bytes al micro para que empiece a capturar por el ADC y este cuando acaba le responde al pc con una trama de 7 bytes.El programa de comunicacion esta hecho en visualbasic y va bien pq midiendo directamente en el puerto del pc con el oscilo se ven los bytes perfectamente y ademas he metido un sniffer del puerto serie que me saca perfectos tb los 4 bytes de la trama.El problema es,que el micro solo recibe el primer byte, de los otros ni se inmuta.he usado interrupciones, he salvado los registros usados antes de la int,velocidad 9600( lo tipico) lo he repasado mil veces, para que no haya overrun me he creado dos buffers, uno de recepcion y otro de transmision , no se que puede pasar y ya me estoy volviendo loco, aqui os pego el codigo bien comentado por si alguien le echa un vistazo y encuentra algo raro,Gracias





**********************************************************
;Zona de datos

   __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
   LIST   P=16F873
   INCLUDE   <P16F873.INC>
   
RxBuf   EQU   20H
TxBuf   EQU   2AH
STX   EQU   4AH
ETX   EQU   4BH
   
ord1   EQU   4CH
ord2   EQU   4DH
ord3   EQU   4EH
ord4   EQU   4FH
ord5   EQU   50H
Canal   EQU   51H
ord   EQU   52H
RxPunt   EQU   53H
TxPunt   EQU   54H
STATUS_TEMP   EQU   55H   ;Almacenamiento   de STATUS durante la interrupcion
WREG_TEMP   EQU   56H   ;Almacenamiento de W durante la interrupcion
FSR_TEMP   EQU   57H   ;Almacenamiento de FSR durante la interrupcion
   
   
;Zona de codigos

   ORG   0
   goto   Inicio
   ORG   4
   goto   INT_SER

Inicio
   clrf   PORTA
   clrf   PORTB
   clrf   PORTC
   bsf   STATUS,RP0   ;Cambio al banco 1
   bcf   STATUS,RP1
   clrf   TRISB      ;Puerto B como salida
   clrf   TRISA      ;Puerto A como salida
   movlw   b"00101111"   
   movwf   TRISA      ;RA0,RA1,RA2,RA3 y RA5 entradas analogicas
   movlw   b"10011111"   ;RC7/Rx entrada,
   movwf   TRISC       ;RC6/Tx   salida y RC5 Salida.
   movlw   b"00100100"   ;Configuracion USART
   movwf   TXSTA      ;y activacion de transmision   
   movlw   .25      ;9600 baudios
   movwf   SPBRG
   movlw   b"11000000"
   movwf   INTCON      ;Habilitamos todas las interrupciones
   movlw   b"00000001"   ;justificacion del resultado de la conv a la izq. es decir en ADRESH
   movwf   ADCON1
   bsf   PIE1,RCIE   ;Habilitacion interrupcion RX
   bsf   PIE1,TXIE   ;Habilitacion interrupcion TX
   bcf   STATUS,RP0   ;Vuelta al banco 0
   movlw   b"01000001"   ;seleccion Tad, canales para
   movwf   ADCON0      ;conversion y A/D=ON
   
   movlw   b"10010000"   ;Configuracion de la usart
   movwf   RCSTA      ;para recepcion continua

   movlw   .32      ;inicializacion de los punteros del buffer
   movwf   RxPunt
   movlw   .42
   movwf   TxPunt

Principal   
   movlw   .0      ;
   subwf   ord,W      ;Comprobamos la orden de conversion,si ord es <> de 0 salta a comprobar si es otra orden
   btfsc   STATUS,Z   ;Si Z=0,salta ya que no son iguales
   goto   Principal   ;En todo momento esta a la espera de que salta la int por recepcion
conv_01
   movlw   .5
   subwf   ord,W      ;Comprobamos si es la orden 5
   btfsc   STATUS,Z   ;Si no son iguales se va a comprobar otra orden
   goto   ord_05      ;Si son iguales se va a ejecutar la orden de conversion 5
conv_02   
   movlw   .1      ;Comprobamos si es la orden 1
   subwf   ord,W
   btfsc   STATUS,Z   ;Si no son iguales se va a comprobar otra ordem
   goto   ord_01      ;Si son iguales se va a ejecutar esa orden
conv_03
   movlw   .2      ;Comprobamos si es la orden 2 de conversion
   subwf   ord,W      
   btfsc   STATUS,Z   ;Si no son iguales se va a comprobar otra orden
   goto   ord_02      ;Si lo son ejecuta la orden de conversion 2
conv_04   
   movlw   .3
   subwf   ord,W
   btfsc   STATUS,Z
   goto   ord_03
conv_05
   movlw   .4
   subwf   ord,W
   btfsc   STATUS,Z
   goto   ord_04
conv_06
   movlw   .5
   subwf   ord,W
   btfss   STATUS,W
   goto    Principal
ord_05
   movlw   TxBuf+1      ;Adquirimos la señal de los 4 canales
   movwf   FSR
   movlw   .1      ;y los resultados de la conversion los vamos metiendo
   movwf   Canal      ;en su respectiva posicion del buffer de transmision
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .2
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .3
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .4
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   goto   prc_tra
ord_01
   movlw   TxBuf+1
   movwf   FSR
   movlw   .1
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   goto   prc_tra
ord_02
   movlw   TxBuf+1
   movwf   FSR
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .2
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   goto   prc_tra      
ord_03
   movlw   TxBuf+1
   movwf   FSR
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .3
   movwf   Canal
   call   Conversion
   movf   ADRESH,W
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   goto   prc_tra      
ord_04            ;Como solo queremos adquirir el canal 4
   movlw   TxBuf+1      ;El segundo (el primero sera STX) byte correspondiente al primer canal
   movwf   FSR         
   movlw   .0      ;lo rellenamos con 0, y asi sucesivamente hasta el cuarto
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .0
   movwf   INDF
   incf   FSR,F
   movlw   .4      ;Este canal si que lo vamos a adquirir
   movwf   Canal      ;Seleccionamos canal del ADC
   call   Conversion   ;y el resultado lo metemos en la 5ºpos del buffer que correponde con la    
   movf   ADRESH,W   ; 5º pos en la trama a enviar al pc
   movwf   INDF
prc_tra            ;preparamos trama a enviar al PC
   clrf   ord
   movlw   STX      ;Ponemos byte STX en primera pos del buffer de transmision
   movwf   TxBuf
   addwf   TxBuf+1,W   ;Calculamos el checksum que equivale a la suma del resultado
   addwf   TxBuf+2,W   ; de la conversion de todos los canales
   addwf   TxBuf+3,W
   addwf   TxBuf+4,W
   movwf   TxBuf+5      ;y el byte checksum lo metemos en la quinta pos. del buffer
   movlw   ETX
   movwf   TxBuf+6      ;el byte de fin de trama ETX lo metemos en la 6º posicion del buffer
   
   movf   TxPunt,W   ;El puntero del buffer que ha sido inicializado al a primera posicion del buffer   
   movwf   FSR      ;va señalando en cada momento el byte que es enviado
   movf   INDF,W      ;asi hasta que ha recorrido todo el buffer de transmision
   movwf   TXREG
   incf   TxPunt,F
   goto   Principal
   


;Subrutina de conversion

Conversion
   bcf   STATUS,RP0
   bcf   STATUS,RP1   ;Cambio a la banco 0
   movlw   b"01000001"   ;Valor por defecto para que despues podamos hacer la iorwf
   movwf   ADCON0
   rlf   Canal,F
   rlf   Canal,F
   rlf   Canal,W
   iorwf   ADCON0,F
   rrf   Canal,F
   rrf   Canal,F   
   bcf   PIR1,ADIF   ;Restaurar flag de peticion de int.del conversor
   nop
   nop
   bsf   ADCON0,GO   ;Iniciamos conversion
espera
   btfss   PIR1,ADIF   ;¿Ha terminado?
   goto   espera      ;No.esperar
   return
   
   
   
INT_SER
   movwf   WREG_TEMP   ;Salvamos el estado actual de los registros criticos para recuperarlos luego
   swapf   STATUS,W
   movwf   STATUS_TEMP
   movf   FSR,W
   movwf   FSR_TEMP
   
   btfss   PIR1,RCIF   ;¿Interrupcion por recepcion?
   goto   TRANSM      ;No,se va a transmision
Recep   bcf   PIR1,RCIF   ;Repone flag de peticion de interrupcion por recep.
   movf   RxPunt,W   ;
   movwf   FSR
   movf   RCREG,W      ;pasamos el dato recibido al registro de trabajo
   movwf   INDF      ;guardamos el dato en el buffer de recepcion,en la direccion apuntada por FSR)direccionamiento indirecto)
;   movwf   PORTB
   incf   RxPunt,F   ;apuntamos a la siguiente poiscion del buffer de recepcion
   movlw   RxBuf+4   
   subwf   RxPunt,W
   btfss   STATUS,Z   ;Comparamos si ha llegado toda la trama.Osea comparar si a donde apunta FSR es igual a la cuarta posicion
            ;del buffer
   goto   FISER      ;Si no ha llegado toda la trama it a final de la interrupcion
;Si si que ha llegado,analiza la trama
Analizar
   movlw   .32
   movwf   RxPunt      ;Ponemos el puntero de recepcion en su posicion inicial
   movlw   STX      ;Pone primer caracter de trama
   subwf   RxBuf,W      ;Comprobamos STX
   btfss   STATUS,Z
   goto   FISER      ;sino son iguales se va a final de la int.
   movlw   ETX
;   movwf   PORTB
   subwf   RxBuf+3,W   ;Comprobamos ETX
   btfss   STATUS,Z
   goto   FISER      ;Si STX y ETX coinciden con el sus respectivos patrones y estan en la posicion correcta de la trama
   movf   RxBuf,W      ; que se ha ido metiendo en el buffer de recpecion, pasamos a calcular el checksum y a comprobar si coincide tambien
   addwf   RxBuf+1,W   ;Se calcula el checksum, que es la suma de ETX mas la orden de conversion
   subwf   RxBuf+2,W   
   btfss   STATUS,Z   ;Comprobamos chk
   goto    FISER      ;Si el checksum no coincide salimos de la int.
;si la trama que ha llegado es correcta comprobamos cual de las 4 ordenes se ha recibido   
RECEP1   movlw   ord1      ;si es la orden 1 la recibida , quiere decir que solo vamos a adquirir del canal 1
   subwf   RxBuf+1,W
   btfss   STATUS,Z
   goto   RECEP3      ;Sino es la orden 1 la recibida  pues pasamos a ver si es otra orden
   movlw   .1      ;si si que es,la guarda en la variable ord.Entonces en la rutina principal vera que ord es <> de 0 y
   movwf   ord      ;se ira a la rutina de conversion llamando al canal 1( 0 en el pic)
   goto   FISER
RECEP3            
   movlw   ord2
   subwf   RxBuf+1,W
   btfss   STATUS,Z   ;Comprobamos si la orden recibida es la 2
   goto   RECEP4
   movlw   .2      ;en caso afirmativo guardamos el valor de la orden den converscion en la variable ord
   movwf   ord      
   goto   FISER

RECEP4   
   movlw   ord3      ;Comprobamos si la orden recibida es la 3
   subwf   RxBuf+1,W
   btfss   STATUS,Z
   goto   RECEP5      
   movlw   .3
   movwf   ord      ;En caso afirmativo guarda el valor en la variable ord
   goto   FISER
RECEP5
   movlw   ord4         ;Comprobamos si la orden recibida es la 4
   subwf   RxBuf+1,W
   btfss   STATUS,Z
   goto   RECEP6
   movlw   .4
   movwf   ord
   goto   FISER
RECEP6
   movlw   ord5      ;comprobramos si la orden recibida es la 5
   subwf   RxBuf+1,W
   btfss   STATUS,Z
   goto   FISER   
   movlw   .5      ;en caso afiramtivo la guardamos en la variable ord
   movwf   ord
   goto   FISER
      
TRANSM   
   bcf   PIR1,TXIF   ;Restaura flag de transmision
   movlw   TxBuf+7
   subwf   TxPunt,W   ;Si el puntero de transmision apunta a la posicion 7 del buffer (la ultima es la 6) es que se ha enviado toda la trama
   btfsc   STATUS,Z   ;Comprobamos si se han transmitido todos los bytes
   goto   subFISER   ;En caso afirmativo salimos de la rutina de transm.
   
   movlw   TxPunt
   movwf   FSR
   movf   INDF,W
   movwf   TXREG
   incf   TxPunt
   goto   FISER
subFISER
   movlw   .42      ;Antes de salir de la interrupcion por tranmision,despues de haber mandado toda la trama al PC
   movwf   TxPunt      ;inicializamos el buffer de transmision a la primera posicion del buffer de transmision
FISER
   movf   FSR_TEMP,W
   movwf   FSR
   swapf   STATUS_TEMP,W
   movwf   STATUS
   swapf   WREG_TEMP,F   ;Prepara W para ser restaurado.
   swapf   WREG_TEMP,W   ;Restaura W sin afectar al bit Z de Status.
   retfie         ;fin interrupcion canal serie.
   
   END


***************************************************
Gracias de antemano