Autor Tema: Simulacion pic16f877a  (Leído 2000 veces)

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

Desconectado sarasarixsara

  • PIC10
  • *
  • Mensajes: 6
Simulacion pic16f877a
« en: 29 de Octubre de 2020, 16:56:25 »
Buenas, estoy simulando un seguidor de linea en assembler en proteus, pero al correr el programa una salida titila sin parar tan pronto un sensor cambia de estado, saben esto por que ocurre? De pronto algun bucle o entrada mal inicializada.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Simulacion pic16f877a
« Respuesta #1 en: 29 de Octubre de 2020, 18:24:52 »
Deberias poner el codigo que estas usando, ya que el problema esta ahí

Desconectado sarasarixsara

  • PIC10
  • *
  • Mensajes: 6
Re:Simulacion pic16f877a
« Respuesta #2 en: 29 de Octubre de 2020, 18:31:56 »
Deberias poner el codigo que estas usando, ya que el problema esta ahí

Corresponde a la funciones
1.so's4+s0's3+s1's2
2.s0s4'
3.s2s3'+s4's1+s1's0
4.s0s4'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESSOR 16F877A
#include <xc.inc>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
                                                      ; CONFIGURACION;
CONFIG CP=OFF ; PFM and Data EEPROM code protection disabled
CONFIG DEBUG=OFF ; Background debugger disabled
CONFIG WRT=OFF
CONFIG CPD=OFF
CONFIG WDTE=OFF ; WDT Disabled; SWDTEN is ignored
CONFIG LVP=ON ; Low voltage programming enabled, MCLR pin, MCLRE ignored
CONFIG FOSC=XT
CONFIG PWRTE=ON
CONFIG BOREN=OFF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MEMORIA Y BANCOS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PSECT udata_bank0
max:
 DS 1 ;reserve 1 byte for max
tmp:
 DS 1 ;reserve 1 byte for tmp
PSECT resetVec,class=CODE,delta=2
INISYS:
    ;CAMBIO A BANCO 1
    BCF STATUS, 6
    BSF STATUS, 5 ; Bank1
    ;Declarando solo los bits que se van a usar (5)
    BSF TRISB, 0
    BSF TRISB, 1
    BSF TRISB, 2
    BSF TRISB, 3
    BSF TRISB, 4
    ;Declarando solo los bits que se van a usar (4)
    BCF TRISA, 0
    BCF TRISA, 1
    BCF TRISA, 2
    BCF TRISA, 3
   
    ;REGRESAR A BANCO 0
    BCF STATUS, 5
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CODIGO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
main:
 
   
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOTORI1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     
    ;PRODUCTO1
   
    ;sensor0 negado
    MOVF PORTB,0    ;Mover puertoB a w
    andlw 00000001; mascara para s0
    movwf 22h     ; guardar s0 en 22h
    comf 22h,1    ; s0 negado en 22
   
    ;Sensor4
    MOVF PORTB,0    ;Mover puertoB a w
    andlw 00010000; mascara para s4
    movwf 27h     ; guardar s4 en 21h
    rrf 27h ,1      ; rotar 4 veces
    rrf 27h,1
    rrf 27h,1
    rrf 27h,1
    movf 22h,0
    andwf 27h,1    ; and entre s0negado(22h) y Sensor4(27h) y guardado en 27h
   
    ;PRODUCTO2
    ;Sensor3
     MOVF PORTB,0   ;Mover puertoB a w
    andlw 00001000; mascara para s3
    movwf 23h     ; guardar s3 en 22h
    rrf 23h,1     ;rotar 3 veces y guardar en 23h
    rrf 23h,1     
    rrf 23h,1     
    movf 22h,0      ; traer 22h s0negado
    andwf 23h,1   ; and entre sensor3(23h) y sensor0 negado(22h) guardado en 23h
   
    ;PRODUCTO3
    ;s1 negado
    MOVF PORTB,0    ;Mover puertoB a w
    andlw 00000010; mascara para s1
    movwf 24h     ; guardar s1 en 24h
    rrf 24h,1     ;rotar y guardar en 24h
    comf 24h,1    ; s1 negado en 24
   
    ;Sensor2
     MOVF PORTB,0   ;Mover puertoB a w
    andlw 00000100; mascara para s3
    movwf 25h     ; guardar s3 en 25h
    rrf 25h,1     ;rotar 2 veces y guardar en 25h
    rrf 25h,1     
    movf 24h,0      ; traer 24h s1 negado
    andwf 25h,0   ; and entre 25h y 24h guardado en w
    iorwf 23h,0   ;or entre w (and) y 24h and anterior. guardado en w
    iorwf 27h,1   ;or entre w (acumulado de 2and) y la otra and. todo motor en el 27h
       
   
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOTORI2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  
    ;Sensor 0
    MOVF PORTB,0    ;Mover puertoB a w
    andlw 00000001; mascara para s0
    movwf 20h     ; guardar s0 en 20h
   
   
    ;Sensor4 negado y producto entre s0 y s4
    MOVF PORTB,0    ;Mover puertoB a w
    andlw 00010000; mascara para s4
    movwf 21h     ; guardar s4 en 21h
    rrf 21h,1       ; rotar 4 veces
    rrf 21h,1
    rrf 21h,1
    rrf 21h,1
    comf 21h,1    ; complemento del rotado
    movf 20h,0      ; traer s0
    andwf 21h,1   ;and entre sensor4 negado(21h) y sensor0 (20h) guardado en 21h
   
   
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOTORD1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;**********PRIMER PRODUCTO**********
   ;para seleccionar solo a S2
MOVF   PORTB,0 ; Mover el pto B a W
ANDLW   00000100B   ;mascara para cojer solo S2 
MOVWF   2AH      ; guardar en 2AH _00100
RRF   2AH,1
RRF   2AH,1      ;00001  S2

   
   ;Para seleccionar S3'
MOVF   PORTB,0
ANDLW   00001000B    ;mascara para cojer solo S3
MOVWF   2BH       ; guardar en 2BH _01000
RRF   2BH,1
RRF   2BH,1
RRF   2BH,1       ;       00001
COMF   2BH,1       ;      11110    S3 negado
MOVF   2AH,0       ; mover S2 a W
ANDWF   2BH,1 ; and entre 2AH(S2) Y 2BH(S3') y se guarda en 2BH


;**********SEGUNDO PRODUCTO**********   
   ;para seleccionar S1
MOVF   PORTB,0 ; Mover el pto B a W
ANDLW   00000010B   ;mascara para cojer solo s1
MOVWF   2CH      ; guardar en 2CH _00010
RRF   2CH,1      ;00001   S1
   
   ;Para seleccionar S4'
MOVF   PORTB,0
ANDLW   00010000B   ;mascara para cojer solo S4
MOVWF   2DH       ; guardar en 2DH _10000
RRF   2DH,1
RRF   2DH,1
RRF   2DH,1
RRF   2DH,1       ;    00001
COMF   2DH,1       ;   11110   S4 negado
MOVF   2CH,0       ; mover S1 a W
ANDWF   2DH,1 ; and entre 2CH(S1) Y 2DH(S4') y se guarda en 2DH

   
;**********TERCER PRODUCTO**********
   ;para seleccionar S0
MOVF   PORTB,0 ; Mover el pto B a W
ANDLW   00000001B   ;mascara para cojer solo S0
MOVWF   2EH      ; guardar en 2EH _00001 S0
   
   ;Para seleccionar S1'
   MOVF   PORTB,0 ; Mover el pto B a W
ANDLW   00000010B   ;mascara para cojer solo s1
MOVWF   2FH      ; guardar en 2CH _00010
RRF   2FH,1      ;00001   S1
COMF   2FH,1       ;   11110   S1 negado
MOVF   2FH,0       ; mover S1 negado a W
ANDWF   2EH,1 ; and entre 2FH(S1') Y 2EH(S0) y se guarda en 2EH

   
MOVF   2BH,0 ; Mover el primer producto a W
IORWF   2DH,1 ;OR1 = OR entre produ 1 y produ 2 y se guarda en 2DH
MOVF   2DH,0; mover resultado de OR1 a W
IORWF   2EH,1 ; OR2 = OR entre OR1 y produ 3 y se guarda en 2EH

   
;++++++++++++++++++++++++++S E Ñ A L E2++++++++++++++++++++++++++++++++++++++
   
   
   ;Para seleccionar S0'
MOVF   2EH,0       ; S0 a W
MOVWF   28H       ; guardar 00001 S0 en 28H
COMF   28H,1       ; 11110 S0 negado
   
   ;Para seleccionar S4
MOVF   PORTB,0       ;mover de port B a W
ANDLW   00010000    ;mascara para cojer solo S$
MOVWF   29H       ; llevar 10000 a 29H
RRF   29H,1   
RRF   29H,1
RRF   29H,1
RRF   29H,1       ;00001  S4
MOVF   28H,0
ANDWF   29H,1 ;and entre 28H (S0') y 29H(S4) y se guarda en 29H
;++++++++++++++++++++++++++S E Ñ A L E3++++++++++++++++++++++++++++++++++++++
   
   
;Salida 1
      bcf PORTA,0; Reset el bit 0 de la salida
      BTFSC 27H,0; si el bit 0 del motor I1 es 0, salta
      GOTO OFF; si el bit0 del motor I1 es 1 va a OFF
      GOTO main
   
      OFF:
      BSF PORTA,0
      GOTO main
 
;Salida 2
 
      bcf PORTA,1; Reset el bit 0 de la salida
      BTFSC 21H,0; si el bit 0 del motor I1 es 0, salta
      GOTO OFF1; si el bit0 del motor I1 es 1 va a OFF
      GOTO main
   
      OFF1:
      BSF PORTA,1
      GOTO main
   
;SALIDA_E2:
     BCF       PORTA,2
     BTFSC   2EH,0
     GOTO    OFF1
     GOTO    main
   
   
   OFF2:
     BSF       PORTA,2
     GOTO    main

       
;SALIDA_E3:
    BCF       PORTA,3
    BTFSC   29H,0
    GOTO    OFF1
    GOTO    main
   
   
   OFF3:
     BSF       PORTA,3
     GOTO    main
   

    END

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Simulacion pic16f877a
« Respuesta #3 en: 04 de Noviembre de 2020, 10:32:52 »
Recién tengo un tiempito como para ver el codigo...

Quisiera decirte que tenes muchas ganas de complicarte la existencia programando de esta manera. No es que sea malo, sino que se vuelve "complicado" rápidamente.
Asi que me voy a centrar en esto, en tu forma de programar, debido a que hay muchas cosas a mejorar y hacerlo con el codigo asi me parece que va a complicarse mas la vida, para vos y para los demas que lo vean.


Me refiro a cosas asi....
Código: ASM
  1. ;sensor0 negado
  2.     MOVF PORTB,0    ;Mover puertoB a w
  3.     andlw 00000001; mascara para s0
  4.     movwf 22h     ; guardar s0 en 22h
  5.     comf 22h,1    ; s0 negado en 22

en ves de:
Código: ASM
  1. ;sensor0 negado
  2.     MOVF PORTB, W    ;Mover puertoB a w
  3.     andlw 0x1; mascara para s0
  4.     movwf SENSORES  ; guardar s0 en 22h
  5.     comf SENSORES, F    ; s0 negado en 22

Es decir agrega en udata, SENSORES: DS 1.
Y no tenes que estar pensando en que posiciones de memoria están las cosas, además W y F vienen definidos dentro del xc.inc, lo mismo que las banderas del statuz, Z,C,etc.
Otra cosa... el linker es quien acomoda donde van a estar.. listo, vos te olvidas de esa parte. Si luego vos haces MOVWF 20h tenes un problema!!! porque seguramente 20h este ocupado por alguna variable que lo ocupo el linker.

En realidad existen dos formas de programar:
- Absoluto como lo estas haciendo dentro del código, es decir vos decís donde esta la posición de memoria con la dirección encima. Y vos llevas la cantidad y las posiciones.
- Relativo, que terminas usando un "símbolo" (etiqueta) que hace referencia a una posición de memoria que todavía no esta asignada, que luego el linker es quien dice, esta memoria la voy a poner en 20h porque la tengo libre, y en todos los lugares donde este ese símbolo, se reemplazara por 20h.

Acá estas mezclando las dos formas. Lo de udata como Relativo, y luego escribir la direccion de forma directa como Absoluto.

Por otra parte.. Todo ese código para hacer:

Código: ASM
  1. CLRF  SENSORES
  2. BTFSC PORTB,0
  3. BSF    SENSORES, 1




Código: ASM
  1. ;Sensor4
  2.     MOVF PORTB,0    ;Mover puertoB a w
  3.     andlw 00010000; mascara para s4
  4.     movwf 27h     ; guardar s4 en 21h
  5.     rrf 27h ,1      ; rotar 4 veces
  6.     rrf 27h,1
  7.     rrf 27h,1
  8.     rrf 27h,1
  9.     movf 22h,0
  10.     andwf 27h,1    ; and entre s0negado(22h) y Sensor4(27h) y guardado en 27h

Mucho mas sencillo...
Código: ASM
  1. MOVF  SENSORES, W
  2. BTFSS PORTB,4
  3. ANDLW 0x01
  4. MOVWF Tu_otro_registro

Si estaba en 1, y PORTB,4 en 1, entonces quedara en 1, si estaba en 0 sea cual sea quedara en 0



Pero en fin... todo esto es para errores, estas leyendo multiples veces el PORTB, etc... Mejor cambiar la estrategia

Funcion:
so's4+s0's3+s1's2

Código: ASM
  1. Main:
  2.    ; Esto antes de llamar a tus "productos" o que tengas que leer las entradas
  3.    MOVF  PORTB,W
  4.    MOVWF AUX                        ; Copia de PORTB  UNA SOLA, no hay cambios hasta que pase por todo esto!
  5.    CALL PRIMER_PRODUCTO;
  6.    CALL SEGUNDO_PRODUCTO;
  7.    ; etc....
  8.    RETURN;
  9.  
  10. PRIMER_PRODUCTO:
  11.    CLRF  RESULTADO_0
  12.    BTFSC AUX,0        ;Si es uno (cero negado), ni vale la pena molestarse por S3 y S4, el resultado es 0 con las AND
  13.    GOTO  NEXT_1      
  14.    BTFSC AUX,4        ; Cualquiera que sea uno, simplemente activaria el bit... Fin..
  15.    BSF    RESULTADO_0,0
  16.    BTFSC AUX,3
  17.    BSF    RESULTADO_0,0
  18. NEXT_1
  19.    BTFSS  AUX,1   ; S1 negado, si es 1 (cero negado) salimos, no tiene sentido.
  20.    RETURN
  21.    BTFSC  AUX,2  ; S2.. Si antes quedo un 1 (luego de negarse) y este esta en 1, activamos
  22.    BSF    RESULTADO_0,0
  23.    RETURN

Tus funciones, 2 y 4 son lo mismo.
Y ademas, no hay un retardo ni nada por el estilo que vea... Si es asi, entonces recorda que el micro es algo MUY rapido, con 4Mhz nomas una instruccion le toma entre 1 a 2us

PD: De RESULTADO_0 estamos usando un solo bit, no tiene ni sentido ponerse a hacer tantos registros cuando tenes 7 bits mas para jugar ahi. A no ser que tengas que hacer algo mas.
« Última modificación: 04 de Noviembre de 2020, 10:50:42 por KILLERJC »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Simulacion pic16f877a
« Respuesta #4 en: 04 de Noviembre de 2020, 12:25:35 »
Ahora un par de cosas sobre el programa.

Todo tu programa y los tres bits que te interesan (los resultados de tus productos y señales) guardados en los bits 0,1 y 2 de RESULTADO

Código: ASM
  1. Main:
  2.    ; Esto antes de llamar a tus "productos" o que tengas que leer las entradas
  3.    CLRF  RESULTADO
  4.    MOVF  PORTB,W
  5.    MOVWF AUX                        ; Copia de PORTB  UNA SOLA, no hay cambios hasta que pase por todo esto!
  6.    CALL PRIMER_PRODUCTO;
  7.    CALL SEGUNDO_PRODUCTO;
  8.    CALL TERCER_PRODUCTO;
  9.    CALL SALIDAS
  10.    RETURN;
  11.  
  12. PRIMER_PRODUCTO:
  13.    BTFSC AUX,0        ;Si es uno (cero negado), ni vale la pena molestarse por S3 y S4, el resultado es 0 con las AND
  14.    GOTO  NEXT_1      
  15.    BTFSC AUX,4        ; Cualquiera que sea uno, simplemente activaria el bit... Fin..
  16.    BSF    RESULTADO,0
  17.    BTFSC AUX,3
  18.    BSF    RESULTADO,0
  19. NEXT_1
  20.    BTFSS  AUX,1   ; S1 negado, si es 1 (cero negado) salimos, no tiene sentido.
  21.    RETURN
  22.    BTFSC  AUX,2  ; S2.. Si antes quedo un 1 (luego de negarse) y este esta en 1, activamos
  23.    BSF    RESULTADO,0
  24.    RETURN
  25.  
  26. SEGUNDO_PRODUCTO:
  27.    BTFSS AUX,0        ; S0 = 1
  28.    RETURN      
  29.    BTFSS AUX,4        ; S4= 0
  30.    BSF    RESULTADO,1  ; S0 AND !S4
  31.    RETURN
  32.  
  33. ;s2s3'+s4's1+s1's0
  34.  
  35. TERCER_PRODUCTO:
  36.    BTFSC AUX,1        ;S1 = 1?
  37.    GOTO  NEXT_3      
  38.    BTFSC AUX,0
  39.    BSF   RESULTADO,2       ; S1= 0 y S0= 1
  40. NEXT_2
  41.    BTFSC AUX,3        ;S3 = 1?
  42.    GOTO  NEXT_3      
  43.    BTFSC AUX,2
  44.    BSF   RESULTADO,2       ; S1= 0 y S0= 1  
  45.    RETURN
  46. NEXT_3
  47.    BTFSS  AUX,4  ; S4= 1
  48.    BSF    RESULTADO,2
  49.    GOTO   NEXT_2


Veamos la parte de las salidas...


Código: ASM
  1. ;Salida 1
  2.       bcf PORTA,0;          PORT en 0
  3.       BTFSC 27H,0;
  4.       GOTO OFF;
  5.       GOTO main
  6.    
  7.       OFF:
  8.       BSF PORTA,0    PORT en 1
  9.       GOTO main

Es decir si estaba en 1 la salida, la pones en 0 y supongamos que luego que tenga que activarse de nuevo, pasan 5 instrucciones para volver a ponerse a 1...
Te conviene agarrar un registro... modificarlo, y finalmente ponerlo todo en el puerto al final.


EN FIN:
- Leer las entradas 1 ves por loop del main
- Modificar las salidas 1 ves por loop del main

En un solo punto del programa me refiero