Autor Tema: Seguidor de linea en assembler  (Leído 1405 veces)

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

Desconectado sarasarixsara

  • PIC10
  • *
  • Mensajes: 6
Seguidor de linea en assembler
« en: 26 de Octubre de 2020, 10:48:37 »
Hola a todos, estoy intentando hacer un seguidor de línea con pic16f877a y un puente h en ensamblador. He inicializado las variables pero no estoy segura del resto. donde 0000 detenerse, 0010 giro izq, 1000 giro derecha, 10101 avanzar, 1001 giro brusco der, 0110 giro brusco izq Agradezco su ayuda
   
INI_PUERTOS
   BCF      STATUS,RP1
   BSF      STATUS,RP0   ;BK1
   BCF      OPTION_REG,7   ;PULL-UP
   MOVLW      0FF   ; '11111111'
   MOVWF      TRISB   ;PORT B ENTRADA
   CLRF      TRISA   ;PORT A SALIDA
   BCF      STATUS,RP0   ;BK0

Goto start
   RETURN
   

START
   CALL INI_PUERTOS
   movlw b'00000010'
   btfsc PORTB,1 ; si s1==1
   retlw
   movlw b'00001000'
   btfsc PORTB,3 ; si s3==1
   retlw
   movlw b'00000110'
   btfsc PORTB,0 ; si s0==1
   retlw
   movlw b'00001001'
   btfsc PORTB,4 ; si s4==1
   retlw
   movlw b'00001010'
   btfsc PORTB,2 ; si s2==1
   retlw
   
   GOTO START
END
   
Modificar mensaje

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Seguidor de linea en assembler
« Respuesta #1 en: 26 de Octubre de 2020, 10:52:48 »
Primero: No postear en dos lados lo mismo, no ayuda.

Segundo: ¿Cuál es tu problema/duda?

Desconectado sarasarixsara

  • PIC10
  • *
  • Mensajes: 6
Re:Seguidor de linea en assembler
« Respuesta #2 en: 26 de Octubre de 2020, 11:05:08 »
Primero: No postear en dos lados lo mismo, no ayuda.

Segundo: ¿Cuál es tu problema/duda?

Disculpa.
Mi pregunta es, hay una manera más optimizada de preguntar por los estados?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Seguidor de linea en assembler
« Respuesta #3 en: 26 de Octubre de 2020, 13:29:16 »
Lo que veo mal en tu codigo es:
- Agregar las lineas de inicializacion dentro del loop principal (INI_PUERTOS)
- No se que sentido tiene el RETURN, teniendo un Goto start, antes. Es decir que estarias usando un CALL pero sin un RETURN, lo cual es un problema. Asegurate siempre que si hay un CALL exista un RETURN.
- La forma en que queres "comprobar" el estado del puerto no funciona asi... Por ejemplo si quiero saber si el puerto tiene el valor movlw b'00000010', y solo tengo 4 bits entonces debo:

Código: ASM
  1. MOVF PORTB   ; Muevo el valor del puerto
  2. ANDLW 0x1F   ; Dejo solo los 5 bits que me interesan.
  3. ;Ahora si compruebo si es alguno de los que yo quiero

Citar
Mi pregunta es, hay una manera más optimizada de preguntar por los estados?

Depende de que te referis con optimizado.
Optimizado para velocidad, Optimizado para memoria, lo mejor es comprobar uno por uno, algo parecido a lo que estas haciendo. O ir preguntado por bits.
Por ejemplo

0000 detenerse,
0010 giro izq,
0110 giro brusco izq
1000 giro derecha,
1001 giro brusco der,
10101 avanzar, 

Podes observar que, y hacerlo en este orden:
- Avanzar es el unico que tiene un 1 en el bit 5, entonces no tiene sentido los demas bits. Preguntas por el bit 5, si es si, voy a AVANZAR.
- En cero: detenerse,  es facil de comprobar el cero, voy a DETENERSE
Bit 1 sentido de giro izq, si esta en 1 voy a IZQUIERDA, sino voy a DERECHA (por eliminacion de las demas opciones)
En IZQUIERDA, pregunto por bit 2, para saber si es brusco o no.
En DERECHA, pregunto por bit 0, para saber si es brusco o no.

Es casi un BTFSS en cada caso...

Código: ASM
  1. MOVF PORTB   ; Muevo el valor del puerto
  2. ANDLW 0x1F   ; Dejo solo los 5 bits que me interesan.
  3. MOVWF AUX
  4. BTFSC STATUS, Z
  5. GOTO DETENERSE
  6. BTFSC AUX,5
  7. GOTO AVANZAR
  8. BTFSC AUX,1
  9. GOTO IZQUIERDA
  10. GOTO DERECHA

Lo muevo a un registro que llame AUX, debido a que el PORTx puede cambiar mientras estoy con mi lecturas. Y eso no es conveniente.
Todo esto es suponiendo que los valores no se superponen.
Ya que avanzar y giro derecha brusco juntos darian un resultado que no es distinguible. Y solo podria determinar entre giro derecha , avanzar, pero no el brusco.
Ademas esto no contempla posibles malformaciones de entrada. Sino es ir probando uno a uno.

Optimizado para futuras ampliaciones...

Crearia una tabla, la recorreria, y probaria si hay igualdad, ya con eso tengo una idea de que hacer, ya que se que cual es el indice, donde se produce la coincidencia.
« Última modificación: 26 de Octubre de 2020, 13:31:33 por KILLERJC »

Desconectado sarasarixsara

  • PIC10
  • *
  • Mensajes: 6
Re:Seguidor de linea en assembler
« Respuesta #4 en: 29 de Octubre de 2020, 16:51:49 »
Lo que veo mal en tu codigo es:
- Agregar las lineas de inicializacion dentro del loop principal (INI_PUERTOS)
- No se que sentido tiene el RETURN, teniendo un Goto start, antes. Es decir que estarias usando un CALL pero sin un RETURN, lo cual es un problema. Asegurate siempre que si hay un CALL exista un RETURN.
- La forma en que queres "comprobar" el estado del puerto no funciona asi... Por ejemplo si quiero saber si el puerto tiene el valor movlw b'00000010', y solo tengo 4 bits entonces debo:

Código: ASM
  1. MOVF PORTB   ; Muevo el valor del puerto
  2. ANDLW 0x1F   ; Dejo solo los 5 bits que me interesan.
  3. ;Ahora si compruebo si es alguno de los que yo quiero

Citar
Mi pregunta es, hay una manera más optimizada de preguntar por los estados?

Depende de que te referis con optimizado.
Optimizado para velocidad, Optimizado para memoria, lo mejor es comprobar uno por uno, algo parecido a lo que estas haciendo. O ir preguntado por bits.
Por ejemplo

0000 detenerse,
0010 giro izq,
0110 giro brusco izq
1000 giro derecha,
1001 giro brusco der,
10101 avanzar, 

Podes observar que, y hacerlo en este orden:
- Avanzar es el unico que tiene un 1 en el bit 5, entonces no tiene sentido los demas bits. Preguntas por el bit 5, si es si, voy a AVANZAR.
- En cero: detenerse,  es facil de comprobar el cero, voy a DETENERSE
Bit 1 sentido de giro izq, si esta en 1 voy a IZQUIERDA, sino voy a DERECHA (por eliminacion de las demas opciones)
En IZQUIERDA, pregunto por bit 2, para saber si es brusco o no.
En DERECHA, pregunto por bit 0, para saber si es brusco o no.

Es casi un BTFSS en cada caso...

Código: ASM
  1. MOVF PORTB   ; Muevo el valor del puerto
  2. ANDLW 0x1F   ; Dejo solo los 5 bits que me interesan.
  3. MOVWF AUX
  4. BTFSC STATUS, Z
  5. GOTO DETENERSE
  6. BTFSC AUX,5
  7. GOTO AVANZAR
  8. BTFSC AUX,1
  9. GOTO IZQUIERDA
  10. GOTO DERECHA

Lo muevo a un registro que llame AUX, debido a que el PORTx puede cambiar mientras estoy con mi lecturas. Y eso no es conveniente.
Todo esto es suponiendo que los valores no se superponen.
Ya que avanzar y giro derecha brusco juntos darian un resultado que no es distinguible. Y solo podria determinar entre giro derecha , avanzar, pero no el brusco.
Ademas esto no contempla posibles malformaciones de entrada. Sino es ir probando uno a uno.

Optimizado para futuras ampliaciones...

Crearia una tabla, la recorreria, y probaria si hay igualdad, ya con eso tengo una idea de que hacer, ya que se que cual es el indice, donde se produce la coincidencia.



Muchas gracias, he estado trabajando en el código y he decidido usar funciones lógicas (derivadas de un mapa de Karnaugh) para definir mis motores. Pero al ingresar ese codigo en el pic, en el simulador proteus, siempre que el sensor 1 0 el sensor2 cambia de valor, una salida titila sin parar, no se si se deba a una entrada mal inicializada o algun bucle


 

anything