Autor Tema: problema con recepción de datos RS232  (Leído 3800 veces)

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

Desconectado Scufflee

  • PIC10
  • *
  • Mensajes: 26
problema con recepción de datos RS232
« en: 26 de Diciembre de 2014, 11:38:50 »
Buenas, he estado trabajando con la comunicación RS232 en el PIC16F628A, estoy usando una interrupción para la recepción de datos donde al momento de recibir un dato me envía un eco de lo que recibió., los recibe bien y todo, pero el PIC no recibe el dato exacto de lo que el envío.

Si le envío un 250 hexa, me devuelve un 254 hexa. Lo mismo con datos menores, le enviaba un 1 y devolvía un 193, cosas así.

Código: [Seleccionar]
LIST    P=PIC16F628A


_INCRC_OSC_NOCLKOUT   equ  0x3FFC
_WDT_OFF              equ  0x3FFB
_PWRTE_ON             equ  0x3FF7
_MCLRE_OFF            equ  0x3FDF
_BODEN_OFF            equ  0x3FBF
_LVP_OFF              equ  0x3F7F
_CPD_OFF              equ  0x3F7F
_CP_OFF               equ  0x3FFF

 __config _INCRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF


;------------------------------------------------------------
;                  Declaración de Registros
;------------------------------------------------------------
w                     equ  0x0000
status                equ  0x0003
porta                 equ  0x0005
portb                 equ  0x0006
pclath                equ  0x000a
intcon                equ  0x000b
pir1                  equ  0x000c
rcsta                 equ  0x0018
txreg                 equ  0x0019
rcreg                 equ  0x001a
cmcon                 equ  0x001f
_np_w                 equ  0x0020
recibir               equ  0x0024
_np_temp1             equ  0x0025
_np_espera1           equ  0x002a
_np_espera2           equ  0x002b
_np_banderas          equ  0x002e
_np_status            equ  0x002f
_np_tiempo            equ  0x0031
_np_tiempo1           equ  0x0032
_np_tiempo2           equ  0x0033
_np_tiempo3           equ  0x0034
_np_t_bak             equ  0x0035
_np_t1_bak            equ  0x0036
_np_t2_bak            equ  0x0037
_np_t3_bak            equ  0x0038
_np_banderas2         equ  0x0039
estado                equ  0x003e
opcion                equ  0x0081
trisa                 equ  0x0085
trisb                 equ  0x0086
pie1                  equ  0x008c
txsta                 equ  0x0098
spbrg                 equ  0x0099


;------------------------------------------------------------
;                  Declaración de Bits
;------------------------------------------------------------
c                     equ  0   ;carry / borrow bit
cren                  equ  4   ;
gie                   equ  7   ;habilitador general de interrupciones
oerr                  equ  1   ;
peie                  equ  6   ;ee write complete interrupt enable bit
rb0_int               equ  0   ;bit 0 del puerto b
rb1                   equ  1   ;bit 1 del puerto b
rb2                   equ  2   ;bit 2 delpuerto b
rb3                   equ  3   ;bit 3 del puerto b
rb4                   equ  4   ;bit 4 del puerto b
rb5                   equ  5   ;bit 5 del puerto b
rb6                   equ  6   ;bit 6 del puerto b
rb7                   equ  7   ;bit 7 del puerto b
rcie                  equ  5   ;
rcif                  equ  5   ;bandera de interrupcion por fin de recepción usart.
rp0                   equ  5   ;registrer bank select bit
rp1                   equ  6   ;registrer bank select bit
spen                  equ  7   ;
trmt                  equ  1   ;
txif                  equ  4   ;bandera de interrupcion por fin de transmisión usart.
z                     equ  2   ;bit cero
rx_ok                 equ  0   ;bandera de recepción de dato ok
sub_inte              equ  0   ;bandera de subrrutina cancelada por interrupcion.


;------------------------------------------------------------
;               Declaración de Registros EEPROM
;------------------------------------------------------------


;------------------------------------------------------------
;                        Inicio
;------------------------------------------------------------

   org 0x00
   goto paso2
   org 0x04
   movwf _np_w
   swapf _np_w,1
   movf status,w
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   movwf _np_status
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   movf _np_tiempo,w
   movwf _np_t_bak
   movf _np_tiempo1,w
   movwf _np_t1_bak
   movf _np_tiempo2,w
   movwf _np_t2_bak
   movf _np_tiempo3,w
   movwf _np_t3_bak
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   btfsc pir1,rcif
   goto inte_rc
salir__intes
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   bsf _np_banderas2,sub_inte       ;activar la bandera de rutina cancelada por interrupcion
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   movf _np_t_bak,w
   movwf _np_tiempo
   movf _np_t1_bak,w
   movwf _np_tiempo1
   movf _np_t2_bak,w
   movwf _np_tiempo2
   movf _np_t3_bak,w
   movwf _np_tiempo3
   movf _np_status,w
   movwf status
   swapf _np_w,w
   retfie


   ;------------------------------------------------------------
   ;                      inicio de la interrupción por rc usart
   ;------------------------------------------------------------
inte_rc_salir
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   bcf pir1,rcif
   goto salir__intes
inte_rc
inte_rc2

   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   bsf _np_banderas,rx_ok           ;iniciar la recepcion sin erroes.
   bcf rcsta,oerr
   clrf _np_espera1
   clrf _np_espera2
   goto inte_rc2_rc_1
inte_rc2_esp_byte_1
   incf _np_espera2,1
   btfss status,z
   goto inte_rc2_rc_1
   incf _np_espera1,1
   btfsc status,z
   goto inte_rc2_err
inte_rc2_rc_1
   btfss pir1,rcif
   goto inte_rc2_esp_byte_1
   movf rcreg,w
   movwf recibir
   bcf pir1,rcif
   btfsc rcsta,oerr
   goto inte_rc2_err
   goto inte_rc2_salir
inte_rc2_err
   bcf _np_banderas,rx_ok           ;error de comunicaciones.
inte_rc2_salir
   bcf rcsta,oerr
   btfss _np_banderas,rx_ok         ;si el -bit, rx_ok = 0
   goto inte_rc2
   call rutusr_002                  ;llamada a rutina usr_enviar
   btfss portb,rb3                  ;si el -bit, rb3 = 10
   goto inte_rc_salir
   movf recibir,w                   ;enviar el byte recibir
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   ;escribir en el puerto a
   movf recibir,w
   movwf porta
   goto inte_rc_salir

;------------------------------------------------------------
;                      programa principal
;------------------------------------------------------------
paso2
   clrf _np_w
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   clrf recibir
   clrf _np_temp1
   clrf _np_espera1
   clrf _np_espera2
   clrf _np_banderas
   clrf _np_status
   clrf _np_tiempo
   clrf _np_tiempo1
   clrf _np_tiempo2
   clrf _np_tiempo3
   clrf _np_t_bak
   clrf _np_t1_bak
   clrf _np_t2_bak
   clrf _np_t3_bak
   clrf _np_banderas2
   clrf estado
   clrf _np_w
   clrf _np_w
   clrf porta
   movlw b'11110000'                ;configurar el puerto a como eeeessss
   bsf status,rp0                   ;cambiar a banco 1
   movwf trisa
   movlw b'00000111'                ;puerto a = e/s digital
   bcf status,rp0                   ;cambiar a banco 0
   movwf cmcon
   clrf portb
   movlw b'11110010'                ;configurar el puerto b como eeeesses
   bsf status,rp0                   ;cambiar a banco 1
   movwf trisb
   bcf status,rp0                   ;cambiar a banco 0
   bsf portb,rb0_int
entrega_dato
   movlw b'00100110'
   bsf status,rp0                   ;cambiar a banco 1
   movwf txsta
   movlw .25
   movwf spbrg
   bcf status,rp0                   ;cambiar a banco 0
   bsf rcsta,spen                   ;habilitacion del puerto de comunicacion serial
   bsf rcsta,cren

   bsf intcon,gie                   ;activar habilitador general de interrupciones.
   bsf intcon,peie                  ;activar habilitador general de interrupciones por perifericos.
   bcf pir1,rcif                    ;limpiar la bandera antes de activarla
   bsf status,rp0                   ;cambiar a banco 1
   bsf pie1,rcie                    ;activar interrupción por fin de recepción por usart.
   goto entrega_dato
   goto entrega_dato


;------------------------------------------------------------
;                  Declaración de Subrutinas
;------------------------------------------------------------

; usr_enviar
rutusr_002

   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   movf recibir,w                   ;si el -reg(08), recibir  = 0xfb,
   xorlw 0xfb
   btfss status,z
   goto rutusr_002_10
   bcf portb,rb3
   btfss portb,rb4                  ;si el -bit, rb4 = 10
   goto rutusr_002_8
   movlw 0x69                       ;enviar el byte 0x69
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x49                       ;enviar el dato 0x49
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x65                       ;enviar el dato 0x65
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
rutusr_002_6
   bcf portb,rb3
rutusr_002_7
   goto rutusr_002_salir
rutusr_002_8
   movlw 0x69                       ;enviar el byte 0x69
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x49                       ;enviar el dato 0x49
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x68                       ;enviar el dato 0x68
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
rutusr_002_9
   bcf portb,rb3
   goto rutusr_002_salir
rutusr_002_10

   movf estado,w                    ;si el -reg(08), estado  = 0xfc,
   xorlw 0xfc
   btfss status,z
   goto rutusr_002_15
   bcf portb,rb3
   btfss portb,rb5                  ;si el -bit, rb5 = 10
   goto rutusr_002_14
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x32                       ;enviar el dato 0x32
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x41                       ;enviar el dato 0x41
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_6                ;cierra el ciclo
rutusr_002_14
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x32                       ;enviar el dato 0x32
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x44                       ;enviar el dato 0x44
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_9                ;cierra el ciclo
rutusr_002_15

   movf estado,w                    ;si el -reg(08), estado  = 0xfd,
   xorlw 0xfd
   btfss status,z
   goto rutusr_002_20
   bcf portb,rb3
   btfss portb,rb6                  ;si el -bit, rb6 = 10
   goto rutusr_002_19
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x33                       ;enviar el dato 0x33
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x41                       ;enviar el dato 0x41
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_6                ;cierra el ciclo
rutusr_002_19
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x33                       ;enviar el dato 0x33
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x44                       ;enviar el dato 0x44
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_9                ;cierra el ciclo
rutusr_002_20

   movf estado,w                    ;si el -reg(08), estado  = 0xfe,
   xorlw 0xfe
   btfss status,z
   goto rutusr_002_25
   bcf portb,rb3
   btfss portb,rb7                  ;si el -bit, rb7 = 10
   goto rutusr_002_24
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x34                       ;enviar el dato 0x34
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x41                       ;enviar el dato 0x41
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_6                ;cierra el ciclo
rutusr_002_24
   movlw 0x45                       ;enviar el byte 0x45
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x34                       ;enviar el dato 0x34
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   movlw 0x44                       ;enviar el dato 0x44
   movwf _np_temp1
   call rs232_tb2_9600              ;llamada a rutina rs232_tb2_9600
   goto rutusr_002_9                ;cierra el ciclo
rutusr_002_25
   bsf portb,rb3
   goto rutusr_002_salir
rutusr_002_salir
   bcf status,rp0                   ;cambiar a banco 0
   bcf status,rp1
   return


rs232_tb2_9600
   movlw b'00100110'
   bsf status,rp0                   ;cambiar a banco 1
   bcf status,rp1
   movwf txsta
   movlw .25
   movwf spbrg
   bcf status,rp0                   ;cambiar a banco 0
   bsf rcsta,spen
   movf  _np_temp1,w
   movwf txreg
   bsf status,rp0                   ;cambiar a banco 1
rs232_tb2_9600_e
   btfss txsta,trmt
   goto rs232_tb2_9600_e
   bcf status,rp0                   ;cambiar a banco 0
   return

Desconectado lucegiar2005

  • PIC24F
  • *****
  • Mensajes: 504
Re: problema con recepción de datos RS232
« Respuesta #1 en: 27 de Diciembre de 2014, 13:51:07 »
Lamento que solo subieras el asm, de eso nada de nada, pero si subes el proyecto en Niple ampliarás las posibilidades de ayuda. Un abrazo
- Santiago -

Desconectado Scufflee

  • PIC10
  • *
  • Mensajes: 26
Re: problema con recepción de datos RS232
« Respuesta #2 en: 08 de Enero de 2015, 12:01:19 »
Ahora subo el npl, es de la versión 5.7

Saludos.

PD: Dejo abajo el archivo NPL en un rar y el circuito que estoy usando (Lo saqué de robots-argentina pero les hice unas modificaciones).

« Última modificación: 08 de Enero de 2015, 14:05:03 por Scufflee »

Desconectado lucegiar2005

  • PIC24F
  • *****
  • Mensajes: 504
Re: problema con recepción de datos RS232
« Respuesta #3 en: 09 de Enero de 2015, 10:38:52 »
Quizá debas probar con la configuración sugerida por Niple para este modo, creo que estas usando una diferente a ella. No veo los resistores pull up ni las conexiones por los mismos termiales que el sugerido que subo y te daba tu versión de Niple.
- Santiago -

Desconectado Scufflee

  • PIC10
  • *
  • Mensajes: 26
Re: problema con recepción de datos RS232
« Respuesta #4 en: 09 de Enero de 2015, 10:59:50 »
Quizá debas probar con la configuración sugerida por Niple para este modo, creo que estas usando una diferente a ella. No veo los resistores pull up ni las conexiones por los mismos termiales que el sugerido que subo y te daba tu versión de Niple.

Es lo mismo, he probado con ese circuito y da el mismo problema.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: problema con recepción de datos RS232
« Respuesta #5 en: 09 de Enero de 2015, 11:44:17 »
Solo mirando el ASM veo que hay una cantidad de cosas en la rutina de interrupcion

Citar
bcf rcsta,oerr
Ese bit es de lectura, ademas intentas modificarlo y luego preguntas por si esta en 0 o en 1, lo cual no tiene sentido esa linea.
(Can be cleared by clearing bit CREN) del mismo registro.

No entiendo cuando se ejecutaria esto (inte_rc2_esp_byte_1):

Citar
inte_rc2_esp_byte_1
   incf _np_espera2,1
   btfss status,z
   goto inte_rc2_rc_1
   incf _np_espera1,1
   btfsc status,z
   goto inte_rc2_err
inte_rc2_rc_1
   btfss pir1,rcif
   goto inte_rc2_esp_byte_1

Si entra a la interrupcion por lo unico que se pregunta es por el flag de RX, sino sale de la interrupcion, PERO luego preguntas nuevamente por el flag RX como se ve al final. Que es obvio que va a saltar por que nunca se puso a 0 antes haciendo que ese codigo jamas se ejecute.

Ademas de haber muchisimos CALL dentro de una rutina de interrupcion y haciendo que la rutina sea extremadamente larga debo de suponer que algo esta mal. La rutina de interrupcion deberia ser lo mas corta posible.

Salvar el contexto
Guardar dato de RX
Limpiar flag de interrupcion / y setear flag de recepcion
Volver el contexto
Salir de la interrupcion

Cuando me refiero a contexto es W y STATUS, no se por que se guarda 3 registros mas llamados (_np_tiempox) que nunca se modifican en el programa.
Usas banderas para que luego en tu programa principal hagas las operaciones que necesitas. Pero la rutina de interrupcion deberia ser lo mas limpia posible.
Por ejemplo si hubiera un error por overrun el programa como esta quedaria en un loop infinito. (... -> inte_rc -> inte_rc2_rc_1 -> inte_rc2_err -> inte_rc2_salir -> inte_rc nuevmanete ) Por lo que explique al comienzo.

Otras cosas raras...

Cada ves que envias un byte Y dentro del loop del programa principal, seteas nuevamente todo:

Citar
  movlw b'00100110'
   bsf status,rp0                   ;cambiar a banco 1
   bcf status,rp1
   movwf txsta
   movlw .25
   movwf spbrg

Hasta incluso seteas un bit de solo lectura. Es decir ese codigo se ejecuta sin sentido una locura de veces. Tanto en un tu programa principal ( entrega_dato ) , como en el envio ( rs232_tb2_9600 )

Lo setearas una sola ves y tendrias menos codigo xD. Me da miedo el codigo de esto  :D

En fin solo se ASM y no NIPLE pero no veo nada fuera de lugar, lo que se recibe por UART es guardado en la variable "recibir" que luego se pasas a otra variable y se envia por el puerto.
Arregla lo de la interrupcion que sea lo mas corta posible. Limpiar lo mejor posible el programa y luego espero que se pueda ver el error.
« Última modificación: 09 de Enero de 2015, 12:10:32 por KILLERJC »