elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Informática
| |-+  Electrónica
| | |-+  Problema al programar microcontrolador PIC16F84
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema al programar microcontrolador PIC16F84  (Leído 7,787 veces)
Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Problema al programar microcontrolador PIC16F84
« en: 27 Febrero 2013, 19:09 pm »

Buenas pues tengo un programa que tiene que hacer una suma una multiplicación y una resta (la función es : Y=2(A+B)-C), si el resultado me da correcto siempre y cuando no sea negativo el resultado, por ejemplo hago:Y=2(1+4)-6  me sale 4
pero si hago: Y=2(1+3)-10 me da 252  :o
aqui os dejo el código a ver si veis algo raro:
Código
  1. list p=16F84 ;indicamos el pic que se vaa usar
  2. include "P16F84.INC";indicamos la librería del PIC que tiene que cargar
  3. REGA equ 0x11 ;Damos un nombre a esta posición de memoria REGISTRO A
  4. REGB equ 0x12 ;Damos un nombre a esta posición de memoria REGISTRO B DE USUARIO
  5. REGC equ 0x13 ;Damos un nombre a esta posición de memoria REGISTRO C DE USUARIO
  6. REGY equ 0x14 ;Damos un nombre a esta posición de memoria REGISTRO DE USUARIO DE RESULTADO
  7. REGAUX equ 0x15 ;Este registro lo vamos a usar para almacenar temporalmente resultados de pasos de operaciones intermedias
  8. org 0x00 ;vector de reset
  9. goto inicio
  10. org 0x05 ;el programa empieza en la posición 5 de la memoria
  11.  
  12.  
  13.         ;*********************
  14. ;INICIO DE PROGRAMA
  15.         ;*********************
  16. inicio MOVLW 0X01 ; Como no se puede cargar directamente un valor a una posición de memoria cualquiera, es necesario cargarlo previamente primero en el registro REGW
  17. MOVWF REGA ;Ahora si se puede mover el valor de REGW a una posición de memoria deseada
  18. MOVLW 0X02 ;Con  los siguientes pasa lo mismo
  19. MOVWF REGB
  20. MOVLW 0X0A
  21. MOVWF REGC
  22.  
  23. ;______________________________
  24. BUCLE ; es necesario poner un bucle para que no finalice el programa el programa
  25. ;Suma de A+B
  26. MOVF REGA,0 ;CARGA EL VALOR REGA EN W
  27. ADDWF REGB,0 ;SUMA EL VALOR DE W + REGB Y COMO ES 0 SE GUARDA EN W
  28. MOVWF REGAUX ;EL VALOR DE LA SUMA ESTÁ EN EL REGISTRO AUXILIAR como ahora vamos a necesitar usar el registro REGW lo movemos a una posicón de memoria temporal
  29. ;Multiplicación 2(A+B) ->(A+B)+(A+B)
  30. ADDWF REGAUX,1 ;SUMA EL VALOR DE W + REGAUX Y COMO ES 0 SE GUARDA EN REGAUX. Como el valor de A+B ya lo teníamos en REGW  y tiene el mismo valor que el REGAUX si se suman ambos será como una multiplicación.
  31. MOVF REGC,0 ;CARGA EL VALOR DE REGC EN W PARA PODER HACER LA RESTA  Y=REGAUX-C ya que la instrución hace la resta  en dirección contraria: F-W
  32. ;resta 2(A+B)-C
  33. SUBWF REGAUX,0 ;REALIZA LA RESTA Y LO GUARDA EN W
  34. MOVWF REGY ;CARGAMOS EL RESULTADO EN LA POSICIÓN REGY
  35. GOTO BUCLE ; Devuelve a donde esté la palabra bucle
  36. END ; fin de programa
  37.  
  38.  
  39.  
  40.  


Uso MPLAB para programarlo y simularlo.
Gracias

Fox_Neo[/size]


En línea

Firos
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.410


Enseña lo que sepas... y oculta lo peor...


Ver Perfil
Re: Problema al programar microcontrolador PIC16F84
« Respuesta #1 en: 28 Febrero 2013, 23:02 pm »

Cuantos bits tiene un registro? 8 bits.

2^8 = 256 (contando el 0 sería 255)


Si un registro tiene una cantidad de 2 y tu le restas 4 estará en 254 si no me equivoco.

Ese es el problema que tienes, realmente el programa esta actuando correctamente pero no interpretas bien los datos.

Cuando los datos son negativos (por debajo de 0) y quieres representarlo en decimal tendrías que complementarlo primero.

Ahí lo que estas haciendo primero es sumar 1+3 = 3 y lo guardas en un registro. Ahora sumas lo que hay en W que realmente es 3 y lo vuelves a sumar con lo que hay en el registro y te da 6. Por lo tanto si ahora le restas 10 tendras -4.

256-4=252

Ahora bien, cogemos el 252 y lo pasamos a binario. 11111100

Le damos la vuelta 00000011 y nos da un 3, le sumamos 1 y tenemos el cuatro que te da en ese resultado 00000100.

Esto es complementarlo a dos.


Ahora bien, ¿como saber cuando un resultado es negativo? tienes que comprobar el BIT C de el STATUS. Que cuando se pone a 1 quiere decir que el resultado es negativo.

Creo que el bit C no se pone a cero solo y no puedes editarlo metiendole un cero, pero si puedes hacerlo con la instrucción BCF (bit clear file).


En línea

El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.
Firos
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.410


Enseña lo que sepas... y oculta lo peor...


Ver Perfil
Re: Problema al programar microcontrolador PIC16F84
« Respuesta #2 en: 1 Marzo 2013, 16:23 pm »


Código
  1. list p=16F84
  2. include "P16F84.INC"
  3.  
  4. REGA equ 0x11 ; REGISTRO A
  5. REGB equ 0x12 ; REGISTRO B DE USUARIO
  6. REGC equ 0x13 ; REGISTRO C DE USUARIO
  7. REGAUX equ 0x15 ; REGISTRO TEMPORAL, AL FINAL CONTIENE EL RESULTADO.
  8.  
  9. org 0x00 ;vector de reset
  10. goto inicio
  11.  
  12. org 0x05 ;el programa empieza en la posición 5 de la memoria
  13.  
  14. ; Cargamos registros con los datos.
  15. inicio MOVLW 0X01 ; Carga 01 en W.
  16. MOVWF REGA ; Carga W en REGA
  17. MOVLW 0X02
  18. MOVWF REGB
  19. MOVLW 0X0A
  20. MOVWF REGC
  21.  
  22. ;______________________________
  23. BUCLE ;
  24.  
  25. MOVF REGA,W ; A+B
  26. ADDWF REGB,W ;     "
  27. MOVWF REGAUX ; A+B+A+B -> REGAUX
  28. ADDWF REGAUX,F                 ;      "
  29. MOVF REGC,W ;
  30. SUBWF REGAUX,F ; REGAUX - REGC -> REGAUX
  31. GOTO BUCLE ;
  32.  
  33. END
  34.  
  35.  



Por cierto, volviendo a ver tu código, te recomiendo que si vas a programar en ASM lo hagas lo mas simple posible o cuando empieces a programar con varios modulos (ADC, RS232, I2C, cualquier cosa) te vas a liar con todo.

Empezando por lo más básico, cuando quieras guardar un fichero en W te aconsejo que lo especifiques con W y no con 0, porque sino luego, no lo veras bien (cuando adquieras experiencia sera otra cosa), y lo mismo cuando quieras guardarlo en un mismo fichero.

Por otro lado, consejos. Optimización, cuanto más pequeño sea el programa mejor. Los microchips tienen mucha memoria, pero cuando hagas programas largos una buena optimización es lo mejor, sobre todo cuando usas tablas para sacar caracteres de frases y trabajas sumandole W a PCL, que en un cambio de página puede significar que el programa no te funcione.

Refiriendome a la Optimización: ¿Realmente te hacen falta tantos registros? Te he eliminado el registro final, el registro temporal sera quien lleve el resultado en ultimo momento.

Acostumbrate a mantenerlo siempre lo mas ordenador posible, o no te aclararás ni tu mismo. Te lo digo por pura experiencia.



Un saludo.
« Última modificación: 1 Marzo 2013, 16:25 pm por Firos » En línea

El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.
Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Problema al programar microcontrolador PIC16F84
« Respuesta #3 en: 3 Marzo 2013, 21:13 pm »

Muchas gracias por las respuestas Estamos empezando a programar en ensamblador en la asignatura de Sistemas basados en microprocesadores de la  carrera de industrial de electrónica. Umm algo intuí al dia siguiente de poner mi duda que podría ser lo que me pusiste que como era 256 bits y me daba 252 era la resta de 256-4. ¿Estás seguro de que si da 1 es negativo? . Para comprobarlo hice una operación en la cual me diera  252 y el registro STATUS me daba:00011011 como el último bit es 1 signigica que la operación ha dado  positivo.

 Con el -4 el registro SATUS me da 00011000 como el primer bit es 0 la operación es negativa.


Respecto a lo de  guardar un fichero en W especificarlo  con w en vez de 0 o 1 ¿Te refieres a dejarlo como una variable y luego cargar en el registro w 1 o 0? porque si no no entiendo por ejemplo en REGA,W como se le da la orden de guardarlo en el registro W o en REGA

Muchas graciasa por la ayuda esta es mi segunda práctica y estoy practicando por mi cuenta, también estoy con la 3º practica que nos han mandado  y es algo liosa si veo que no me sale ya pediré ayuda, ya que veo que sabes programar en ASM. :) Gracias por los consejos
En línea

Firos
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.410


Enseña lo que sepas... y oculta lo peor...


Ver Perfil
Re: Problema al programar microcontrolador PIC16F84
« Respuesta #4 en: 7 Marzo 2013, 05:15 am »

Es simple compañero.

En las especificaciones de cada comando te suele poner los bits que se ven afectados del STATUS en caso de realizar una operación y la forma de el comando y su uso.


En el caso de hacer una ADDWF, SWAP, INCF, DECF o cualquier otro comando que te permita guardar en F o en W podras hacerlo de las dos maneras.

Por ejemplo, en el caso de el comando ADDWF:

Sintaxis:
Código:
ADDWF      f,d
Estados afectados: C, DC, Z

El contenido del registro W se suma al registro F. Si "d" es 0, el resultado se almacena en W; si "d" es 1, el resultado se guarda en el registro "f".

Al programar en MPLAB tienes que tener en cuenta que MPLAB interpretara ciertos comandos y los convertirá automaticamente sin problemas a lo que tendrían que ser realmente. Con esto quiero decir, que si tu en el comando de ADDWF pones:

Código:
ADDWF REGX,F -> Suma W con REGX y lo guarda en REGX.

seria lo mismo que poner:

ADDWF REGX,1

Solo que tu, en vez de ver un 1 ves una F y lo identificas mucho mejor.

Podrías hacer lo mismo con el registro W en vez de poner un 0.


La verdad es que de unos PICS a otros varían algunas cosas, pero en los datasheets de cada PIC esta todo. Veras los comandos y los estados afectados al terminar la operación. Cuando termina la operación si ves un estado afectado tendrás que ver por qué ese estado se ve afectado. Es decir, cuando desborda, si rotas un registro con RRF y sale un 1 que se va al C, etc... pero a eso ya llegarás más adelante.

Por eso te digo que en el caso este, como estas realizando una resta, que posiblemente será inferior a 0, tienes que poner una comprobación después de la operación para ver si el estado que te identifica que es negativo está activo.

Termina de testearlo y me cuentas de nuevo. Haz sumas y mira los estados. Haz restas en las que el resultado sea positivo y mira los estados y haz lo mismo con resultados negativos.


Por cierto. Si trabajas normalmente con MPLAB no hace falta que estes cambiando constantemente los numeros dentro de el programa. En esa misma ventana de "File Registers" en la parte de abajo dale a HEX.


Configura los registros de REGX, REGA y tal en las posiciones que te interesen. Por ejemplo en la 30, 40 y el resultado en la 50.

Y hazlo todo con los registros, es decir, muevo el registro A a W, se lo resto a B y lo almaceno en W, luego lo meto en RESU. Algo asi:

Código:
		list p=16f876,	f=INHX8M, r=hex
include "p16f876.inc"

MINU equ 20
SUST equ 30
RESU equ 40

org 0

Inicio         movf SUST,W
subwf MINU,W
movwf RESU


goto Inicio

end


Con esto asi y con la ventana de FILE REGISTERS simplemente tendrás que indicar la cantidad en FILE REGISTERS, das doble click en el registro y pones la cantidad, simulas el programa paso a paso en MPLAB y vas viendo los estados afectados y en las casillas de los registros el resultado.


Por cierto, importante, asegurate también de revisar y borrar los estados afectados después de una operación, porque puede ser que lo siguiente que hagas también dependa de un estado despues de otra acción (aunque no es el caso) y que como esta afectado por la anterior, a lo mejor en esta no se ha visto afectado y te da error. Digamos que en la primera resta te da negativo, los estados se ven afectados y luego en la segunda resta no se ven afectados, como el estado no ha vuelto a su posición inicial el segundo resultado estará mal.


BITS Z, DC y C DE STATUS

Z: Se pone a 1 después de una operación aritmético lógica con resultado 0. Se queda en 0 cuando el resultado lógico es distinto de 0.

DC: Bit de acarreo o debe. Se pone a 1 cuando hay acarreo en el cuarto bit (este no lo usarás prácticamente).

C: Bit de acarreo o debe en las instrucciones ADDWF, ADDLW, SUBLW, SUBWF. Se pone a 1 cuando hay acarreo en el 8 bit.


¿Esto que quiere decir?

- Que en estas operaciones, o en cualquier programa que quieras detectar que es un 0 podrás hacerlo a través de el bit Z de el status con btfsc.

- Compruebas el carry que estará en 0., que se verá afectado después de realizar la resta y tendrás que hacer el "complemento a dos" sobre el resultado que te ha dado para sacar la cantidad exacta. Que es tu caso. Tenías razón. Al estar en 1 indica que es positivo, y al estar en 0 indica que es negativo.



Entonces, en el programa tendríamos que incluir esto:

Código:
		list p=16f876,	f=INHX8M, r=hex
include "p16f876.inc"

MINU equ 21
SUST equ 31
RESU equ 41
SIMB equ  40


org 0

Inicio bcf SIMB,0 ; Borramos indicador de símbolo, que estara en el bit 0 de SIMB.
movf SUST,W ; Movemos el sustraendo a W.
subwf MINU,W ; Restamos sustraendo a minuendo.
movwf RESU ; Guardamos resultado.

btfsc STATUS,C ; ¿Resultado negativo? ¿C=0?
goto Inicio ; No: Vuelve a inicio y hace otra operación.

bsf SIMB,0 ; Si: Incrementa la marca de el símbolo.
movlw b'11111111' ; Es lo mismo que poner 0xFF, la b indica binario.
xorwf RESU,F ; XOR entre F y W, guarda en RESU.
incf RESU,F ; Haciendo XOR con FF le damos la vuelta y sumándole 1 (incrementando 1 con este comando) para terminar el "Complemento a Dos".

goto Inicio ; Vuelve a inicio y hace otra operación.
end


Y, como vemos, he añadido el complemento a 2.


Si te da "11111100" hazle una operación XOR con FF.

11111100
11111111
-----------
00000011

Y le sumas 1, que te dará el cuatro :). No lo he comprobado, pero en teoría debería funcionar. Mañana lo miro, que ya es tarde.


Y ya... rizando el rizo, si sumas dos números que te den un resultado mayor a un byte tendrías que incrementar otro registro al lado de el resultado y... eso ya es otro capítulo.



Vaya testamento... me he liado bastante a escribir. Espero que te haya servido.

Suerte, cualquier duda ya sabes  :)

Un saludo.
« Última modificación: 7 Marzo 2013, 05:51 am por Firos » En línea

El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.
Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Problema al programar microcontrolador PIC16F84
« Respuesta #5 en: 8 Marzo 2013, 17:53 pm »

Muchas gracias por las respuestas  y la explicación tan detallada ;D  ya hice la siguiente practica trataba de usar comparaciones y dependiendo de eso hacer una series de operaciones y que se repitieran  con un  bucle. Si me surgen más dudas ya las iré poniendo.
Gracias :)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Mini-intro al PIC16F84...
Electrónica
BADBYTE-K 3 17,953 Último mensaje 19 Agosto 2008, 03:23 am
por Meta
Programacion del PIC16F84 (ASM)
Electrónica
BADBYTE-K 7 25,874 Último mensaje 16 Diciembre 2010, 16:54 pm
por skapunky
contador con pic16f84
Electrónica
julyos 8 38,509 Último mensaje 27 Junio 2006, 10:09 am
por Syphroot
Ayuda para programar un microcontrolador en asm
Electrónica
taskkill# 3 2,240 Último mensaje 17 Enero 2006, 09:35 am
por Syphroot
microcontrolador P16F877A
Electrónica
toni84 2 2,474 Último mensaje 9 Abril 2006, 19:13 pm
por toni84
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines