Autor Tema: Interrupcion por RX serial  (Leído 5697 veces)

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

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Interrupcion por RX serial
« en: 24 de Agosto de 2016, 03:44:37 »
Hola, nuevamente acudo a la sabiduría de ustedes, estoy implementando por primera vez la interrupción por RX serial, la idea es que mientras no reciba nada este chequeando el estado de ciertos registro y si están en 1 poner la salida que corresponda en alto, y cuando se activa la interrupción recibe una cadena y chequea que tiene que hacer, esos estados son 3 poner a 1 la correspondiente salida, a bajo o poner a 1 el registro que tiene asignada la salida para luego volver a donde estaba y seguir chequeando.
Bien el problema que tengo es que cuando se activa la interrupción hace correctamente todo pero borra lo anterior, es decir que si había recibido la orden de poner a alto la salida A0 y luego recibía la orden de poner a alto la A2, apaga la "0" y enciende la "2", y si le vuelvo a enviar la "0" apaga la "2" y enciende la "0", es como si una vez que sale de la interrupción borrara lo anterior para poner lo nuevo.
Les dejo los archivos para simularlo


Código: ASM
  1. ;*******************************************************************
  2.  
  3.         LIST P=16F877, R=HEX    ; Usar el PIC16F877A y sistema decimal
  4.  
  5.         #include "P16F877A.INC"  ; Incluye datos de PIC16F877A
  6.  
  7.         __CONFIG   _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _XT_OSC
  8.  
  9.  
  10. ;*******************************************************************
  11. ; CONFIGURACION
  12. ;*******************************************************************
  13.  
  14.  
  15. ;*******************************************************************
  16. ; VARIABLES
  17. ;*******************************************************************
  18.  
  19. PDel0A      EQU     0x42
  20. PDel1A      EQU     0x43
  21. contador    EQU     0x52        ; variable
  22. dato_serie  EQU     0x53        ; dato serie desde la PC
  23. puerto_a    EQU     'A'         ;puerto A
  24. digito_0    EQU     '0'         ;salida puerto 0
  25. digito_1    EQU     '1'         ;salida puerto 1
  26. digito_2    EQU     '2'         ;salida puerto 2
  27. caracter_q  EQU     'Q'         ;encendido
  28. caracter_w  EQU     'W'         ;apagado
  29. caracter_p  EQU     'P'         ;parpadea
  30. CONF_ADCON1 EQU     b'00000110'         ; Configuracion PORTA E/S digital
  31. ;*******************************************************************
  32.         ORG    0x00            ; El programa empieza en 0x000
  33.         goto   configuracion
  34.         org    0x04            ;Vector de interrupción
  35.         goto   interrup
  36.  
  37. ;******************************************************************
  38.  
  39. configuracion
  40.     bsf     STATUS,RP0            ; Ir banco 1
  41.     bcf     STATUS,RP1      ;xxxxxx
  42.     movlw   b'00000000'       ; valor inicial portA
  43.     movwf   PORTA
  44.     movlw   b'00000000'       ; valor inicial portB
  45.     movwf   PORTB
  46.     movlw   b'00000000'       ; valor inicial portC
  47.     movwf   PORTC
  48.     movlw   b'00000000'       ; valor inicial portD
  49.     movwf   PORTD
  50.     movlw   b'00000000'       ; valor inicial portE
  51.     movwf   PORTE
  52.     movlw   b'00000000'       ; valor  portA
  53.     movwf   PORTA
  54.     movlw   b'00000000'       ; valor  portB  0 SALIDA---1 ENTRADA
  55.     movwf   PORTB
  56.     movlw   b'10000000'       ; valor  portC
  57.     movwf   PORTC
  58.     movlw   b'00000000'       ; valor  portD
  59.     movwf   PORTD
  60.     movlw   b'00000000'       ; valor  portE
  61.     movwf   PORTE
  62.  
  63. ;*******************************************************************
  64. ; BAUD RATE para la comunicación RS232
  65. ; y otras definiciones para USART
  66. ;*******************************************************************
  67. ; Baud Rate = 9600, Sin Paridad, 1 Bit parada
  68.     movlw   0x19              ; 0x19=9600 bps (0x0C=19200 bps)
  69.     movwf   SPBRG
  70.     movlw   b'00100100'       ;
  71.     movwf   TXSTA             ; habilita la transmisión Async
  72.     bsf     PIE1,RCIE           ;Habilita interrupción en la recepción
  73.     bcf     STATUS,RP0            ; Ir banco 0
  74.     movlw   b'10010000'       ; habilita de recepción Async
  75.     movwf   RCSTA
  76.     bsf     INTCON,PEIE       ;Activa interrupción de periféricos
  77.     bsf     INTCON,GIE        ;Activa interrupciones
  78.          
  79. ;*******************************************************************
  80. ; TIEMPO DE ESTABILIZACION
  81. ;*****************************************************************
  82.            
  83.         clrf    PDel0A
  84.         clrf    PDel1A
  85.         clrf    dato_serie
  86.         clrf    PORTA
  87.         clrf    PORTB
  88.         clrf    PORTC
  89.         clrf    PORTD
  90.         clrf    PORTE
  91.         clrf    contador
  92.         clrf    0x31
  93.         clrf    0x54
  94.         clrf    0x55
  95.         clrf    0x56
  96.  
  97. estab   decfsz  contador,F
  98.         goto    estab
  99.         movf    RCREG,W
  100.         movf    RCREG,W
  101.         movf    RCREG,W             ; vacía el buffer de recepcion
  102.        
  103.         bsf     0x56,6              ;LED_31     ; ESTA EN ALTO PARA PROBAR
  104.        
  105. ;*******************************************************************
  106. ;INICIO
  107. ;*******************************************************************
  108. inicio
  109.         btfsc   0x31,0      ;LED_1
  110.         bsf     PORTA,0
  111.         btfsc   0x31,1      ;LED_2
  112.         bsf     PORTA,1
  113.         btfsc   0x31,2      ;LED_3
  114.         bsf     PORTA,2
  115.         btfsc   0x31,3      ;LED_4
  116.         bsf     PORTA,3
  117.         btfsc   0x31,4      ;LED_5
  118.         bsf     PORTA,4
  119.         btfsc   0x31,5      ;LED_6
  120.         bsf     PORTA,5
  121.         btfsc   0x31,6      ;LED_7
  122.         bsf     PORTE,0
  123.         btfsc   0x31,7      ;LED_8
  124.         bsf     PORTE,1
  125.         btfsc   0x54,0      ;LED_9
  126.         bsf     PORTE,2
  127.         btfsc   0x54,1      ;LED_10
  128.         bsf     PORTC,0
  129.         btfsc   0x54,2      ;LED_11
  130.         bsf     PORTC,1
  131.         btfsc   0x54,3      ;LED_12
  132.         bsf     PORTC,2
  133.         btfsc   0x54,4      ;LED_13
  134.         bsf     PORTC,3
  135.         btfsc   0x54,5      ;LED_14
  136.         bsf     PORTD,0
  137.         btfsc   0x54,6      ;LED_15
  138.         bsf     PORTD,1
  139.         btfsc   0x54,7      ;LED_16
  140.         bsf     PORTB,7
  141.         btfsc   0x55,0      ;LED_17
  142.         bsf     PORTB,6
  143.         btfsc   0x55,1      ;LED_18
  144.         bsf     PORTB,5
  145.         btfsc   0x55,2      ;LED_19
  146.         bsf     PORTB,4
  147.         btfsc   0x55,3      ;LED_20
  148.         bsf     PORTB,3
  149.         btfsc   0x55,4      ;LED_21
  150.         bsf     PORTB,2
  151.         btfsc   0x55,5      ;LED_22
  152.         bsf     PORTB,1
  153.         btfsc   0x55,6      ;LED_23
  154.         bsf     PORTB,0
  155.         btfsc   0x55,7      ;LED_24
  156.         bsf     PORTD,7
  157.         btfsc   0x56,0      ;LED_25
  158.         bsf     PORTD,6
  159.         btfsc   0x56,1      ;LED_26
  160.         bsf     PORTD,5
  161.         btfsc   0x56,2      ;LED_27
  162.         bsf     PORTD,4
  163.         btfsc   0x56,3      ;LED_28
  164.         bsf     PORTC,5
  165.         btfsc   0x56,4      ;LED_29
  166.         bsf     PORTC,4
  167.         btfsc   0x56,5      ;LED_30
  168.         bsf     PORTD,3
  169.         btfsc   0x56,6      ;LED_31
  170.         bsf     PORTD,2
  171.         call    DEMORA1
  172.         call    DEMORA1     ; 300 milisegundos
  173.         call    DEMORA1
  174.         btfsc   0x31,0      ;LED_1
  175.         bcf     PORTA,0
  176.         btfsc   0x31,1      ;LED_2
  177.         bcf     PORTA,1
  178.         btfsc   0x31,2      ;LED_3
  179.         bcf     PORTA,2
  180.         btfsc   0x31,3      ;LED_4
  181.         bcf     PORTA,3
  182.         btfsc   0x31,4      ;LED_5
  183.         bcf     PORTA,4
  184.         btfsc   0x31,5      ;LED_6
  185.         bcf     PORTA,5
  186.         btfsc   0x31,6      ;LED_7
  187.         bcf     PORTE,0
  188.         btfsc   0x31,7      ;LED_8
  189.         bcf     PORTE,1
  190.         btfsc   0x54,0      ;LED_9
  191.         bcf     PORTE,2
  192.         btfsc   0x54,1      ;LED_10
  193.         bcf     PORTC,0
  194.         btfsc   0x54,2      ;LED_11
  195.         bcf     PORTC,1
  196.         btfsc   0x54,3      ;LED_12
  197.         bcf     PORTC,2
  198.         btfsc   0x54,4      ;LED_13
  199.         bcf     PORTC,3
  200.         btfsc   0x54,5      ;LED_14
  201.         bcf     PORTD,0
  202.         btfsc   0x54,6      ;LED_15
  203.         bcf     PORTD,1
  204.         btfsc   0x54,7      ;LED_16
  205.         bcf     PORTB,7
  206.         btfsc   0x55,0      ;LED_17
  207.         bcf     PORTB,6
  208.         btfsc   0x55,1      ;LED_18
  209.         bcf     PORTB,5
  210.         btfsc   0x55,2      ;LED_19
  211.         bcf     PORTB,4
  212.         btfsc   0x55,3      ;LED_20
  213.         bcf     PORTB,3
  214.         btfsc   0x55,4      ;LED_21
  215.         bcf     PORTB,2
  216.         btfsc   0x55,5      ;LED_22
  217.         bcf     PORTB,1
  218.         btfsc   0x55,6      ;LED_23
  219.         bcf     PORTB,0
  220.         btfsc   0x55,7      ;LED_24
  221.         bcf     PORTD,7
  222.         btfsc   0x56,0      ;LED_25
  223.         bcf     PORTD,6
  224.         btfsc   0x56,1      ;LED_26
  225.         bcf     PORTD,5
  226.         btfsc   0x56,2      ;LED_27
  227.         bcf     PORTD,4
  228.         btfsc   0x56,3      ;LED_28
  229.         bcf     PORTC,5
  230.         btfsc   0x56,4      ;LED_29
  231.         bcf     PORTC,4
  232.         btfsc   0x56,5      ;LED_30
  233.         bcf     PORTD,3
  234.         btfsc   0x56,6      ;LED_31
  235.         bcf     PORTD,2
  236.         call    DEMORA1
  237.         call    DEMORA1     ; 300 milisegundos
  238.         call    DEMORA1
  239.         goto    inicio
  240.  
  241. ;******************************************************************************************
  242. ;Tratamiento de la interrupción
  243. ;******************************************************************************
  244. interrup
  245.       btfss   PIR1,RCIF           ;Ha sido interrupción en la recepción ??
  246.       retfie                      ;No, falsa interrupción
  247.       bcf     PIR1,RCIF           ;Si, restaurar el flag de interrupción
  248.       call    recibeRS232         ; sí, hay
  249.       movwf   dato_serie          ; guarda dato (para uso de cualquier rutina)
  250.       goto    testeanumero        ; llama rutina para testear clave
  251.      
  252. ;***********************************************************************************
  253. ; CHEQUEA QUE PIC ES
  254. ;***********************************************************************************
  255.  
  256. testeanumero
  257.            
  258.         movf    dato_serie,w         ; Guarda el contenido de la tecla pulsada.
  259.         xorlw   digito_1            ; ¿Es el pic 1?
  260.         btfsc   STATUS,Z
  261.         goto    pic_1               ; Sí, se procede a chequear el puerto
  262.         retfie
  263. ;***********************************************************************************
  264. ; CHEQUEAR QUE PUERTO ES
  265. ;***********************************************************************************
  266.        
  267. pic_1
  268.         movf     RCREG,W            ; Borra el buffer
  269. loopi   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  270.         goto     loopi              ; no, no llegó
  271.         call     recibeRS232        ; sí, hay
  272.         movwf    dato_serie         ; Guarda el contenido de la tecla pulsada.
  273.         xorlw    puerto_a           ; ¿Es el puerto A?
  274.         btfsc    STATUS,Z
  275.         goto     port_a             ; Sí, se procede a chequear el bit
  276.         retfie
  277.  
  278. ;***********************************************************************************
  279. ; CHEQUEAR QUE BIT ES DEL PUERTO A
  280. ;***********************************************************************************
  281. port_a
  282.         movf     RCREG,W            ; Borra el buffer
  283. loopo   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  284.         goto     loopo              ; no, no llegó
  285.         call     recibeRS232        ; sí, hay
  286.         movwf    dato_serie         ; Guarda el contenido de la tecla pulsada.
  287.         xorlw    digito_0           ; ¿Es la salida 0?
  288.         btfsc    STATUS,Z
  289.         goto     a_0                ; Sí, se procede a chequear la accion
  290.  
  291.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  292.         xorlw    digito_1           ; ¿Es la salida 1?
  293.         btfsc    STATUS,Z
  294.         goto     a_1                ; Sí, se procede a chequear la accion
  295.  
  296.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  297.         xorlw    digito_2           ; ¿Es la salida 2?
  298.         btfsc    STATUS,Z
  299.         goto     a_2                ; Sí, se procede a chequear la accion
  300.         retfie
  301. ;***********************************************************************************
  302. ; CHEQUEAR LA ACCION DEL PUERTO A
  303. ;***********************************************************************************
  304. a_0
  305.         movf     RCREG,W            ; Borra el buffer
  306. loopp   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  307.         goto     loopp              ; no, no llegó
  308.         call     recibeRS232        ; sí, hay
  309.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  310.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  311.         btfsc    STATUS,Z
  312.         bsf      PORTA,0            ;LED_1
  313.  
  314.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  315.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  316.         btfsc    STATUS,Z
  317.         bcf      PORTA,0            ;LED_1  
  318.         bcf      0x31,0
  319.  
  320.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  321.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  322.         btfsc    STATUS,Z
  323.         bsf      0x31,0             ; Sí,
  324.         retfie
  325.  
  326. a_1
  327.         movf     RCREG,W            ; Borra el buffer
  328. l_oopp  btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  329.         goto     l_oopp             ; no, no llegó
  330.         call     recibeRS232        ; sí, hay
  331.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  332.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  333.         btfsc    STATUS,Z
  334.         bsf      PORTA,1            ;LED_2              
  335.                  
  336.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  337.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  338.         btfsc    STATUS,Z
  339.         bcf      PORTA,1            ;LED_2
  340.         bcf      0x31,1
  341.  
  342.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  343.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  344.         btfsc    STATUS,Z
  345.         bsf      0x31,1             ; Sí,
  346.         retfie
  347.  
  348. a_2
  349.         movf     RCREG,W            ; Borra el buffer
  350. lo_opp   btfss   PIR1,RCIF          ; (5) se fija si hay dato RS232
  351.         goto     lo_opp             ; no, no llegó
  352.         call     recibeRS232        ; sí, hay
  353.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  354.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  355.         btfsc    STATUS,Z
  356.         bsf      PORTA,2            ;LED_3            
  357.  
  358.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  359.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  360.         btfsc    STATUS,Z
  361.         bcf      PORTA,2            ;LED_3              ; Sí,
  362.         bcf      0x31,2
  363.  
  364.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  365.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  366.         btfsc    STATUS,Z
  367.         bsf      0x31,2             ; Sí,
  368.         retfie
  369.  
  370. ;***********************************************************************************
  371. ; ENVIA CARACTER SERIE - RS232 - A LA Placa Y ESPERA A QUE HAYA SALIDO
  372. ;***********************************************************************************
  373. enviaRS232
  374.         movwf  TXREG            ; envío el dato en acunulador w
  375.         bsf    STATUS,RP0       ; Pág 1 RAM
  376. Espere  btfss  TXSTA,TRMT       ; transmision completa si es alto
  377.         goto   Espere
  378.         bcf    STATUS,RP0       ; Pág 0 RAM
  379.         return
  380. ;***********************************************************************************
  381. ; RECIBE CARACTER SERIE - RS232 - DESDE LA PC
  382. ;***********************************************************************************
  383.  
  384. recibeRS232
  385.         movf    RCREG,W            ; guarda dato recibido en acumulador
  386.         return
  387.  
  388. ;-------------------------------------------------------------
  389. ; TEMPORIZADOR 100 MS
  390. ;-------------------------------------------------------------
  391. DEMORA1  movlw     .110       ; 1 set numero de repeticion  (B)
  392.          movwf     PDel0A     ; 1 |
  393. PLoop1A  movlw     .181       ; 1 set numero de repeticion  (A)
  394.          movwf     PDel1A     ; 1 |
  395. PLoop2A  clrwdt               ; 1 clear watchdog
  396.          clrwdt               ; 1 ciclo delay
  397.          decfsz    PDel1A,1   ; 1 + (1) es el tiempo 0  ? (A)
  398.          goto      PLoop2A    ; 2 no, loop
  399.          decfsz    PDel0A,1   ; 1 + (1) es el tiempo 0  ? (B)
  400.          goto      PLoop1A    ; 2 no, loop
  401. PDelL1A  goto      PDelL2A    ; 2 ciclos delay
  402. PDelL2A  goto      PDelL3A    ; 2 ciclos delay
  403. PDelL3A  clrwdt               ; 1 ciclo delay
  404.          return               ; 2+2 Fin.
  405.  
  406.     END

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #1 en: 24 de Agosto de 2016, 12:40:57 »
Hola kapotik, No revise el codigo, debido a que lo primero que veo y hay que arreglar es que no estas guardando/retomando los registros W y STATUS en la interrupcion.

Tenes 2 soluciones, la primera es leer el link que te dejo y espero que este explicado el por que debes usarlo:

http://www.todopic.com.ar/foros/index.php?topic=24720.msg201405#msg201405

Y la otra en el datasheet de tu microcontrolador busca W_TEMP y ahi te da el codigo completo que deberias agregar. El cual podrias copiar sin siquiera leer el por que.

--------------------------------

La otra seria bueno que crees un "nombre" para los registros que manejas, para no tener esto:

Código: ASM
  1. clrf    0x54
  2.         clrf    0x55
  3.         clrf    0x56
  4.  
  5.         btfsc   0x31,5      ;LED_6
  6.         bsf     PORTA,5
  7.         btfsc   0x31,6      ;LED_7
  8.         bsf     PORTE,0
  9.         btfsc   0x31,7      ;LED_8
  10.         bsf     PORTE,1
  11.         btfsc   0x54,0      ;LED_9
  12.         bsf     PORTE,2

Y de paso se entenderia mas facil el programa si fuera algo asi (los nombres que use son aleatorios):

Código: ASM
  1. clrf    LEDSPORTA
  2.         clrf    LEDSPORTB
  3.         clrf    LEDSPORTE
  4.  
  5.         btfsc   LEDSPORTA,5      ;LED_6
  6.         bsf     PORTA,5
  7.         btfsc   LEDSPORTE,6      ;LED_7
  8.         bsf     PORTE,0
  9.         btfsc   LEDSPORTE,7      ;LED_8
  10.         bsf     PORTE,1
  11.         btfsc   LEDSPORTE,0      ;LED_9
  12.         bsf     PORTE,2

Obviamente que vas a tener que definir esos nombres con los EQU, como hiciste con el PDel0A por ejemplo.
No solo te va a ayudar a vos, en caso de que lo dejes algun dia y vuelvas con el programa ( ya que no te vas a acordar de que es 0x54 ni 0x31), sino que ademas a aquellos que les estas preguntando van a tener una mejor vision y entendimiento de que quisiste hacer. Y poder llegar a resolver de manera mas rapida tu problema.

----------------

Otra de las cosas que tenes que entender de la USART, es que es uan transmision serie, llega un dato y luego otro, cuando llega por completo es cuando activa la interrupcion, normalmente la velocidad del micro es bastante mayor a lo que llegan los datos, por lo tanto en tu interrupcion tenes que recibir 1 dato y salir, no DEBERIAS quedarte esperando hasta que llegue otro dato. Luego el micro solo cuando llegue otro valor va a entrar de nuevo a la interrupcion. Seguiras guardando datos hasta que llegue algun caracter en especial ( si es que es una trama larga), si es una letra sola lo que envias realizas la accion si es que no lleva demasiado tiempo, si lleva demasiado tiempo tenes que activar un bit y realizarlo en tu loop principal.

PD: No te guies con los programas del PIC16F84 y PIC16F628A  que dio Suky, ahi el omitio la parte de guardar W y STATUS, ya que en su loop principal ( fuera de la interrupcion ) no tiene nada, pero si tenes algo como vos lo tenes, entonces hay que agregarlo.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #2 en: 24 de Agosto de 2016, 13:21:14 »
Gracias killer por siempre ahy, guau, muchas cosas, veo todo lo que me propones y vuelvo!!!

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #3 en: 25 de Agosto de 2016, 01:47:16 »
Modifique  el codigo con la explicacion de suky pero sigo igual

Código: ASM
  1. ;*******************************************************************
  2.  
  3.         LIST P=16F877, R=HEX    ; Usar el PIC16F877A y sistema decimal
  4.  
  5.         #include "P16F877A.INC"  ; Incluye datos de PIC16F877A
  6.  
  7.         __CONFIG   _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _XT_OSC
  8.  
  9.  
  10. ;*******************************************************************
  11. ; CONFIGURACION
  12. ;*******************************************************************
  13.  
  14.  
  15. ;*******************************************************************
  16. ; VARIABLES
  17. ;*******************************************************************
  18. W_Temp      EQU     0x30
  19. STATUS_Temp EQU     0x40
  20. PDel0A      EQU     0x42
  21. PDel1A      EQU     0x43
  22. contador    EQU     0x52        ; variable
  23. dato_serie  EQU     0x53        ; dato serie desde la PC
  24. puerto_a    EQU     'A'         ;puerto A
  25. digito_0    EQU     '0'         ;salida puerto 0
  26. digito_1    EQU     '1'         ;salida puerto 1
  27. digito_2    EQU     '2'         ;salida puerto 2
  28. caracter_q  EQU     'Q'         ;encendido
  29. caracter_w  EQU     'W'         ;apagado
  30. caracter_p  EQU     'P'         ;parpadea
  31. CONF_ADCON1 EQU     b'00000110'         ; Configuracion PORTA E/S digital
  32. ;*******************************************************************
  33.         ORG    0x00            ; El programa empieza en 0x000
  34.         goto   configuracion
  35.         org    0x04            ;Vector de interrupción
  36.         goto   interrup
  37.  
  38. ;******************************************************************
  39.  
  40. configuracion
  41.     bsf     STATUS,RP0            ; Ir banco 1
  42.     bcf     STATUS,RP1      ;xxxxxx
  43.     movlw   b'00000000'       ; valor inicial portA
  44.     movwf   PORTA
  45.     movlw   b'00000000'       ; valor inicial portB
  46.     movwf   PORTB
  47.     movlw   b'00000000'       ; valor inicial portC
  48.     movwf   PORTC
  49.     movlw   b'00000000'       ; valor inicial portD
  50.     movwf   PORTD
  51.     movlw   b'00000000'       ; valor inicial portE
  52.     movwf   PORTE
  53.     movlw   b'00000000'       ; valor  portA
  54.     movwf   PORTA
  55.     movlw   b'00000000'       ; valor  portB  0 SALIDA---1 ENTRADA
  56.     movwf   PORTB
  57.     movlw   b'10000000'       ; valor  portC
  58.     movwf   PORTC
  59.     movlw   b'00000000'       ; valor  portD
  60.     movwf   PORTD
  61.     movlw   b'00000000'       ; valor  portE
  62.     movwf   PORTE
  63.  
  64. ;*******************************************************************
  65. ; BAUD RATE para la comunicación RS232
  66. ; y otras definiciones para USART
  67. ;*******************************************************************
  68. ; Baud Rate = 9600, Sin Paridad, 1 Bit parada
  69.     movlw   0x19              ; 0x19=9600 bps (0x0C=19200 bps)
  70.     movwf   SPBRG
  71.     movlw   b'00100100'       ;
  72.     movwf   TXSTA             ; habilita la transmisión Async
  73.     bsf     PIE1,RCIE           ;Habilita interrupción en la recepción
  74.     bcf     STATUS,RP0            ; Ir banco 0
  75.     movlw   b'10010000'       ; habilita de recepción Async
  76.     movwf   RCSTA
  77.     bsf     INTCON,PEIE       ;Activa interrupción de periféricos
  78.     bsf     INTCON,GIE        ;Activa interrupciones
  79.          
  80. ;*******************************************************************
  81. ; TIEMPO DE ESTABILIZACION
  82. ;*****************************************************************
  83.            
  84.         clrf    PDel0A
  85.         clrf    PDel1A
  86.         clrf    dato_serie
  87.         clrf    PORTA
  88.         clrf    PORTB
  89.         clrf    PORTC
  90.         clrf    PORTD
  91.         clrf    PORTE
  92.         clrf    contador
  93.         clrf    0x31
  94.         clrf    0x54
  95.         clrf    0x55
  96.         clrf    0x56
  97.  
  98. estab   decfsz  contador,F
  99.         goto    estab
  100.         movf    RCREG,W
  101.         movf    RCREG,W
  102.         movf    RCREG,W             ; vacía el buffer de recepcion
  103.        
  104.         bsf     0x56,6              ;LED_31     ; ESTA EN ALTO PARA PROBAR
  105.        
  106. ;*******************************************************************
  107. ;INICIO
  108. ;*******************************************************************
  109. inicio
  110.         btfsc   0x31,0      ;LED_1
  111.         bsf     PORTA,0
  112.         btfsc   0x31,1      ;LED_2
  113.         bsf     PORTA,1
  114.         btfsc   0x31,2      ;LED_3
  115.         bsf     PORTA,2
  116.         btfsc   0x31,3      ;LED_4
  117.         bsf     PORTA,3
  118.         btfsc   0x31,4      ;LED_5
  119.         bsf     PORTA,4
  120.         btfsc   0x31,5      ;LED_6
  121.         bsf     PORTA,5
  122.         btfsc   0x31,6      ;LED_7
  123.         bsf     PORTE,0
  124.         btfsc   0x31,7      ;LED_8
  125.         bsf     PORTE,1
  126.         btfsc   0x54,0      ;LED_9
  127.         bsf     PORTE,2
  128.         btfsc   0x54,1      ;LED_10
  129.         bsf     PORTC,0
  130.         btfsc   0x54,2      ;LED_11
  131.         bsf     PORTC,1
  132.         btfsc   0x54,3      ;LED_12
  133.         bsf     PORTC,2
  134.         btfsc   0x54,4      ;LED_13
  135.         bsf     PORTC,3
  136.         btfsc   0x54,5      ;LED_14
  137.         bsf     PORTD,0
  138.         btfsc   0x54,6      ;LED_15
  139.         bsf     PORTD,1
  140.         btfsc   0x54,7      ;LED_16
  141.         bsf     PORTB,7
  142.         btfsc   0x55,0      ;LED_17
  143.         bsf     PORTB,6
  144.         btfsc   0x55,1      ;LED_18
  145.         bsf     PORTB,5
  146.         btfsc   0x55,2      ;LED_19
  147.         bsf     PORTB,4
  148.         btfsc   0x55,3      ;LED_20
  149.         bsf     PORTB,3
  150.         btfsc   0x55,4      ;LED_21
  151.         bsf     PORTB,2
  152.         btfsc   0x55,5      ;LED_22
  153.         bsf     PORTB,1
  154.         btfsc   0x55,6      ;LED_23
  155.         bsf     PORTB,0
  156.         btfsc   0x55,7      ;LED_24
  157.         bsf     PORTD,7
  158.         btfsc   0x56,0      ;LED_25
  159.         bsf     PORTD,6
  160.         btfsc   0x56,1      ;LED_26
  161.         bsf     PORTD,5
  162.         btfsc   0x56,2      ;LED_27
  163.         bsf     PORTD,4
  164.         btfsc   0x56,3      ;LED_28
  165.         bsf     PORTC,5
  166.         btfsc   0x56,4      ;LED_29
  167.         bsf     PORTC,4
  168.         btfsc   0x56,5      ;LED_30
  169.         bsf     PORTD,3
  170.         btfsc   0x56,6      ;LED_31
  171.         bsf     PORTD,2
  172.         call    DEMORA1
  173.         call    DEMORA1     ; 300 milisegundos
  174.         call    DEMORA1
  175.         btfsc   0x31,0      ;LED_1
  176.         bcf     PORTA,0
  177.         btfsc   0x31,1      ;LED_2
  178.         bcf     PORTA,1
  179.         btfsc   0x31,2      ;LED_3
  180.         bcf     PORTA,2
  181.         btfsc   0x31,3      ;LED_4
  182.         bcf     PORTA,3
  183.         btfsc   0x31,4      ;LED_5
  184.         bcf     PORTA,4
  185.         btfsc   0x31,5      ;LED_6
  186.         bcf     PORTA,5
  187.         btfsc   0x31,6      ;LED_7
  188.         bcf     PORTE,0
  189.         btfsc   0x31,7      ;LED_8
  190.         bcf     PORTE,1
  191.         btfsc   0x54,0      ;LED_9
  192.         bcf     PORTE,2
  193.         btfsc   0x54,1      ;LED_10
  194.         bcf     PORTC,0
  195.         btfsc   0x54,2      ;LED_11
  196.         bcf     PORTC,1
  197.         btfsc   0x54,3      ;LED_12
  198.         bcf     PORTC,2
  199.         btfsc   0x54,4      ;LED_13
  200.         bcf     PORTC,3
  201.         btfsc   0x54,5      ;LED_14
  202.         bcf     PORTD,0
  203.         btfsc   0x54,6      ;LED_15
  204.         bcf     PORTD,1
  205.         btfsc   0x54,7      ;LED_16
  206.         bcf     PORTB,7
  207.         btfsc   0x55,0      ;LED_17
  208.         bcf     PORTB,6
  209.         btfsc   0x55,1      ;LED_18
  210.         bcf     PORTB,5
  211.         btfsc   0x55,2      ;LED_19
  212.         bcf     PORTB,4
  213.         btfsc   0x55,3      ;LED_20
  214.         bcf     PORTB,3
  215.         btfsc   0x55,4      ;LED_21
  216.         bcf     PORTB,2
  217.         btfsc   0x55,5      ;LED_22
  218.         bcf     PORTB,1
  219.         btfsc   0x55,6      ;LED_23
  220.         bcf     PORTB,0
  221.         btfsc   0x55,7      ;LED_24
  222.         bcf     PORTD,7
  223.         btfsc   0x56,0      ;LED_25
  224.         bcf     PORTD,6
  225.         btfsc   0x56,1      ;LED_26
  226.         bcf     PORTD,5
  227.         btfsc   0x56,2      ;LED_27
  228.         bcf     PORTD,4
  229.         btfsc   0x56,3      ;LED_28
  230.         bcf     PORTC,5
  231.         btfsc   0x56,4      ;LED_29
  232.         bcf     PORTC,4
  233.         btfsc   0x56,5      ;LED_30
  234.         bcf     PORTD,3
  235.         btfsc   0x56,6      ;LED_31
  236.         bcf     PORTD,2
  237.         call    DEMORA1
  238.         call    DEMORA1     ; 300 milisegundos
  239.         call    DEMORA1
  240.         goto    inicio
  241.  
  242. ;******************************************************************************************
  243. ;Tratamiento de la interrupción
  244. ;******************************************************************************
  245. interrup
  246.        movwf    W_Temp              ;Copiamos W a un registro temporario
  247.       swapf     STATUS,W            ;Invertimos los nibles del registro STATUS
  248.       movwf     STATUS_Temp         ;Guardo STATUS en un registro temporario
  249.  
  250.       btfss   PIR1,RCIF           ;Ha sido interrupción en la recepción ??
  251.       retfie                      ;No, falsa interrupción
  252.       bcf     PIR1,RCIF           ;Si, restaurar el flag de interrupción
  253.       call    recibeRS232         ; sí, hay
  254.       movwf   dato_serie          ; guarda dato (para uso de cualquier rutina)
  255.       goto    testeanumero        ; llama rutina para testear clave
  256.  
  257.       fin_isr
  258.       swapf     STATUS_Temp,W
  259.       movwf     STATUS
  260.       swapf     W_Temp,f
  261.       swapf     W_Temp,W
  262.       retfie
  263. ;***********************************************************************************
  264. ; CHEQUEA QUE PIC ES
  265. ;***********************************************************************************
  266.  
  267. testeanumero
  268.            
  269.         movf    dato_serie,w         ; Guarda el contenido de la tecla pulsada.
  270.         xorlw   digito_1            ; ¿Es el pic 1?
  271.         btfsc   STATUS,Z
  272.         goto    pic_1               ; Sí, se procede a chequear el puerto
  273.         goto    fin_isr
  274. ;***********************************************************************************
  275. ; CHEQUEAR QUE PUERTO ES
  276. ;***********************************************************************************
  277.        
  278. pic_1
  279.         movf     RCREG,W            ; Borra el buffer
  280. loopi   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  281.         goto     loopi              ; no, no llegó
  282.         call     recibeRS232        ; sí, hay
  283.         movwf    dato_serie         ; Guarda el contenido de la tecla pulsada.
  284.         xorlw    puerto_a           ; ¿Es el puerto A?
  285.         btfsc    STATUS,Z
  286.         goto     port_a             ; Sí, se procede a chequear el bit
  287.         goto        fin_isr
  288.  
  289. ;***********************************************************************************
  290. ; CHEQUEAR QUE BIT ES DEL PUERTO A
  291. ;***********************************************************************************
  292. port_a
  293.         movf     RCREG,W            ; Borra el buffer
  294. loopo   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  295.         goto     loopo              ; no, no llegó
  296.         call     recibeRS232        ; sí, hay
  297.         movwf    dato_serie         ; Guarda el contenido de la tecla pulsada.
  298.         xorlw    digito_0           ; ¿Es la salida 0?
  299.         btfsc    STATUS,Z
  300.         goto     a_0                ; Sí, se procede a chequear la accion
  301.  
  302.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  303.         xorlw    digito_1           ; ¿Es la salida 1?
  304.         btfsc    STATUS,Z
  305.         goto     a_1                ; Sí, se procede a chequear la accion
  306.  
  307.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  308.         xorlw    digito_2           ; ¿Es la salida 2?
  309.         btfsc    STATUS,Z
  310.         goto     a_2                ; Sí, se procede a chequear la accion
  311.         goto         fin_isr
  312. ;***********************************************************************************
  313. ; CHEQUEAR LA ACCION DEL PUERTO A
  314. ;***********************************************************************************
  315. a_0
  316.         movf     RCREG,W            ; Borra el buffer
  317. loopp   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  318.         goto     loopp              ; no, no llegó
  319.         call     recibeRS232        ; sí, hay
  320.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  321.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  322.         btfsc    STATUS,Z
  323.         bsf      PORTA,0            ;LED_1
  324.  
  325.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  326.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  327.         btfsc    STATUS,Z
  328.         bcf      PORTA,0            ;LED_1  
  329.         bcf      0x31,0
  330.  
  331.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  332.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  333.         btfsc    STATUS,Z
  334.         bsf      0x31,0             ; Sí,
  335.         goto        fin_isr
  336.  
  337. a_1
  338.         movf     RCREG,W            ; Borra el buffer
  339. l_oopp  btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  340.         goto     l_oopp             ; no, no llegó
  341.         call     recibeRS232        ; sí, hay
  342.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  343.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  344.         btfsc    STATUS,Z
  345.         bsf      PORTA,1            ;LED_2              
  346.                  
  347.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  348.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  349.         btfsc    STATUS,Z
  350.         bcf      PORTA,1            ;LED_2
  351.         bcf      0x31,1
  352.  
  353.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  354.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  355.         btfsc    STATUS,Z
  356.         bsf      0x31,1             ; Sí,
  357.         goto       fin_isr
  358.  
  359. a_2
  360.         movf     RCREG,W            ; Borra el buffer
  361. lo_opp   btfss   PIR1,RCIF          ; (5) se fija si hay dato RS232
  362.         goto     lo_opp             ; no, no llegó
  363.         call     recibeRS232        ; sí, hay
  364.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  365.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  366.         btfsc    STATUS,Z
  367.         bsf      PORTA,2            ;LED_3            
  368.  
  369.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  370.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  371.         btfsc    STATUS,Z
  372.         bcf      PORTA,2            ;LED_3              ; Sí,
  373.         bcf      0x31,2
  374.  
  375.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  376.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  377.         btfsc    STATUS,Z
  378.         bsf      0x31,2             ; Sí,
  379.         goto       fin_isr
  380.  
  381. ;***********************************************************************************
  382. ; ENVIA CARACTER SERIE - RS232 - A LA Placa Y ESPERA A QUE HAYA SALIDO
  383. ;***********************************************************************************
  384. enviaRS232
  385.         movwf  TXREG            ; envío el dato en acunulador w
  386.         bsf    STATUS,RP0       ; Pág 1 RAM
  387. Espere  btfss  TXSTA,TRMT       ; transmision completa si es alto
  388.         goto   Espere
  389.         bcf    STATUS,RP0       ; Pág 0 RAM
  390.         return
  391. ;***********************************************************************************
  392. ; RECIBE CARACTER SERIE - RS232 - DESDE LA PC
  393. ;***********************************************************************************
  394.  
  395. recibeRS232
  396.         movf    RCREG,W            ; guarda dato recibido en acumulador
  397.         return
  398.  
  399. ;-------------------------------------------------------------
  400. ; TEMPORIZADOR 100 MS
  401. ;-------------------------------------------------------------
  402. DEMORA1  movlw     .110       ; 1 set numero de repeticion  (B)
  403.          movwf     PDel0A     ; 1 |
  404. PLoop1A  movlw     .181       ; 1 set numero de repeticion  (A)
  405.          movwf     PDel1A     ; 1 |
  406. PLoop2A  clrwdt               ; 1 clear watchdog
  407.          clrwdt               ; 1 ciclo delay
  408.          decfsz    PDel1A,1   ; 1 + (1) es el tiempo 0  ? (A)
  409.          goto      PLoop2A    ; 2 no, loop
  410.          decfsz    PDel0A,1   ; 1 + (1) es el tiempo 0  ? (B)
  411.          goto      PLoop1A    ; 2 no, loop
  412. PDelL1A  goto      PDelL2A    ; 2 ciclos delay
  413. PDelL2A  goto      PDelL3A    ; 2 ciclos delay
  414. PDelL3A  clrwdt               ; 1 ciclo delay
  415.          return               ; 2+2 Fin.
  416.  
  417.     END

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #4 en: 25 de Agosto de 2016, 14:37:13 »
Acabo de ver el codigo, lo que intentas hacer vos es un poco mas complicado, cuando posea un tiempo veo si puedo realizar el codigo.
El principal problema que tenes es que te quedas atrapado en la interrupcion esperando la llegada del otro dato, cuando deberias entrar comprobar, guardar y salir. Y sugiere realizar una mquina de estados.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #5 en: 26 de Agosto de 2016, 08:24:16 »
que es para vos una maquina de estado?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #6 en: 26 de Agosto de 2016, 09:10:33 »
Usualmente una variable que mantiene el estado (podes llamarle indice de una tabla) y que segun lo recibido cambie ese Estaod/Indice. Ese estado luego servira en una tabla para realizar distintos saltos a pedazos de codigos gracias a una tabla.


Ejemplo vos esperas algo asi 1A6P

Mi primer estado (valor = 0) es donde no recibi nada y deberias quedar esperando un 1, si NO recibo un 1 salgo y no cambio el estado.
Si recibo un 1, procedo a incrementar el estado (valor = 1) y salir.
Ahora cuando entre a la interrupcion el estado me va a enviar a otro pedazo de codigo, donde espera una letra A, B o el puerto que sea. Ahora mas posibilidades.
- Si llega un A,B o letra de puerto avanzamos de estado (=3), y salgo
- Si llega un 1, que se quede en el estado que esta y salgo ( como si hubieras puesto 11A6P)
- Si llega otra cosa, directamente que ponga el estado en 0 volviendo a pedir el primer numero.

Ahora mi 3er estado buscaria que sea un valor de 0 a 7, si NO lo es pondria el estado a 0 y pediria volver a comenzar, si lo es entonces avanzo estado a 4
4to estado espero el ultimo valor, si es correcto genero lo que se necesite, y si no lo es salgo, en ambos casos pondria estado igual a 0, para que comienze a recibir toda la trama de vuelta.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #7 en: 26 de Agosto de 2016, 09:36:49 »
cual es la diferencia con lo que yo hago?
yo no tengo problema en detectar la trama, el problema es que cada ves que entra en la interrupción y detecta una nueva trama borra todo lo anterior, por ejemplo si recibo 1A0Q, pone en alto
Código: [Seleccionar]
BSF     PORTA,0 o si recibo 1A0P, pone a 1 el registro para luego poder testearlo y saber si tiene que parpadear o no
Código: [Seleccionar]
BSF     0x31,0pero borra el comando anterior, algo debo de estar haciendo mal con la interrupción por que si lo hago sin interrupción funciona, pero tengo que hacerlo con interrupcion por que como ya sabras de la otras manera si no cae en el momento justo no funciona, me llama mucho la atencion que si yo ponga       
Código: [Seleccionar]
BSF     PORTA,0otra instruccion la ponga a cero, para mi el micro se esta reseteando cada vez que entra en la interrupcion             

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #8 en: 26 de Agosto de 2016, 13:28:21 »
La diferencia esta  que:

En tu codigo, tu loop principal (INICIO) , no se va a ejecutar HASTA que termines de recibir toda la trama, es decir si presionas un 1 ( de la trama 1A0Q ) queda encerrado en la interrupcion, y no vuelve hasta que completes enteramente la trama.

La diferencia con lo que YO planteo, es que reciba el dato y proceda a salir de la interrupcion, asi el codigo de tu loop principal, pueda seguir ejecutandose mientras estes entremedio de la trama.


Es muy complicado tratar de hacer un parpadeo de un led cuando esta atrapado el programa en algo asi:

Código: ASM
  1. loopi   btfss    PIR1,RCIF          ; (5) se fija si hay dato RS232
  2.         goto     loopi

Arreglado eso, se podria ver si existe algun problema en el loop principal.
Si yo tuviera que realizar esto tendria:

- Una interrupcion en un timer ( para el parpadeo y es el que te da el tiempo)
- Una interrupcion de la USART

1 Registro por cada Puerto a manejar ( que indica el parpadeo ) es suficiente.

Y ni siquiera tendria loop principal.. seria un loop infinito. Cuando llegan los datos a recibir y se detecta que:
- Si es apagar, Pondria a 0 el bit del registro de parpadeo de ese puerto y ademas pondria a 0 el bit del puerto.
- Si es encender, Pondria a 0 el bit del registro de parpadeo de ese puerto y pondria un 1 en el bit del puerto
- Si es parpadera, Pondria un 1 en el bit del registro de parpadeo de ese puerto.

En la interrupcion del Timer simplmente hacer una XOR del registro con el puerto, aquel bit con 1 es quien va a parpadear. Es todo lo que debe de hacerse en la interrupcion, todo lo demas es de la UART.

Esto te deja para que hagas lo que quieras en el loop principal

---------------------------------------

¿No queres usar la interrupcion de la UART? Move todo el codigo de esa interrupcion al loop principal, ahi no vas a tener problema de que tenes que esperar y que se quede atrapado.
Solo necesitarias la interrupcion del Timer para generar el parpadeo.
Pero creo que tu objetivo es aprender a usar la UART por interrupcion, asi que esto no es valido.
« Última modificación: 26 de Agosto de 2016, 14:04:06 por KILLERJC »

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #9 en: 26 de Agosto de 2016, 13:59:37 »
me parece que en este caso no tiene mucha relevancia ya que 1° solo recibe tramas correctas no hay falsos datos (el programa que envía las tramas también lo e hecho yo) y 2° recepcionar la trama completa no le lleva mas que algunos micro segundos los cuales son totalmente imperceptibles al loop principal, lo único que si podría ser una mejora seria que dentro de la interrupción solo chequeara el primer dato de la trama y saliera, y los demás datos verificarlos fuera de la interrupción.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #10 en: 26 de Agosto de 2016, 14:12:40 »
Entonces si crees que todo es correcto y no te importa que se quede atrapado en la interrupcion solo deberias modificar las cosas asi:

Cambia cada a_x como este:

Código: ASM
  1. a_2
  2.         movf     RCREG,W            ; Borra el buffer
  3. lo_opp   btfss   PIR1,RCIF          ; (5) se fija si hay dato RS232
  4.         goto     lo_opp             ; no, no llegó
  5.         call     recibeRS232        ; sí, hay
  6.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  7.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  8.         btfsc    STATUS,Z
  9.         bsf      PORTA,2            ;LED_3            
  10.  
  11.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  12.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  13.         btfsc    STATUS,Z
  14.         bcf      PORTA,2            ;LED_3              ; Sí,
  15.         bcf      0x31,2
  16.  
  17.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  18.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  19.         btfsc    STATUS,Z
  20.         bsf      0x31,2             ; Sí,
  21.         goto       fin_isr


Por esto:


Código: ASM
  1. P_PORTA         EQU     0x31
  2.  
  3. a_2
  4.         movf     RCREG,W            ; Borra el buffer
  5. lo_opp   btfss   PIR1,RCIF          ; (5) se fija si hay dato RS232
  6.         goto     lo_opp             ; no, no llegó
  7.         call     recibeRS232        ; sí, hay
  8.         movwf    dato_serie         ; Recupera el contenido de la tecla pulsada.
  9.         xorlw    caracter_q         ; ¿Es el caracter Q? ENCENDIDO
  10.         btfsc    STATUS,Z
  11.         bsf      PORTA,2            ;LED_3
  12.         BCF      P_PORTA,2
  13.  
  14.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  15.         xorlw    caracter_w         ; ¿Es el caracter W? APAGADO
  16.         btfsc    STATUS,Z
  17.         bcf      PORTA,2            ;LED_3              ; Sí,
  18.         bcf      P_PORTA,2
  19.        
  20.  
  21.         movf     dato_serie,W       ; Recupera el contenido de la tecla pulsada.
  22.         xorlw    caracter_p         ; ¿Es el caracter P? PARPADEA
  23.         btfsc    STATUS,Z
  24.         BSF      P_PORTA,2             ; Sí,
  25.         goto       fin_isr

Solo agregue una instruccion y luego procedi a ponerle un nombre y no usar 0x31

En tu loop principal deberia quedarte asi:

Código: ASM
  1. Inicio:
  2.         MOVF    P_PORTA, W
  3.         XORWF   PORTA, F
  4.         call    DEMORA1
  5.         call    DEMORA1     ; 300 milisegundos
  6.         call    DEMORA1
  7.         goto    inicio

Es decir se apagaria al recibir el dato o encenderia al recibir el dato, en caso de parpadeo lo tenes ahi realizado en tu loop principal

--------------------------------------------------------------------------------------

Yo me referia algo asi:

Código: ASM
  1. Interrupcion
  2.         ;Guardo Contexto
  3.  
  4.         BTFSC   PIR1, RCIF
  5.         CALL    UART_INT
  6.  
  7.         ;Devuelvo contexto
  8.         RETFIE
  9.  
  10. UART_INT
  11.         MOVWF   ESTADO
  12.         ADDWF   PCL,F
  13.         GOTO    CARACTER_PIC
  14.         GOTO    CARACTER_PORT
  15.         GOTO    CARACTER_BIT
  16.         GOTO    CARACTER_ACTION
  17.  
  18.  
  19. CARACTER_PIC
  20.         MOVF    RCREG, W
  21.         XORLW   '1'
  22.         BTFSS   STATUS, Z
  23.         RETURN
  24.         INCF    ESTADO, F
  25.         RETURN
  26.  
  27. CARACTER_PORT
  28.         MOVF    RCREG, W
  29.         MOVWF   TEMP
  30.         SUBLW   'A'
  31.  
  32.         ;Preguntar si esta entre 'A' y 'D' por ejemplo (Proteccion)
  33.         ;Si no lo esta entonces Estado = 0, y SALIR
  34.  
  35.         ;En caso que sea correcto ( en TEMP debe quedar lo que llego menos 'A' )
  36.         MOVF    TEMP, W
  37.         MOVWF   STATE_PORT
  38.         INCF    ESTADO, F
  39.         RETURN
  40.  
  41. CARACTER_BIT
  42.         MOVF    RCREG, W
  43.         SUBLW   '0'
  44.         MOVWF   TEMP
  45.  
  46.         ;Preguntar si es menor o igual a 7 (Proteccion)
  47.         ; No lo es, Estado = 0, y SALIR
  48.  
  49.         ;Si (Suponiendo que en TEMP queda la resta de lo que llego menos '0' )
  50.         INCF    TEMP, F
  51.         CLRF    STATE_BIT
  52.         BSF     STATUS, C
  53.         RLF     STATE_BIT,F
  54.         DECFSZ  TEMP, F
  55.         GOTO    $-2
  56.         INCF    ESTADO, F
  57.         RETURN
  58.  
  59. CARACTER_ACCION
  60.         MOVF    RCREG, W
  61.         MOVWF   TEMP
  62.         XORLW   'P'
  63.         BTFSC   STATUS,Z
  64.         GOTO    CHAR_ACT_P
  65.         MOVWF   TEMP
  66.         XORLW   'Q'
  67.         BTFSC   STATUS,Z
  68.         GOTO    CHAR_ACT_Q
  69.         MOVWF   TEMP
  70.         XORLW   'W'
  71.         BTFSC   STATUS,Z       
  72.         GOTO    CHAR_ACT_W
  73.         CLRF    ESTADO
  74.         RETURN
  75.  
  76. CHAR_ACT_P      ;Intermitente
  77.  
  78.         MOVF    STATE_PORT, W
  79.         ADDLW   PORTA
  80.         MOVWF   FSR
  81.         MOVF    STATE_BIT, W
  82.         XORWF   INDF, F
  83.         CLRF    ESTADO
  84.         RETURN
  85.  
  86. CHAR_ACT_Q      ; Apagado
  87.  
  88.         MOVF    STATE_PORT, W
  89.         ADDLW   PORTA
  90.         MOVWF   FSR
  91.         COMF    STATE_BIT, W
  92.         ANDWF   INDF, F
  93.         MOVF    STATE_PORT, W
  94.         ADDLW   P_PORTA
  95.         MOVWF   FSR
  96.         COMF    STATE_BIT, W
  97.         ANDWF   INDF, F
  98.         CLRF    ESTADO
  99.         RETURN
  100.  
  101. CHAR_ACT_W      ;Encendido
  102.  
  103.         MOVF    STATE_PORT, W
  104.         ADDLW   PORTA
  105.         MOVWF   FSR
  106.         COMF    STATE_BIT, W
  107.         IORWF   INDF, F
  108.         MOVF    STATE_PORT, W
  109.         ADDLW   P_PORTA
  110.         MOVWF   FSR
  111.         COMF    STATE_BIT, W
  112.         ANDWF   INDF, F
  113.         CLRF    ESTADO
  114.         RETURN
« Última modificación: 26 de Agosto de 2016, 21:07:46 por KILLERJC »

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #11 en: 03 de Septiembre de 2016, 05:21:04 »
hola, vuelvo con algunos avanses,

el pic no se esta reseteando, luego de cargar el codigo completo y de poner todos los led al micro me di cuenta de que funciona, o eso parece, los puertos B, C y D funcionan perfecto, hacen todo lo que quiero, que era encender, apagar o parpadear, los unicos puertos que no andan son el A y el E, haber si le digo que encienda PORTDA,0 lo hace, pero cuando le digo que encienda PORTA,1 lo hace pero apaga el anterior.
 Pensando que podria haber un error en el codigo coloque algo tan simple como esto:

Código: [Seleccionar]
        bsf PORTA,0
call DEMORA_6
bsf PORTA,1
call DEMORA_6
bsf PORTA,2
call DEMORA_6
bsf PORTA,3
call DEMORA_6
bsf PORTA,5
call DEMORA_6
bsf PORTE,0
call DEMORA_6
bsf PORTE,1
call DEMORA_6
bsf PORTE,2
call DEMORA_6
y esto es lo que sucede:



cuando se deberian haber quedado prendidos todos a la vez.

buscando en google encontre la siguiente nota:
Citar
Las lineas cuando actuan como salidas estan <<lacheadas>>, lo que significa que sus patitas sacan el nivel logico que se haya cargado por ultima vez en el Registro "PORTA". La escritura de una puerta implica la operacion <<lectura/modificacion/escritura>>, primero lee la puerta, luego se modifica el valor y finalmente se escribe en el lach de salida.

ahora no creo que no se pueda encender y apagar a discrecion, yo no soy un programador experto en PIC pero si un viejo usuario y es la primera ves que no puedo manipular las salidas a mi antojo, por lo que sospecho que tal vez el problema este en la configuracion de los puertos, cuando lo compilo al codigo el MPLAP me tira varios WARNIG sobre configuraciones fuera de los bancos:

Citar
Message[302] D:\PINBAL.ASM 126 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] D:\PINBAL.ASM 128 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] D:\PINBAL.ASM 129 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] D:\PINBAL.ASM 1470 : Register in operand not in bank 0.  Ensure that bank bits are correct.

el codigo completo


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RX serial
« Respuesta #12 en: 03 de Septiembre de 2016, 10:24:50 »
2 cosas para decirte:

¿Lo pusiste en digital? por que coinciden que esos son analogicos ( ANx ), en el reset comienzan de forma analoga. Para ponerlo como digitales:

Código: ASM
  1. BANKSEL ADCON1          ; A banco 1
  2.         MOVLW   0x07           
  3.         MOVWF   ADCON1          ; Digitales
  4.         BANKSEL PORTA           ; A banco 0


Si no es eso, entonces proba este codigo y fijate si funciona:

Código: ASM
  1. temp EQU 0x70
  2.  
  3.         MOVLW   0x01
  4.         MOVWF   temp
  5.         MOVWF   PORTA
  6. loop
  7.         CALL    DEMORA_6
  8.         RLF     temp, W
  9.         IORLW   temp, F
  10.         MOVF    temp, W
  11.         MOVWF   PORTA
  12.         BTFSS   temp, 7
  13.         GOTO    loop
  14.         CALL    DEMORA_6

Lo que estoy haciendo es crear un registro temp y es donde voy a ir poniendo a 1 los bits, luego pongo todo eso al puerto A

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #13 en: 04 de Septiembre de 2016, 02:42:28 »
solucionado!
era problema de la configuracion de los puertos, cual era, no se, solo copie un proyecto anterior y salio andando.
asi quedo

Código: [Seleccionar]
CONF_ADCON1 EQU b'00000111' ; Configuracion PORTA E/S digital
CONF_CMCON  EQU b'00000111'
;*******************************************************************
        org    0x00            ; El programa empieza en 0x000
        goto   configuracion
        org    0x04            ;Vector de interrupción
        goto   interrup

configuracion
bsf STATUS,RP0 ; Ir banco 1
movlw b'00000000'       ; valor inicial portA
        movwf PORTA
        movlw b'00000000'       ; valor inicial portB
        movwf PORTB
movlw b'00000000'       ; valor inicial portC
        movwf PORTC
        movlw b'00000000'       ; valor inicial portD
        movwf PORTD
movlw b'00000000'       ; valor inicial portE
        movwf PORTE
bcf STATUS,RP1
movlw CONF_ADCON1 ; Configurar el PORTA como digital
movwf ADCON1
        movlw b'00000000' ; valor  portA
        movwf PORTA
        movlw b'00000000' ; valor  portB 0 SALIDA---1 ENTRADA
        movwf PORTB
movlw b'10000000'       ; valor  portC
        movwf PORTC
        movlw b'00000000'       ; valor  portD
        movwf PORTD
movlw b'00000000'       ; valor  portE
        movwf PORTE

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 121
Re:Interrupcion por RX serial
« Respuesta #14 en: 04 de Septiembre de 2016, 03:21:12 »
Ahora quisiera saber si de alguna manera se puede guardar el estado de los pines de los puertos, apagarlos todos un tiempo determinado y luego leer lo que se guardo y ponerlo de nuevo en los puertos?.

Para que se entienda mejor guardar que pines están prendidos y cuales apagados y cuales parpadeando, apagar todo y luego volver todo a como estaba.

saludos


 

anything