Autor Tema: Problema transmision USART , PIC16F873  (Leído 2085 veces)

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

Desconectado lluiset

  • PIC10
  • *
  • Mensajes: 3
Problema transmision USART , PIC16F873
« en: 17 de Julio de 2005, 13:07:00 »
Tengo un problema con una comunicacion entre el PIC y el PC. El programa que tengo se encarga de enviar via serie la conversion de los canales ADC con caracter de cabecera y de fin previa peticion del pc. El pc le envia 3 bytes, una cabecera el dato (orden de conversion) y un checksum que es la suma de los dos anteriores.Haciendo pruebas veo que llega bien todo, que lo mete bien en el buffer y que luego lo lee bien. El problema es a la hora de contestar, que comprobando que el registro TXREG es escrito y que TXSTA esta bien configurado a la hora de transmitir del pic no sale nada de nada. La placa esta bien y el pic tambien poque he probado el mismo programa pero enviando a saco sin peticion alguna del pc y si que envia.

Posteo el codigo por si algun alma caritativa le quiere echar un vistazo y darme algun consejo.

Codigo:

         list p=16f873      ;list directive to define processor
      #include <p16f873.inc>   ;processor specific definitions
      errorlevel -302      ;suppress "not in bank 0" message

      __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _LVP_ON & _DEBUG_OFF & _CPD_OFF

   
RxDATO                      equ          0x20
rflgs         equ   0x21
rdat         equ   0x22
cksum         equ   0x23
Bufferdata      equ   0x24
RxEndPtr                      equ   0x25
RxStartPtr      equ   0x26
Flags         equ   0x27
STX         equ   0x4A

TX_BUF_LEN                       equ   .80      ;Longitud del buffer circular de transmision
RX_BUF_LEN                   equ   TX_BUF_LEN   ;Longitud del buffer circular de recepcion

;Definiciones de bit del byte Flags
TxBuflleno   equ   0      ;Bit que indica que el buffer de transmision esta lleno
TxBufvacio   equ   1      ;Bit que indica que el buffer de transmision esta vacio
RxBuflleno   equ   2      ;Bit que indica que el buffer de recepcion esta lleno
RxBufvacio   equ   3      ;Bit que indica que el buffer de recepcion esta vacio
CRrecibido   equ   4      ;Bit que indica que se ha recibido un retorno de carro
int      equ   5      ;Bit que indica si se ha producido una interrupcion por recepcion

;Definiciones de bit del byte rflgs
pakerr   equ   0      ;error de paquete
newpac   equ   1      ;paquete completado
newData   equ   2      ;nuevo dato recibido
newtype   equ   4      ;tipo recibido
newseq   equ   5      ;seq recibida
newlen   equ   6      ;len recibido
newSTX   equ   7      ;cabecera recibida


 

      CBLOCK   0x70
      WREG_TEMP         ;Almacenamiento de W durante la interrupcion
      STATUS_TEMP
      PCLATH_TEMP
      FSR_TEMP
      FLAGS
      ENDC
      
;Buffer de transmision
      CBLOCK   0x2F
      TxBuffer:TX_BUF_LEN
      ENDC
;Buffer de recepcion
      CBLOCK   0xAF
      RxBuffer:RX_BUF_LEN
      ENDC
      
      org   0x0000         ;Vector de Reset
      goto   Inicio

      org   0x0004         ;Salva vector de interrupción
      
isr      
      movwf   WREG_TEMP
      movf   STATUS,W
      clrf   STATUS
      movwf   STATUS_TEMP
      movf   PCLATH,W
      movwf   PCLATH_TEMP
      clrf   PCLATH
      movf   FSR,W
      movwf   FSR_TEMP
         
      btfss   PIR1,RCIF      ;¿Interrupcion por recepcion?
      goto   finisr      ;NO.salir
      bcf   PIR1,RCIF      ;Limpiar flag de recepcion
      movf   RCREG,W
      movwf   rdat      ;Guardamos dato recibido en la variable RxDato
;      movwf   PORTB
      bsf   FLAGS,int
;   bsf   PORTB,0
;Coge los datos recibidos y los mete en el buffer de recepcion, previa comprobacion de la trama
GetData   
;======================= 1º Comprobar si ETX es correcto ===============================
pacrec1                   btfsc   rflgs,newSTX         ;STX recibido ya? si no,saltar siguiente
      goto   pacrec2         ;Sí,
      movlw   STX         ;No.Es el STX correcto?   
      subwf   rdat,w
      btfss   STATUS,Z      ;Si sí,saltar siguiente
      goto   finisr         ;No.Salir de la interrupcion,se deshecha toda la trama
      bsf   rflgs,newSTX      ;Sí.setear flag de cabecera recibida
      movf   rdat,w         ;Metemos el STX en el checksum
      addwf   cksum,f         ;Añadirlo al checksum
      goto   finisr
;====================== 2º Meter el dato en el buffer ========================
pacrec2                   btfsc   rflgs,newData   ;Datos de canales recibidos ya?
      goto   pacrec3         ;Sí,ir a comprobar el checksum
      bsf   rflgs,newData      ;No.Setear flag de datos recibidos
      addwf   cksum,f         ;Sumar el dato al checksum
      goto   PutRxBuffer      ;Meterlo en el buffer de recepción
;===================== 3º Comprobar Checksum =================================
pacrec3                   movf   rdat,w            ;Metemos el dato recibido en w
      subwf   cksum,w         ;Comprobar si el checksum recibido es correcto
      btfss   STATUS,Z      ;Si no son iguales.Saltar instruccion
      goto   finisr         ;Salimos de la interrupcion
      
      bsf   rflgs,newpac      ;seteamos flag de paquete completo recibido      
      goto   finisr
               
               
PutRxBuffer
      bcf   STATUS,RP0      ;banco 0 de memoria
      
      BANKISEL RxBuffer
      movwf   Bufferdata      ;guarda el contenido de w en la variable bufferdata
      movf   RxEndPtr,w      ;cogemos Endpointer
      movwf   FSR         ;y lo cargamos en FSR
      movf   Bufferdata,w      ;cogemos el contenido de bufferdata
      movwf   INDF         ;y lo metemos en la posicion del buffer apuntada por endpointer.
;Comprobamos si el puntero del buffer necesita apuntar al inicio del buffer
      movlw   LOW RxBuffer+RX_BUF_LEN-1   ;Cogemos la ultima posicion del buffer
      xorwf   RxEndPtr,w      ;y lo comparamos con endpointer
      movlw   LOW RxBuffer      ;Cargamos primera direccion del buffer
      btfss   STATUS,Z      ;Comprobamos si el puntero apunta a la ultima direccion
      incf   RxEndPtr,w      ;Si no, entonces incrementamos el puntero
      movwf   RxEndPtr      ;Almacenamos nuevo valor del endpointer         
finisr      
      movf   FSR_TEMP,W
      movwf   FSR
      movf   PCLATH_TEMP,W
      movwf   PCLATH
      movf   STATUS_TEMP,W
      movwf   STATUS
      swapf   WREG_TEMP,F
      swapf   WREG_TEMP,W
      retfie   
         
;****************Lectura de los datos****************

Lectura
      Banksel   ADRESH
      movf   ADRESH,W
      return

;********************************************************************************************
;Tx_Dato: Transmite vía serie el dato presente en el reg. W

Tx_Dato      btfss   PIR1,TXIF
      goto   Tx_Dato   
      bcf   PIR1,TXIF      ;Restaura el flag del transmisor
      movwf   TXREG         ;Almacena el byte a transmitir
      bsf   STATUS,RP0
Tx_Dato_Wait   btfss   TXSTA,TRMT      ;Byte transmitido ??
      goto   Tx_Dato_Wait      ;No, esperar
      bcf   STATUS,RP0
;   bsf   PORTB,1
      return            ;Si

;*******************************************************************************************
;Programa principal

Inicio           clrwdt
      clrf   PORTC      
      bsf   STATUS,RP0      ;Selecciona banco 1
      movlw   b"00000000"
      movwf   ADCON1         ;RA0-RA3 analógicas, Vref=Vcc, alineación izq.
      movlw   b"11111111"
      movwf   TRISA         ;Puerta A entrada
      movlw   b"00000000"   
      movwf   TRISB         ;Puerta B salida
      movlw   b"10111111"
      movwf   TRISC         ;RC7/Rx entrada, RC6/Tx salida
      movlw   b"11001111"
      movwf   OPTION_REG      ;Preescaler de 128 asociado al WDT

      movlw   b"00100100"   
      movwf   TXSTA         ;TX en On, modo asíncrono con 8 bits y alta velocidad
      movlw   .25
      movwf   SPBRG         ;9600 baudios con Fosc=4MHz
      movlw   0xC0
      movwf   INTCON
      bsf   PIE1,RCIE      ;Habilita interrupcion en recepcion

      bcf   STATUS,RP0      ;Selecciona banco 0
      bsf   RCSTA,SPEN      ;USART en On
      bsf   RCSTA,CREN      ;Recepcion continua

;El ADC trabaja a Fosc/8

      movlw   b"01000001"
      movwf   ADCON0         ;ADC en On
      movlw   0x00
      movwf   PORTB
      
      clrf   rflgs
      clrf   cksum
      clrf   Flags
;================== Inicialización del buffer de recepción ======================
InitRxBuffer
      bcf   STATUS,RP0
      movlw   LOW RxBuffer      ;Coge la dirección del buffer de recepción
      movwf   RxStartPtr      ;y la depositamos en el puntero de inicio
      movwf   RxEndPtr      ;y la depositamos en el puntero de fin
      bcf   Flags,RxBufvacio   
      bcf   Flags,RxBuflleno   
Loop   
      btfss   rflgs,newpac      ;Esperamos a que toda la trama haya llegado bien
      goto   Loop
      call   GetRxBuffer
      movwf   RxDATO
      movlw   0x4C
      subwf   RxDATO,W      ;Comprobamos que el dato recibido correponde con la orden de conversion
      btfss   STATUS,Z      ;Si Z=1 salta ya que son iguales
      goto   Loop         ;Espera a que la recepcion sea correcta es decir solo convierte una vez a peticion del PC.
      btfss   FLAGS,int      ;Conversion por disparo
      goto   Loop         ;El flag int dice si se ha producido interrupcion, es decir si se ha pedido desde el PC que convierta.
                  ;Si si convierte y envia.Si no se queda esperando a dicha orden
      movlw   0x4A   
      call   Tx_Dato
      movf   TXREG,W

      bcf   STATUS,RP0
      movwf   PORTB
      
      clrwdt
      bcf   PIR1,ADIF      ;Restaura el flag del conversor
      movlw   b"01000001"
      movwf   ADCON0      
      nop
      bsf   ADCON0,GO   ;Inicia conversión del canal 0
ADC0_Wait   btfss   PIR1,ADIF      ;Fin de conversión ??
      goto   ADC0_Wait      ;No, esperar
      call   Lectura         ;Lee el valor de la conversión
      call   Tx_Dato         ;Salida por RS232
      
      bcf   PIR1,ADIF      ;Restaura el flag del conversor
      movlw   b"01001001"
      movwf   ADCON0      
      nop
      bsf   ADCON0,GO      ;Inicia conversión del canal 1
ADC1_Wait   btfss   PIR1,ADIF      ;Fin de conversión ??
      goto   ADC1_Wait      ;No, esperar
      call   Lectura         ;Lee el valor de la conversión
      call   Tx_Dato         ;Salida por RS232
 
      bcf   PIR1,ADIF      ;Restaura el flag del conversor
      movlw   b"01010001"
      movwf   ADCON0      
      nop
      bsf   ADCON0,GO      ;Inicia conversión del canal 2
ADC2_Wait   btfss   PIR1,ADIF                      ;Fin de conversión ??;
      goto   ADC2_Wait      ;No, esperar
      call   Lectura         ;Lee el valor de la conversión
      call   Tx_Dato         ;Salida por RS232

      bcf   PIR1,ADIF      ;Restaura el flag del conversor
      movlw   b"01011001"
      movwf   ADCON0      
      nop
      bsf   ADCON0,GO      ;Inicia conversión del canal 3
ADC3_Wait   btfss   PIR1,ADIF      ;Fin de conversión ??
      goto   ADC3_Wait      ;No, esperar
      call   Lectura         ;Lee el valor de la conversión
      call   Tx_Dato         ;Salida por RS232
      
      movlw   0x0D
      call   Tx_Dato         ;Transmite CR (Retorno de carro)
      bcf   FLAGS,int
      clrf   rflgs
      goto   Loop
      
;------------------ Quita y devuelve en w el byte que hay en el inicio del buffer------------
GetRxBuffer
      bcf   STATUS,RP0
      btfsc   Flags,RxBufvacio   ;Comprueba si el buffer de recepcion esta vacio
      nop            ;Aqui iria una llamada a un rutina de tratamiento de error
      bsf   STATUS,RP0
      bcf   PIE1,RCIE      ;Deshabilitar interrupcion por recepcion
      bcf   STATUS,RP0
      
      BANKISEL   RxBuffer   ;Bit del banco para direccionamiento indirecto
      movf   RxStartPtr,w      ;Cogemos StartPointer
      movwf   FSR         ;y lo depositamos en FSR
      
;Comprobamos si el puntero del buffer necesita apuntar al comienzo del buffer de memoria
      
      movlw   LOW RxBuffer+RX_BUF_LEN-1   ;Cogemos la ultima posicion del buffer de memoria
      xorwf   RxStartPtr,w         ;y la comparamos con el puntero de inicio
      movlw   LOW RxBuffer      ;Cargamos primera direccion de buffer
      btfss   STATUS,Z      ;Comprobamos si el puntero esta en la ultima direccion del buffer
      incf   RxStartPtr,W      ;Si no, incrementar puntero
      movwf   RxStartPtr      ;almacenar nuevo valor del puntero
      bcf   Flags,RxBuflleno   ;el buffer no puede estar vacio
      
      movf   INDF,W         ;Cogemos el dato del buffer
      
      bsf   STATUS,RP0
      bsf   PIE1,RCIE      ;Habilitamos interrupcion por recepcion
      bcf   STATUS,RP0
      return
      

      end            ;Fin del programa fuente



Saludos y gracias de antemano.

Desconectado Artifox

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 455
    • Quadbot
RE: Problema transmision USART , PIC16F873
« Respuesta #1 en: 18 de Julio de 2005, 13:40:00 »
A ver.... revisar todo tu codigo me llevaria un par de horas, asi que solo te dare unas ideas de que es lo que puedes hacer.

Primero, ese dato(orden de conversion) q envias desde la pc q es? para q selecciones de q canal ADC vas a leer?. Bueno, revisa  bien los registros de interrupcion q tienes. Ademas, me aprece que cuando empiezas a recibir todo lo haces dentro de la misma interrupcion... Lo q deberias hacer es algo asi:

Interrupcion:
valor=rxreg
index=index+1
Findeinterrupcion
index=0
inicio:
; configuras los puertos y todo lo demas
loop
valadc=adresl    ; guarda el valor adc
if index=1 then
............
if index=2 then
.............
If index=3 then
txreg= valadc
goto loop



O por lo menos algo asi. No se si entiendas mi idea. Bueno, ojala te sirva de algo. Nos vemos...
Video Quadbot
Saludos desde mi querido Perú.
Si realmente queremos que el mundo cambie debemos empezar por nosotros mismos... ;)

Desconectado lluiset

  • PIC10
  • *
  • Mensajes: 3
RE: Problema transmision USART , PIC16F873
« Respuesta #2 en: 19 de Julio de 2005, 04:44:00 »
Gracias por la respuesta, aunque realmente no hace falta leerse todo el programa, mi problema basicamente es que teniendo habilitada la transmision es decir el bit TXEN del registro TXSTA, cuando esribo sobre TXREG el pic no envia nada, y eso es lo que me tiene muy mosca, porque la recepcion si que la hace bien.

Saludos.