TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Fedextrem en 02 de Febrero de 2015, 09:42:28

Título: Preguntas sobre assembler
Publicado por: Fedextrem en 02 de Febrero de 2015, 09:42:28
Buenas gente, tengo una duda existencial. Como hago en assembler para preguntar si un dato que ingresa por medio de llaves es entre un valor u otro? Por ejemplo entre 0 y 9 o A(10) y F(15)?

Porque si es entre los primeros tiene que hacer algo diferente a que si es entre los segundos parametros.
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 02 de Febrero de 2015, 11:52:17
De la misma forma que haces para saber si un dato tiene X valor

Restando. Algunos micros tienen set de instrucciones mas complejos que permiten una clara diferenciacion de Mas grande que, Menor que, etc.

Pero si es de lo mas basico, primero restas W - literal = W (SUBLW)y te fijas en las banderas. asi ya tenes si es un valor menor, igual o lo que sea, y luego comprobas por el otro extremo, restando 15 y preguntando si es cero o mayor.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 04 de Febrero de 2015, 01:53:49
Una pregunta, el caso es que yo tengo declaro estas variables
cblock  20H
    pwm_r, pwm_v, pwm_a, W2, Status2, Var_I, Var_C
    endc
la cosa es que los registros Var_I, Var_C, no los reconoce :/ al incrementar Var_I o Var_C no lo hace... me di cuenta cuando corri paso por paso mi programa en proteus.... dejo el codigo por aqui, espero me ayuden!

list p=16f887
    #include   <p16f887.inc>
    __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
   __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V


;------------------------------------------------------------------
;configuro inicio del programa con el vector reset/interrupcion
;*****************************************************************
        org 00H

           goto inicio

     org 04h
        goto inte
;-----------------------------------------------------------------------
; Inicia Programa
; CONFIGURO I/O
;**********************************************************************

inicio
    ;-------------------------------------------------------------------------
; Configuro Variables
;*************************************************************************
    CBLOCK  20H
    pwm_r, pwm_v, pwm_a, W2, Status2, Var_I, Var_C
    endc

     BANKSEL ANSEL
    clrf    ANSELH
    BANKSEL TRISD
    clrf    TRISB
    BANKSEL PORTA
    clrf    PORTB
;---------------------------------------------------------------------
; configuro Interrupcion cada 40us
;*********************************************************************
   
    BANKSEL OPTION_REG
    Movlw   b'00000100'
    Movwf   OPTION_REG
    BANKSEL INTCON
    Movlw   b'10100000'
    Movwf   INTCON
;-------------------------------------------------------------------------
; Defino pin de puertos
;*************************************************************************
    #Define Led_r PORTB,0
    #Define Led_v PORTB,1
    #Define Led_a PORTB,2

;--------------------------------------------------------------------------
; Pregunto la variable "Var_C" para ver en que Var_C me encuentro
;**************************************************************************

Carga_duty
    movlw   0h
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso
    goto    rojo
Reviso
    movlw   .1
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso1
    goto    Azul
Reviso1
    movlw   .2
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso2
    goto    verde
Reviso2
    movlw   .3
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso3
    goto    amarillo
Reviso3
    movlw   .4
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso4
    goto    agua
Reviso4
    movlw   .5
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso5
    goto    magenta
Reviso5
    movlw   .6
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso6
    goto    orange
Reviso6
    movlw   .7
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso7
    goto    bonito
Reviso7
    movlw   .8
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso8
    goto    morado
Reviso8
    movlw   .9
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso9
    goto    marron
Reviso9
    movlw   .10
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso10
    goto    violeta
Reviso10
    movlw   .11
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso11
    goto    oscuro
Reviso11
    movlw   .12
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso12
    goto    verde1
Reviso12
    movlw   .13
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso13
    goto    rosado
Reviso13
    movlw   .14
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Reviso14
    goto    verde2
Reviso14
    movlw   .15
    subwf   Var_C,0
    btfss   STATUS,Z
    goto    Carga_duty
    goto    blanco
;-------------------------------------------------------------------------
; Cargo las variables con los distintos dutys para generar
;los colores correspondientes
;*************************************************************************
rojo
    movlw   .255
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

verde
    movlw   .0
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

Azul
    movlw   .0
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

amarillo
    movlw   .255
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm
agua
    movlw   .0
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

magenta
    movlw   .255
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

orange
    movlw   .255
    movwf   pwm_r
    movlw   .140
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

bonito
    movlw   .0
    movwf   pwm_r
    movlw   .250
    movwf   pwm_v
    movlw   .154
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

morado
    movlw   .147
    movwf   pwm_r
    movlw   .112
    movwf   pwm_v
    movlw   .219
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

marron
    movlw   .139
    movwf   pwm_r
    movlw   .69
    movwf   pwm_v
    movlw   .19
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

violeta
    movlw   .238
    movwf   pwm_r
    movlw   .130
    movwf   pwm_v
    movlw   .238
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

oscuro
    movlw   .25
    movwf   pwm_r
    movlw   .25
    movwf   pwm_v
    movlw   .112
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

verde1
    movlw   .46
    movwf   pwm_r
    movlw   .139
    movwf   pwm_v
    movlw   .87
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

rosado
    movlw   .220
    movwf   pwm_r
    movlw   .20
    movwf   pwm_v
    movlw   .60
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

verde2
    movlw   .144
    movwf   pwm_r
    movlw   .238
    movwf   pwm_v
    movlw   .144
    movwf   pwm_a
    incf    Var_C,0
    goto    Pregunto_Pwm

blanco
    movlw   .255
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    clrf    Var_C
    goto    Pregunto_Pwm

;-------------------------------------------------------------------------
;Pregunto si ya cumplieron los ciclos de trabajo
;**************************************************************************
Pregunto_duty
    movwf    W2
    movf     STATUS,w
    movwf    Status2
;---------------------------------------------------------------------
; Pregunto si Var_I llego a 255
;**********************************************************************
    movlw   .255
    subwf   Var_I,0
    btfss   STATUS,Z
    goto    otro
    clrf    Var_I
;-------------------------------------------------------------------
; devuelvo valor a w y status, tambien pongo en bajo Toif
;****************************************************************
    movf    Status2,w
    movwf   STATUS
    movf    W2,W
    BANKSEL INTCON
    bcf     INTCON,T0IF
    bsf     INTCON,GIE
;---------------------------------------------------------------------
; configuro Interrupcion cada 40us
;*********************************************************************
    BANKSEL OPTION_REG
    Movlw   b'00000100'
    Movwf   OPTION_REG
    goto    Carga_duty

otro
    BANKSEL OPTION_REG
    Movlw   b'00000100'
    Movwf   OPTION_REG
    movf    Status2,W
    movwf   STATUS
    movf    W2,W
    bcf     INTCON,T0IF
    BANKSEL TMR0
    Movlw   .255
    Movwf   TMR0
    retfie

Pregunto_Pwm
    BANKSEL TMR0
    Movlw   .255
    Movwf   TMR0
Pregunto_Pwm1
    movf    pwm_r,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_r
    goto    off_r
off_r
    bsf     Led_r
    goto    Pregunto_v
on_r
    bcf     Led_r
    goto    Pregunto_v

Pregunto_v
    movf    pwm_v,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_v
    goto    off_v
off_v
    bsf     Led_v
    goto    Pregunto_a
on_v
    bcf     Led_v
    goto    Pregunto_a

Pregunto_a
    movf    pwm_a,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_a
    goto    off_a
off_a
    bsf     Led_a
    goto    Pregunto_Pwm1
on_a
    bcf     Led_a
    goto    Pregunto_Pwm1
;--------------------------------------------------------------------
;rutina de interrupcion
;********************************************************************

inte
;---------------------------------------------------------------------
;guardamos registros importantes
;*********************************************************************
    incf    Var_I,f
    goto    Pregunto_duty
    end
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 04 de Febrero de 2015, 03:24:51
Por lo que decis puede ocurrir por 2 cosas:

1- Por los bancos

Citar
   BANKSEL INTCON
    Movlw   b'10100000'
    Movwf   INTCON

No se bien que banco tomara ya que INTCON es accesible de todos los bancos, por ende buscate otro registro que solo pertenesca al banco 0, o fijate en el proteus is cambia el banco a donde corresponde ( banco 0 )

2- Por malas instrucciones:

incf    Var_C,0  es lo mismo que decir  incf Var_C,W

Por lo tanto incrementa y guarda en W, no se salva el valor, deberias poner incf Var_C,F  o incf Var_C,1, de esa forma el resultado se almacena en el registro



Por otra parte todos esos reviso podrias simplificarlo con una tabla

         
Carga_Duty:
        MOVF    Var_C,W
   ADDWF PCL, F
   GOTO  rojo   
   GOTO  Azul
   GOTO  verde
   GOTO  amarillo
        ........ etc

Y seguro que se puede hacer algo parecido con los colores.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 04 de Febrero de 2015, 14:15:59
Esta bien hecha esta resta y suma?

BTFSS PIR1,TXIF
   RETURN;Aca me fijo si es de 0 a 9 asi le sumo 0x30 ('0') o si es una A a F asi le sumo una 'A' a DATO_A_ENVIAR
    MOVF    DATO_A_ENVIAR
    SUBLW   .10
    BTFSC   STATUS,Z ; pregunto por si la resta da 0
    GOTO    SUMO30
    GOTO    SUMOA
    MOVWF TXREG      ;Cargo el valor asi se envia
   RETURN

SUMO30       ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
    ADDLW   0x30
    MOVWF   DATO_A_ENVIAR
    RETURN

SUMOA      ; el dato no es cero por lo tanto sumo A
    ADDLW   0x0A
    MOVWF   DATO_A_ENVIAR
    RETURN
 END

Es cortito pero no estoy seguro de si la estructura esta bien hecha porque casi nunca trabajo con programas asi.
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 04 de Febrero de 2015, 17:48:12
ahi solo estas viendo si el numero es igual a 10
Si quisieras saber si el resultado es negativo deberias de usar el bit Carry.

SUBLW
k - (W) -> (W)

Si k > W .... C = 1 , Z = 0
Si k = W .... C = 1 , Z = 1
Si k < W .... C = 0

es decir:
k >= W ... C = 1
k < W   ... C = 0

Código: [Seleccionar]
   BTFSS PIR1,TXIF
    RETURN;Aca me fijo si es de 0 a 9 asi le sumo 0x30 ('0') o si es una A a F asi le sumo una 'A' a DATO_A_ENVIAR
    MOVF    DATO_A_ENVIAR
    SUBLW   .9
    BTFSC   STATUS,C ; Si esta en 0 es negativo, es decir 9 - DATO_A_ENVIAR = negativo o 9 < DATO_A_ENVIAR  , apartir de 10 se pondria C = 1
    GOTO    SUMO30

SUMOA      ; el dato no es cero por lo tanto sumo A
    MOVF    DATO_A_ENVIAR
    ADDLW   .55 ; 'A' - 10
    MOVWF   DATO_A_ENVIAR
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

SUMO30       ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
    MOVF    DATO_A_ENVIAR
    ADDLW   0x30
    MOVWF   DATO_A_ENVIAR
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

 END

Arregle el codigo por que habia varios errores (aunque asumi unas cosas, de todas formas te digo los errores asi lo acomodas a lo que queres):

1- Estas intruccion jamas se iban a ejecutar, incluso cambiando los GOTO anteriores por CALL iba a hacer que entrara a ambas subrutinas si daba el caso que entra primero en SUMO30.

 MOVWF TXREG      ;Cargo el valor asi se envia
 RETURN

2- Aca tenes un problema:

SUMO30       ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
    ADDLW   0x30
    MOVWF   DATO_A_ENVIAR

Tu problema radica que en W no esta "DATO_A_ENVIAR" sino que te quedo el resto de la resta que hiciste con anterioridad, asi que ese dato no es valido. Ademas no se por que volverlo a cargar en "DATO_A_ENVIAR" .... cuando ya lo sumaste... asi que imagino que esa instruccion debe estar de mas, por las dudas no la quite. ya que no se que funcion cumple.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 04 de Febrero de 2015, 19:19:29
Okey entiendo donde esta mal, la cuestión es que tengo que mandar el dato a los displays y también al tx por eso lo puse dos veces al MOV, esta mal o al código que me corregiste le cambio eso y ya esta?

Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 04 de Febrero de 2015, 19:43:41
Okey entiendo donde esta mal, la cuestión es que tengo que mandar el dato a los displays y también al tx por eso lo puse dos veces al MOV, esta mal o al código que me corregiste le cambio eso y ya esta?

Y el codigo si estaba mal...
Tu codigo jamas escribiria el TXREG, solo verifica si es igual a 10, luego termina guardando en DATO_A_ENVIAR el valor de la resta + '0' o 'A'

El codigo le cambie:

- el valor a restar de 10 a 9,
- la pregunta por el bit carry.
- Quite un return
- cambie de lugares las subrutinas asi habia un GOTO menos.
- puse el MOVWF TXREG en cada subrutina para que se envie el valor, antes no se ejecutaba
- le agregue un MOVF DATO_A_ENVIAR, para cargar nuevamente W con el valor del registro. Para la "A" no es necesario pero por las dudas lo deje.
- el ASCII de la "A" es 0x41 o .65, como el 10 seria la A, le sumo .55

EDIT: Ahora releo la pregunta, entendi otra cosa. Creo que con el codigo como te lo pase deberia andar bien. No se por que pense que me habias preguntado que le habia corregido a tu codigo.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 04 de Febrero de 2015, 22:42:16
Por lo que decis puede ocurrir por 2 cosas:

1- Por los bancos

Citar
   BANKSEL INTCON
    Movlw   b'10100000'
    Movwf   INTCON

No se bien que banco tomara ya que INTCON es accesible de todos los bancos, por ende buscate otro registro que solo pertenesca al banco 0, o fijate en el proteus is cambia el banco a donde corresponde ( banco 0 )

2- Por malas instrucciones:

incf    Var_C,0  es lo mismo que decir  incf Var_C,W

Por lo tanto incrementa y guarda en W, no se salva el valor, deberias poner incf Var_C,F  o incf Var_C,1, de esa forma el resultado se almacena en el registro



Por otra parte todos esos reviso podrias simplificarlo con una tabla

         
Carga_Duty:
        MOVF    Var_C,W
   ADDWF PCL, F
   GOTO  rojo   
   GOTO  Azul
   GOTO  verde
   GOTO  amarillo
        ........ etc

Y seguro que se puede hacer algo parecido con los colores.

con los colores lo he intentado pero no he sabido como hacerlo :/ GRACIAS por la idea con la variable Var_C! la verdad es que no se muy buen como usar las tablas y por ende no se me ocurrio algo asi! :D me facilitaste mucho las cosas  :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: GRACIAS tambien por lo de "W" tienes razon, no se guardaba en la variable el incremento sino en W! q tonta al no fijarme  :oops: :oops: :oops:
Muchisimas gracias por responder :)
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 05 de Febrero de 2015, 19:22:09
Citar
EDIT: Ahora releo la pregunta, entendi otra cosa. Creo que con el codigo como te lo pase deberia andar bien. No se por que pense que me habias preguntado que le habia corregido a tu codigo.

Bueno dale espero tu respuesta!
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 05 de Febrero de 2015, 19:45:57
Citar
EDIT: Ahora releo la pregunta, entendi otra cosa. Creo que con el codigo como te lo pase deberia andar bien. No se por que pense que me habias preguntado que le habia corregido a tu codigo.

Bueno dale espero tu respuesta!

Yo creo que deberia quedar solo 1, solamente el de TXREG
recorda que inicialmente tu "DATOS_A_ENVIAR" tenian el valor en hexa, lo que luego se trato y se envia a TXREG es el dato en ASCII.
Si yo quisiera mostrar en UN SOLO display y estuviera usando un CD4511 por ejemplo quisiera que "DATOS_A_ENVIAR" no se modifique para nada.
Si lo quisiera mostrar en 2 displays ( de forma decimal ) entonces deberia tratar el valor original y pasarlo a BCD.

En fin :
DATOS_A_ENVIAR es tu valor original.
Con ese valor generas el ASCII lo que pones en TXREG
Con ese valor generas el BCD / o directametne lo usas para la salida del CD4511 con un display

Por lo tanto deberias de mantenerlo "intacto" asi que quitaria el MOVWF DATOS_A_ENVIAR en ambos(SUMOA y SUMO30).

Otra de las cosas que no me fije es que deberias asegurarte que DATOS_A_ENVIAR no supere los 15 del hexa, con lo cual antes de realizar la primer resta ( la de restar 9 ) podrias hacer una ANDLW 0x0F y asi te aseguras que sea lo que pase a traves de esa variable se cumpla que no exceda la "F".

Modifique un poco mas el codigo:

Código: [Seleccionar]
ENVIAR_DATO                             ;Aca me fijo si es de 0 a 9 asi le sumo 0x30 ('0') o si es una A a F asi le sumo una 'A' a DATO_A_ENVIAR

    BTFSS TXSTA,TRMT                ; Pregunto por si esta libre el USART para mandar otro dato
    RETURN
    MOVF    DATO_A_ENVIAR
    ANDLW  0x0F
    SUBLW   .9
    BTFSC   STATUS,C ; Si esta en 0 es negativo, es decir 9 - DATO_A_ENVIAR = negativo o 9 < DATO_A_ENVIAR  , apartir de 10 se pondria C = 1
    GOTO    SUMO30

SUMOA      ; el dato no es cero por lo tanto sumo A
    MOVF    DATO_A_ENVIAR
    ADDLW   .55 ; 'A' - 10
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

SUMO30       ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
    MOVF    DATO_A_ENVIAR
    ADDLW   0x30
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

Pregunto por el bit TRMT, este bit esta en 0 cuando esta enviando y en 1 cuando puedo cargar otro valor al UART. Y no uso el flag de interrupcion ( que me obligaba a ponerlo en 0 cada ves que envio ), quite los MOVWF DATO_A_ENVIAR. Y agregue la proteccion para que no supere el valor 15 en decimal (0xF). Con respecto al bit TXSTA.TRMT lo tome de un PIC16F887, no que PIC estas usando, pero seguro que debe haber algo parecido.

Y solo deberias llamar a esta subrutina con un CALL ENVIAR_DATO, obviamente cargando antes el valor de dato_a_enviar con lo que deseas
Luego haras una subrutina para mostrar en los displays,etc.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 09 de Febrero de 2015, 22:11:54
Buenas.. otra vez yo :( la cosa es que se "SUPONE" que i programa debe encender un led rgb con diferentes colores....
asi que hice lo siguiente: el periodo que use fue de 10ms y lo dividi en 255 partes eso me dio  39.21us
que deje en 40 us

declare una interrupcion del Timer0 cada 40 us y a su vez incremente una variable Var_I

ahora cada vez que Var_I = 255 esta variable regresa a 0

asi hice 1 periodo de 10ms

ahora el PWM

si Var_I >= pwm1 ?
si es asi apago el led rojo
si no es asi prendo el led rojo

ahora repeti esto mismo 2 veces mas
.... como tambien debo modificar si el periodo es 10, 20, 0 30 ms.. hice o mismo del principio.. dividi 20ms/255 y asi con todos los tiempos que necesito, y calcule el valor del timer para que cada vez que Var_I llegara a 255 se cumplieran todos estos periodos.....
la cosa es que no se porque las ondas que deberian ser cuadradas, con los diferentes periodos segun yo escoja..... me salen horribles :( o sea, no salen como deberia :( alguna ayuda se les agradeceria :S

PD: gracias a los que me han ayudado

este es el codigo...

    list p=16f887
    #include   <p16f887.inc>
    __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
   __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
       
   ;------------------------------------------------------------------
;configuro inicio del programa con el vector reset/interrupcion
;*****************************************************************
        org 00H

           goto inicio

     org 04h
        goto Interrupcion
;-----------------------------------------------------------------------
; Inicia Programa
; CONFIGURO I/O
;**********************************************************************

inicio
   
;---------------------------------------------------------------------
; configuro Pre-escaler
;*********************************************************************
    clrwdt
    BANKSEL OPTION_REG
    Movlw   b'00000100'
    Movwf   OPTION_REG
    Movlw   b'10100000'
    Movwf   INTCON
    BANKSEL TRISD
    clrf    TRISC
    BANKSEL PORTA
    clrf    PORTC
;-------------------------------------------------------------------------
; Configuro Variables
;*************************************************************************
    CBLOCK  20H
    pwm_r, pwm_v, pwm_a, W2, Status2, Var_I, Var_C, Var_T
    endc
;-------------------------------------------------------------------------
; Defino pin de puertos
;*************************************************************************
    #Define Led_r PORTC,0
    #Define Led_v PORTC,1
    #Define Led_a PORTC,2

;-----------------------------------------------------------------
;Tabla para cargar los valores de Timer que variaran los tiempo
;*****************************************************************
    goto    inicio1
Tiempo
    movf    Var_T,W
    addwf   PCL,F
    retlw   .255    ;10ms
    retlw   .254    ;20ms
    retlw   .252    ;30ms
    retlw   .251    ;40ms
    retlw   .250    ;50ms
    retlw   .249    ;60ms
    retlw   .247    ;70ms
    retlw   .246    ;80ms
    retlw   .245    ;90ms
    retlw   .244    ;100ms = 1s
    retlw   .243    ;110ms
    retlw   .241    ;120ms
    retlw   .240    ;130ms
    retlw   .239    ;140ms
    retlw   .238    ;150ms
    retlw   .236    ;160ms
    retlw   .235    ;170ms
    retlw   .234    ;180ms
    retlw   .233    ;190ms
    retlw   .231    ;200ms = 2s
inicio1
    movlw   .19
    movwf   Var_T
;--------------------------------------------------------------------------
; Pregunto la variable "Var_C" para ver en que color me encuentro
;**************************************************************************
Carga_duty
    movf    Var_C,W
    addwf   PCL, F
    goto    rojo
    goto    Azul
    goto    verde
    goto    amarillo
    goto    agua
    goto    magenta
    goto    orange
    goto    bonito
    goto    morado
    goto    marron
    goto    violeta
    goto    oscuro
    goto    verde1
    goto    rosado
    goto    verde2
    goto    blanco
;-------------------------------------------------------------------------
; Cargo las variables con los distintos dutys para generar
;los colores correspondientes
;*************************************************************************

rojo
    movlw   .255
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

verde
    movlw   .0
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

Azul
    movlw   .0
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

amarillo
    movlw   .255
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm
agua
    movlw   .0
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

magenta
    movlw   .255
    movwf   pwm_r
    movlw   .0
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

orange
    movlw   .255
    movwf   pwm_r
    movlw   .140
    movwf   pwm_v
    movlw   .0
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

bonito
    movlw   .0
    movwf   pwm_r
    movlw   .250
    movwf   pwm_v
    movlw   .154
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

morado
    movlw   .147
    movwf   pwm_r
    movlw   .112
    movwf   pwm_v
    movlw   .219
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

marron
    movlw   .139
    movwf   pwm_r
    movlw   .69
    movwf   pwm_v
    movlw   .19
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

violeta
    movlw   .238
    movwf   pwm_r
    movlw   .130
    movwf   pwm_v
    movlw   .238
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

oscuro
    movlw   .25
    movwf   pwm_r
    movlw   .25
    movwf   pwm_v
    movlw   .112
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

verde1
    movlw   .46
    movwf   pwm_r
    movlw   .139
    movwf   pwm_v
    movlw   .87
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

rosado
    movlw   .220
    movwf   pwm_r
    movlw   .20
    movwf   pwm_v
    movlw   .60
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

verde2
    movlw   .144
    movwf   pwm_r
    movlw   .238
    movwf   pwm_v
    movlw   .144
    movwf   pwm_a
    incf    Var_C
    goto    Pregunto_Pwm

blanco
    movlw   .255
    movwf   pwm_r
    movlw   .255
    movwf   pwm_v
    movlw   .255
    movwf   pwm_a
    clrf    Var_C
    goto    Pregunto_Pwm

;--------------------------------------------------------------------------
; Pregunto que valor tiene la variable "Var_T" para saber cuando durara mi
; Periodo y con eso modificar el valor del Timer0
;*************************************************************************
Pregunto_Pwm
    call    Tiempo
    BANKSEL TMR0
    Movwf   TMR0

Pregunto_Pwm1
    movf    pwm_r,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_r
    goto    off_r
off_r
    bsf     Led_r
    goto    Pregunto_v
on_r
    bcf     Led_r
    goto    Pregunto_v

Pregunto_v
    movf    pwm_v,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_v
    goto    off_v
off_v
    bsf     Led_v
    goto    Pregunto_a
on_v
    bcf     Led_v
    goto    Pregunto_a

Pregunto_a
    movf    pwm_a,0
    subwf   Var_I,0
    btfss   STATUS,C
    goto    on_a
    goto    off_a
off_a
    bsf     Led_a
    goto    Pregunto_Pwm1
on_a
    bcf     Led_a
    goto    Pregunto_Pwm1
;-------------------------------------------------------------------------
;Pregunto si ya cumplieron los ciclos de trabajo
;**************************************************************************
Pregunto_duty
    movwf    W2
    movf     STATUS,w
    movwf    Status2
;---------------------------------------------------------------------
; Pregunto si Var_I llego a 255
;**********************************************************************
    movlw   .255
    subwf   Var_I,0
    btfss   STATUS,Z
    goto    otro
    clrf    Var_I
;-------------------------------------------------------------------
; devuelvo valor a w y status, tambien pongo en bajo Toif
;****************************************************************
    movf    Status2,w
    movwf   STATUS
    movf    W2,W
    bcf     INTCON,T0IF
    bsf     INTCON,GIE
;---------------------------------------------------------------------
; configuro Interrupcion
;*********************************************************************
    goto    Carga_duty

otro
    bcf     INTCON,T0IF
    call    Tiempo
    Movwf   TMR0
    movf    Status2,w
    movwf   STATUS
    movf    W2,W
    retfie

;--------------------------------------------------------------------
;rutina de interrupcion
;********************************************************************

Interrupcion
    incf    Var_I,f
    goto    Pregunto_duty
    end
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 09 de Febrero de 2015, 23:06:42
Tu idea es de realizar un PWM por software

Tu aproximacion es correcta, pero deberias de mantener tu periodo fijo.. es decir 10ms, no se por que cambiarias tu periodo ( frecuencia )

y luego lo unico que modificas es el limite de 0 a 255 para rojo, para verde y para azul. de esa forma pasas a no darle tension al led a darle tension siempre.

La forma de onda obviamente no es cuadrada, estas modificando el ancho del pulso (Pulse Width) Mientras mas grande sea el valor mas cercano a una señal continua es.

Por otro lado veo que estas cargando el valor 255 ( 0xFF ) en el timer, esto significa que apenas cuente 1 solo se produciria la interrupcion. ya que es un contador ascendente, si quisiera que cuente 255 entonces deberia poner 0x01 en el TMR0.
Ojo con eso.. es el complemento a 2. la interrupcion ocurre cuando pasa de 0xFF a 0x00.

Una de las cosas que tenes que tener en cuenta en las interrupciones es que vas a volver a tu programa ( pensalo como un call - return que mete en el programa cuando ocurre algo ).. ejemplo

Código: [Seleccionar]
decf mi_variable
--> Salta a interrupcion
<-- Vuelve de la interrupcion
btfss status,z

Interrupcion
incf otra_variable
retfie

Si hago eso y ocurre la interrupcion donde lo marque... ese INCF me va a modificar los valores del registro STATUS, asi que cuando vuelva y quiera comprobar el flag Z, no voy a estar comprobando el del DECF , sino el del INCF de la rutina de interrupcion.
Por eso mismo se suele guardar el "contexto" al entrar a la interrupcion, esto es guardar lo que esta en el registro W y lo que esta en el registro STATUS. para luego reponerlo cuando salga.

Código: [Seleccionar]
Interrupcion
    incf    Var_I,f
    goto    Pregunto_duty

Otra cosa... asi no funciona la interrupcion.. no podes usar un goto para volver a donde gustes. La interrupcion esta para atender eventos y no afectar el curso del programa.

Código: [Seleccionar]
Interrupcion
  ; Guardo contexto, codigo en el datasheet
  ; Limpio flag de interrupcion
  ; Cargo valor en TMR0 de ser necesario
  INCF  Var_I,F
  ; Devuelvo el contexto
  RETFIE  ; retorna a donde ocurrio la interrupcion y activa nuevamente las interrupciones globales GIE

Con lo cual tu interrupcion seria lo que puse arriba y tu programa algo asi:

Principal:
si Var_I >= pwm_verde ? SI: apago led , NO enciendo led
si Var_I >= pwm_rojo ? SI: apago led , NO enciendo led
si Var_I >= pwm_azul ? SI: apago led , NO enciendo led
Aca pones la condicion para cuando quieras que aumente Var_C, incrementas Var_C y preguntas por los nuevos colores que van a quedar en pwm_verde, pwm_rojo y pwm_azul
GOTO principal.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 10 de Febrero de 2015, 17:16:02
Buenas! El programa tiene un defecto, en una parte donde tengo que tomar los datos para después enviarlos no los esta tomando y no le veo el porque, recibe los datos de llaves en binario y los pasa a bcd para que se vean en los displays. Acá el código:
Código: [Seleccionar]
TOMAR_DATOS
MOVF PORTA ;supongo que esta en el porta el dato en el nibble bajo
        ANDLW 0x0F
MOVWF DATO_A_ENVIAR
        addlw    .256-.10       ; C will be set if number was >= 10
        BTFSC    STATUS,C
        addlw    .6                  ; ...adjust for 10..29
        addlw    -(.256-.10)   ; Back to original value;paso a BCD
        ANDLW 0x0F
        MOVWF UNIDADES
SWAPF DATO_A_ENVIAR,W
        ANDLW 0x0F
        MOVWF DECENAS


Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 10 de Febrero de 2015, 19:39:54
Primero que nada disculpa Fedextrem por si omito algo es que ya no recuerdo exactamente como era tu programa, voy a suponer por lo que recuerdo que los datos se tomaron de las llaves y se guardaron en DATO_A_ENVIAR, y habiamos dicho que DATO_A_ENVIAR se intente mantener lo mas original posible. Ahora que recuerdo un poco mas esta es la parte de donde tomamos los datos y ademas sacamos el BCD de ellos.

Código: [Seleccionar]
       addlw    .256-.10       ; C will be set if number was >= 10
        BTFSC    STATUS,C
        addlw    .6                  ; ...adjust for 10..29
        addlw    -(.256-.10)   ; Back to original value;paso a BCD

Ese codigo toma lo que hay W y luego cuando termina en W queda el codigo BCD, solamente permite 4 bits.

Código: [Seleccionar]
TOMAR_DATOS
MOVF PORTA ;supongo que esta en el porta el dato en el nibble bajo
        ANDLW 0x0F              ; solo dejo pasar el nibble bajo
MOVWF DATO_A_ENVIAR   ; lo guardo en DATO_A_ENVIAR asi las demas subrutinas pueden usar el valor original que se tomo
        addlw    .256-.10       ; Procedo a pasarlo a BCD
        BTFSC    STATUS,C
        addlw    .6                  
        addlw    -(.256-.10)   ; Final del paso a BCD
        MOVWF UNIDADES     ; Utilizo al registro como un registro temporal.  UNIDADES = decenas:unidades
SWAPF  UNIDADES,W  ; Cambio de lugar los nibbles    W = unidades:decenas
        ANDLW 0x0F             ; Elimino las unidades en W, me quedan las decenas ... W = 0:decenas
        MOVWF DECENAS       ; Guardo las decenas
        MOVF UNIDADES        ; Vuelvo a cargar todo el resultado del BCD -> decenas:unidades
        ANDLW 0x0F             ; Elimino las decenas   W = 0:unidades
        MOVWF UNIDADES     ; Guardo las unidades

Es hace que tome el dato del PORTA, guarde las 4 bits de menor peso en DATO_A_ENVIAR asi es tratado en las demas subrutinas y luego lo pasa a BCD y los guarda en DECENAS y UNIDADES

Variables de entrada: Ninguna

Variables de salida:

DATO_A_ENVIAR
DECENAS
UNIDADES



EDIT: ahora vi donde fue, perdon me equivoque en el codigo yo q te habia pasado antes.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 10 de Febrero de 2015, 20:06:29
No hay drama! Lo voy a probar con el que me acabas de corregir y te digo, porque el problema que tenía es que iniciaba el programa y cualquier dato que le mande a través de las llaves no se veía en los displays

Te dejo el programa así tal vez recuerdes un poco mientras pruebo el código:
Código: [Seleccionar]
org 0x00
    NOP
    NOP
    GOTO CONFIGURACION
    org 0x04
    GOTO INTERRUPCION


CONFIGURACION       ; Aca configuro todo (puertos, timers, inicializo todas las  variables a 00 o el valor que tengan, cargo valor de timer y activo interrupciones al ultimo )

BANKSEL PORTA ; SELECT BANK OF PORTA
CLRF PORTA ; INITIALIZE PORTA BY
BANKSEL OSCCON
MOVLW 0X60  ;RELOJ INTERNO 4MHZ
MOVWF OSCCON
; BANKSEL ANSEL ; SELECT BANK OF ADCON1
; MOVLW 0X00  ; CONFIGURE ALL PINS
; MOVWF ANSEL ; AS DIGITAL INPUTS
; BANKSEL TRISA
; MOVLW 0X0F  ; VALUE USED TO
; MOVWF TRISA ; SET RA<7:0> AS INPUTS
; BANKSEL TRISB
         ;   CLRF TRISB
BANKSEL PORTA
            CLRF INTCON
            CALL    TIMER
            BANKSEL DISPLAY1
            MOVLW   .78
            MOVWF   CONTADOR_DISPLAYS
            CLRF    PORTB
            MOVLW   .0
            MOVWF   DISPLAY1
            MOVLW   .0
            MOVWF   DISPLAY2
            CLRF    FLAG

;   BANKSEL   OSCCON
;   MOVLW   0X60   ;RELOJ INTERNO 4MHZ
;   MOVWF   OSCCON
  BANKSEL PORTA       ; BANK0
MOVLW     B'11110000'
MOVWF     PORTA
MOVLW     B'00000011'
MOVWF     PORTB

BANKSEL TRISA       ; BANK1
MOVLW     B'11110000'
MOVWF     TRISA
MOVLW     B'00100111'
MOVWF     TRISB
MOVLW     B'00000000'
MOVWF     ANSEL         ; PORTA INPUTS = DIGITAL NOT ANALOG
;
; BAUD RATE SETTINGS
;
;  BAUD VALUES WITH BRGH = 0
;  ((20000000/9600)/64)-1 = 32
;    MOVLW     D'207'    ;  1200 BAUD @ 16 MHZ FOSC +0.16 ERR
;    MOVLW     D'103'          ;  2400 BAUD @ 16 MHZ FOSC +0.16 ERR
;    MOVLW     D'25'           ;  9600 BAUD @ 16 MHZ FOSC +0.16 ERR
;    MOVLW     D'12'           ; 19200 BAUD @ 16 MHZ FOSC +0.16 ERR
;    MOVLW     D'255'          ;  1200 BAUD @ 20 MHZ FOSC +1.73 ERR
;    MOVLW     D'129'          ;  2400 BAUD @ 20 MHZ FOSC +0.16 ERR
;    MOVLW     D'32'          ;  9600 BAUD @ 20 MHZ FOSC -1.36 ERR
;    MOVLW     D'15'          ; 19200 BAUD @ 20 MHZ FOSC +1.73 ERR

;  BAUD VALUES WITH BRGH = 1
;  ((20000000/9600)/16)-1 = 32
MOVLW     D'25'         ;  9600 BAUD @ 20 MHZ FOSC +0.16 ERR
MOVWF     SPBRG
MOVLW     B'00100100'    ; BRGH = 1
MOVWF     TXSTA           ; ENABLE ASYNC TRANSMISSION, SET BRGH
BANKSEL   RCSTA       ; BANK0
MOVLW     B'10010000'
MOVWF     RCSTA          ; ENABLE ASYNC RECEPTION
MOVF RCREG,W
MOVF RCREG,W
MOVF RCREG,W           ; FLUSH RECEIVE BUFFER

TIMER
            BANKSEL OPTION_REG
            MOVLW       B'00000110'
            MOVWF       OPTION_REG
            BCF INTCON,6             ;INT EXTERNAS
            BSF         INTCON,5              ;TMR0
            BCF         INTCON,4               ;INT RB0
            BCF         INTCON,3               ;INT RB4-RB7
            BCF         INTCON,1            ;BANDERA RB0
            BCF         INTCON,0         ;BANDERA RB4-RB7
            BCF         INTCON,2           ;BANDERA TMROIF
            BSF INTCON,7           ;INT GENERAL
            MOVLW D'217'
            BANKSEL     TMR0
            MOVWF TMR0
            RETURN


    GOTO MAIN


;******COMIENZO DE INTERRUPCION********

INTERRUPCION
;guardo contexto
    SWAPF    STATUS, W       ;Swap status to be saved into W
CLRF     STATUS          ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF    STATUS_TEMP     ;Save status to bank zero STATUS_TEMP register
MOVF     PCLATH, W       ;Only required if using page 1
MOVWF    PCLATH_TEMP     ;Save PCLATH into W
CLRF     PCLATH          ;Page zero, regardless of current page
    CLRF     PORTB
;--------------------------------------------------------------------------
BTFSC PIR1,RCIF ; Pregunto por si llego algo en la UART
    GOTO int_uart
BTFSS INTCON,TMR0IF ; Pregunto si la interrupcion fue del timer
GOTO salir_int ; Aca podria seguir agregando por eso pregunte arriba, y puse el GOTO, sino no hacia flata pregunta si era lo unico 2 que estaba activo
DECF  CONTADOR_DISPLAYS ;Implemento contador por si es muy corta la interrupcion y para hacerla mas larga ( es decir contar la cantidad de interrupciones )
BTFSS STATUS,Z
GOTO salir_int
BSF    FLAG,1 ; mi flag al pasar X veces por aca habilitando que se muestre
MOVLW .217 ; Recargo mi temporizador
MOVWF TMR0
MOVLW .78 ; Recargo mi contador
MOVWF CONTADOR_DISPLAYS
BCF INTCON,TMR0IF
GOTO salir_int

int_uart

BSF FLAG,0 ; mi flag de que llego algo por la UART
        MOVF RCREG ; Limpio el buffer de lectura
        MOVF RCREG ; Limpio el buffer de lectura
        MOVF RCREG ; Limpio el buffer de lectura, 3 por que es posible tener 2 en la FIFO + 1 en el shift register, al vaciar la FIFO se pone a 0 RCIF

salir_int
;devuelvo el contexto------------------------------------
    BCF      INTCON,TMR0IF
    MOVLW    .217
    MOVWF    TMR0
    MOVF     PCLATH_TEMP, W ;Restore PCLATH;
    MOVWF    PCLATH         ;Move W into PCLATH
    SWAPF    STATUS_TEMP, W ;Swap STATUS_TEMP register into W
                                    ;(sets bank to original state)
MOVWF    STATUS         ;Move W into STATUS register
SWAPF    W_TEMP, F ;Swap W_TEMP
SWAPF    W_TEMP, W      ;Swap W_TEMP into W
RETFIE

;******FIN DE INTERRUPCION********

;******COMIENZO DE PROGRAMA PRINCIPAL********

MAIN
CALL TOMAR_DATOS
CALL ENVIAR
CALL MOSTRAR_DISPLAYS
CALL ANIMACION
GOTO MAIN


MOSTRAR_DISPLAYS
BTFSC FLAG,2    ; Con este indico que display estoy mostrando, si esta en 1 significa que es mi 2do display
GOTO  display2

display1
BTFSC FLAG,1    ; Espero hasta que pase el tiempo se ejecute la interrupcion y me habilite la flag sino sigo saliendo
RETURN
BCF  PORTB,2    ;catodo2
MOVF DATO_DECENAS
MOVWF PORTB ; Aca supongo que todo lo demas que no es dato esta en 0
BSF  PORTB,3     ;catodo1
BSF FLAG,2      ; Activo el flag para que pase al otro display ( 2 )
        BCF FLAG,1 ; Desactivo el flag del timer
RETURN

display2
BTFSC FLAG,1
RETURN
BCF  PORTB,3     ;catodo1
MOVF DATO_UNIDADES
MOVWF PORTB ; Aca supongo que todo lo demas que no es dato esta en 0
BSF PORTB,2         ;catodo2
BCF FLAG,2      ; Activo el flag para que pase al otro display ( 1 )
        BCF FLAG,1 ; Desactivo el flag del timer
RETURN


TOMAR_DATOS

MOVF PORTA ;supongo que esta en el porta el dato en el nibble bajo
        ANDLW 0x0F              ; solo dejo pasar el nibble bajo
MOVWF DATO_A_ENVIAR   ; lo guardo en DATO_A_ENVIAR asi las demas subrutinas pueden usar el valor original que se tomo
        addlw    .256-.10       ; Procedo a pasarlo a BCD
        BTFSC    STATUS,C
        addlw    .6                 
        addlw    -(.256-.10)   ; Final del paso a BCD
        MOVWF UNIDADES     ; Utilizo al registro como un registro temporal.  UNIDADES = decenas:unidades
    SWAPF  UNIDADES,W  ; Cambio de lugar los nibbles    W = unidades:decenas
        ANDLW 0x0F             ; Elimino las unidades en W, me quedan las decenas ... W = 0:decenas
        MOVWF DECENAS       ; Guardo las decenas
        MOVF UNIDADES        ; Vuelvo a cargar todo el resultado del BCD -> decenas:unidades
        ANDLW 0x0F             ; Elimino las decenas   W = 0:unidades
        MOVWF UNIDADES     ; Guardo las unidades

ENVIAR

;ENVIAR_DATO                             ;Aca me fijo si es de 0 a 9 asi le sumo 0x30 ('0') o si es una A a F asi le sumo una 'A' a DATO_A_ENVIAR

    BTFSS TXSTA,TRMT                ; Pregunto por si esta libre el USART para mandar otro dato
    RETURN
    MOVF    DATO_A_ENVIAR
    ANDLW  0x0F
    SUBLW   .9
    BTFSC   STATUS,C ; Si esta en 0 es negativo, es decir 9 - DATO_A_ENVIAR = negativo o 9 < DATO_A_ENVIAR  , apartir de 10 se pondria C = 1
    GOTO    SUMO30

SUMOA      ; el dato no es cero por lo tanto sumo A
    MOVF    DATO_A_ENVIAR
    ADDLW   .55 ; 'A' - 10
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

SUMO30       ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
    MOVF    DATO_A_ENVIAR
    ADDLW   0x30
    MOVWF TXREG      ;Cargo el valor asi se envia
    RETURN

ANIMACION
BTFSS FLAG,0
        RETURN
;Aca parecido nomas que deberia contar un poco mas ya que el otro delay es mas corto o directamente aplicar la interrupcion a este.Y el otro no hacerle un "delay"

CLRF     FLAG
            MOVLW    .0
            MOVWF    UNIDADES
            MOVLW    .0
            MOVWF    DECENAS
            GOTO     MULTI

MULTI

            BTFSS    CONTADOR_DISPLAYS,0
            GOTO     SALTO1
            GOTO     DISP1
SALTO1
            BTFSS   CONTADOR_DISPLAYS,1
            GOTO    DISP2
            GOTO    DISP2

DISP1


            BANKSEL UNIDADES
            MOVF    UNIDADES,0
            BANKSEL PORTB
            MOVWF   PORTB

            MOVLW   B'00000010'
            MOVWF   CONTADOR_DISPLAYS
            BSF     PORTB,7
            RETURN
DISP2
            BANKSEL DECENAS
            MOVF    DECENAS,0
            BANKSEL PORTB
            MOVWF   PORTB
            MOVLW   B'00000001'
            MOVWF   CONTADOR_DISPLAYS
            BSF     PORTB,6
            BCF FLAG,0
        RETURN

 END

Los registros ya están declarados en CBLOCK
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 10 de Febrero de 2015, 20:11:40
Lo único que se ve en los displays son dos ceros, el multiplexado esta bien, pero no me toma los datos que le mando desde las llaves y apenas es el principio
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 11 de Febrero de 2015, 02:50:02
- Bueno con el programa que me pasaste veo que en MOSTRAR_DISPLAYS. Usa las variables:    MOVF DATO_DECENAS y como dije la salida de mi codigo es DECENAS lo mismo ocurre para las unidades. Deberias cambiar los nombres de esas variables.

- El codigo que pase le falta el RETURN


- Por otra parte solo vi un pedacito de codigo y me encontre con esto:

Código: [Seleccionar]
MULTI

            BTFSS    CONTADOR_DISPLAYS,0
            GOTO     SALTO1
            GOTO     DISP1
SALTO1
            BTFSS   CONTADOR_DISPLAYS,1
            GOTO    DISP2
            GOTO    DISP2

Si observas SALTO1 sea cual sea la condicion que le de el BTFSS ( si salta o no ) va a ir a DISP2 por lo tanto es lo mismo que si existiera una sola instruccion "GOTO DISP2" , tambien se puede elimitar el GOTO SALTO1  y un equivalente a lo que tenes realizado ahi es :

Código: [Seleccionar]
MULTI

            BTFSS    CONTADOR_DISPLAYS,0
            GOTO     DISP2
            GOTO     DISP1

No me fije si esta bien, solo vi ese detalle. Ahora que lo miro te eproximaste un poco mal al tema de los 0, no necesitas 2 variables ni nada por el estilo, es simplemente poner un 0 a la salida y activar/desactivar los catodos, sin necesidad de tratarlos como 2 displays (sino como 1 solo display). ya que los numeros son iguales.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 11 de Febrero de 2015, 18:03:31
Citar
No me fije si esta bien, solo vi ese detalle. Ahora que lo miro te eproximaste un poco mal al tema de los 0, no necesitas 2 variables ni nada por el estilo, es simplemente poner un 0 a la salida y activar/desactivar los catodos, sin necesidad de tratarlos como 2 displays (sino como 1 solo display). ya que los numeros son iguales.

Bueno cuando tengas un tiempito mira el programa entero y me decís, parece largo pero no es tanto. Y ya arregle la parte que me dijiste
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 11 de Febrero de 2015, 21:37:39
Bueno cuando tengas un tiempito mira el programa entero y me decís, parece largo pero no es tanto. Y ya arregle la parte que me dijiste

Son 274 lineas, 200 si no cuento espacios y algunos comentarios.

Supongo que la parte de enviar el dato funciona bien. Asi que quedan 2 cosas por hacer..

1- Limitar para cuando este la "animacion" de los ceros que la funcion "Mostrar display" y/o las demas funciones se ejecuten cuando este en marcha la animacion esa.
2- Hacer el programa para los ceros, eso es todo.

Suerte haciendolo :), seran 2 lineas para cada subrutina o unas 4 lineas si lo haces en la seccion principal para el punto 1. Y para el punto 2 imagino que no mas de 20 o por ahi cerca.
Título: Re: Preguntas sobre assembler
Publicado por: Fedextrem en 11 de Febrero de 2015, 21:50:29
Igualmente no me esta tomando los datos que le mando por las llaves, me tendría que mostrar el número enviado pero siempre son ceros
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 11 de Febrero de 2015, 22:14:11
debuggealo... usa el stimulus/ o modifica los SFR ) del MPLAB
Paso a paso para ver que este bien el programa y responda como se debe ante cada entrada. Si entra en una seccion que no deberia entrar acorde a tus planes entonces ahi tenes un problema.
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 12 de Febrero de 2015, 10:13:28
Código: ASM
  1. ; *************** Toma de datos y conversion a BCD ********************
  2. ;
  3. ; Registro de entrada: PORTA 3:0
  4. ; Registros de salida: dato original: DATO_A_ENVIAR , BCD: UNIDADES, DECENAS
  5.  
  6. TOMAR_DATOS
  7.  
  8.         BANKSEL PORTA
  9.             MOVF PORTA,W                ;supongo que esta en el porta el dato en el nibble bajo
  10.         ANDLW 0x0F              ; solo dejo pasar el nibble bajo
  11.             MOVWF DATO_A_ENVIAR   ; lo guardo en DATO_A_ENVIAR asi las demas subrutinas pueden usar el valor original que se tomo
  12.         addlw    .256-.10       ; Procedo a pasarlo a BCD
  13.         BTFSC    STATUS,C
  14.         addlw    .6
  15.         addlw    -(.256-.10)   ; Final del paso a BCD
  16.         MOVWF UNIDADES     ; Utilizo al registro como un registro temporal.  UNIDADES = decenas:unidades
  17.             SWAPF  UNIDADES,W  ; Cambio de lugar los nibbles    W = unidades:decenas
  18.         ANDLW 0x0F             ; Elimino las unidades en W, me quedan las decenas ... W = 0:decenas
  19.         MOVWF DECENAS       ; Guardo las decenas
  20.         MOVF UNIDADES,W        ; Vuelvo a cargar todo el resultado del BCD -> decenas:unidades
  21.         ANDLW 0x0F             ; Elimino las decenas   W = 0:unidades
  22.         MOVWF UNIDADES     ; Guardo las unidades
  23.         RETURN
  24.  
  25.  
  26. ; *************** Realiza multiplexado en los displays ********************
  27. ;
  28. ; Registro de entrada: FLAG,2 (flag de displays) , FLAG,1(flag de tiempo), DECENAS y UNIDADES
  29. ; Registros de salida: PORTB 3:0 bits BCD al 4511, PORTB,4 catodo_unidades y PORTB,5 catodo_decenas
  30.  
  31.  
  32. MOSTRAR_DISPLAYS
  33.     BANKSEL PORTA
  34.         BTFSC FLAG,2            ; Con este indico que display estoy mostrando, si esta en 1 significa que es mi 2do display
  35.         GOTO  display2
  36.  
  37. display1
  38.         BTFSS FLAG,1            ; Espero hasta que pase el tiempo se ejecute la interrupcion y me habilite la flag sino sigo saliendo
  39.         RETURN
  40.         BCF  PORTB,4            ; apago catodo_unidades
  41.         MOVF DECENAS,W
  42.         MOVWF PORTB             ; Aca supongo que todo lo demas que no es dato esta en 0
  43.         BSF  PORTB,5            ; enciendo mi diplay de decenas
  44.         BSF FLAG,2              ; Activo el flag para que pase al otro display ( 2 )
  45.     BCF FLAG,1          ; Desactivo el flag del timer
  46.         RETURN
  47.  
  48. display2
  49.         BTFSS FLAG,1
  50.         RETURN
  51.         BCF  PORTB,5            ; apago catodo_decenas
  52.         MOVF UNIDADES,W
  53.         MOVWF PORTB             ; Aca supongo que todo lo demas que no es dato esta en 0
  54.         BSF PORTB,4         ; activo catodo_unidades
  55.         BCF FLAG,2              ; Activo el flag para que pase al otro display ( 1 )
  56.     BCF FLAG,1          ; Desactivo el flag del timer
  57.         RETURN
  58.  
  59.  
  60. ; *************** Enia datos por la UART ********************
  61. ;
  62. ; Registro de entrada: DATOS_A_ENVIAR
  63. ; Registros de salida: Ninguno
  64.  
  65.  
  66. ENVIAR
  67.  
  68.                                 ;Aca me fijo si es de 0 a 9 asi le sumo 0x30 ('0') o si es una A a F asi le sumo una 'A' a DATO_A_ENVIAR
  69.     BANKSEL TXSTA
  70.     BTFSS TXSTA,TRMT            ; Pregunto por si esta libre el USART para mandar otro dato
  71.     RETURN
  72.     BANKSEL PORTA
  73.     MOVF    DATO_A_ENVIAR,W
  74.     ANDLW    0x0F               ; Limito a 15 aunque ya lo hice en tomar_datos
  75.     SUBLW   .9
  76.     BTFSC   STATUS,C            ; Si esta en 0 es negativo, es decir 9 - DATO_A_ENVIAR = negativo o 9 < DATO_A_ENVIAR  , apartir de 10 se pondria C = 1
  77.     GOTO    SUMO30
  78.  
  79. SUMOA                           ; el dato no es cero por lo tanto sumo A
  80.     MOVF    DATO_A_ENVIAR,W
  81.     ADDLW   .55                 ; 'A' - 10
  82.     MOVWF   TXREG               ;Cargo el valor asi se envia
  83.     RETURN
  84.  
  85. SUMO30                          ; el dato que llega es 0 entonces sumo 0x30 a dato a enviar
  86.     MOVF    DATO_A_ENVIAR,W
  87.     ADDLW   0x30
  88.     MOVWF   TXREG               ;Cargo el valor asi se envia
  89.     RETURN
  90.  
  91.  
  92.  
  93. ; *************** Enia datos por la UART ********************
  94. ;
  95. ; Registro de entrada: FLAG,1 (flag de tiempo) y FLAG,0 (indicador de que algo llego)
  96. ; Registros de salida: Ninguno
  97.  
  98.  
  99. ANIMACION
  100.  
  101.     BTFSS FLAG,0                ;Pregunto si algo llego, sino no hago nada.
  102.     RETURN
  103.     RETURN
  104.  
  105.  
  106.  
  107.  
  108.  END

Hasta ahi funciona perfectamente a no ser que tengas algo mal en la rutina de interrupcion/configuracion. La parte de los ceros no esta realizada pero esta facil de hacer (y podes hacerlo de 2 formas, una que siga enviando por UART y la otra que solo haga la animacion).
Problemas que encontre en el codigo que te pase yo:

Faltaron unos BANKSEL
Faltaron un par de ,W en los MOVF ( asumi que los mandaba a W)

Eso me paso por hacerlo en el aire y no mirar el datasheet.

Por tu parte encuentro otras cosas.
TOMAR_DATOS usa los 4 primeros bits del PORTA, aun asi vos los configuraste como salidas.... si los tenes como salida y le pusiste un cero antes, vas a leer 0.
Tambien el que muestra en los displays usa el PORTB de 5:0 esos 6 bits que como se puede ver en el codigo que tenes esta como entradas algunos y no como salida.

Tu codigo:
Código: ASM
  1. MOVLW     B'11110000'
  2.         MOVWF     TRISA
  3.         MOVLW     B'00100111'
  4.         MOVWF     TRISB

Si no podes cambiar eso de orden vas a tener que mostrarlo en otros bits y eso queda pendiente de vos.
Suerte de ahora en adelante. Estudia el codigo, mira donde estas poniendo los datos, etc, no hagas un copy-paste.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 15 de Febrero de 2015, 17:50:54
hola otra vez! gracias por ayuda! ya arregle lo que dijiste, ceo q lo solucione, sin embargo tengo un problema :( no me llega a 5v  la salida! apenas llega a 2,5 .... no se porque! quizas sea algo en el codigo :S espero puedan ayudarme! adjunto codigo!
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 15 de Febrero de 2015, 17:51:33
hola otra vez! gracias por ayuda! ya arregle lo que dijiste, ceo q lo solucione, sin embargo tengo un problema :( no me llega a 5v  la salida! apenas llega a 2,5 .... no se porque! quizas sea algo en el codigo :S espero puedan ayudarme! adjunto codigo!
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 15 de Febrero de 2015, 18:12:02
La solucion mas simple a para saber si es el programa es mirar con un osciloscopio el pin de salida, si cumple o no cuando le pedis el 100% de duty. Fijate en eso y luego si ves que no cumple con ese duty observamos el programa.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 22 de Febrero de 2015, 16:32:29
La solucion mas simple a para saber si es el programa es mirar con un osciloscopio el pin de salida, si cumple o no cuando le pedis el 100% de duty. Fijate en eso y luego si ves que no cumple con ese duty observamos el programa.

listo, el problema era que no mostraba la componente completa DC de la salida del pic, ya sale los 5V.. ahora lo quedo resolver es como hacer que prenda mi led, rgb,, porque cuando conecto todo en fisico no me anda :S al parecer los led, me consumen voltaje, lo que hace que mi onda llegue a 2V.... otra cosa, a travez de la pc, debo enviarle valores a las variables, Var_C,Var_T, para cambiar de colores y hacer que dure un tiempo determinado.... la cosa es que no se como hacerlo, reviso y sale algo de como enviar txtos.... pero y quiero enviar numeros, o sea, crear un menu que me pida los valores de Var_C,Var_T para variar loc colores y los tiempos..... tengo el MAXr232, pero sinceramente solo se, que debo conectar el TX del DB9 al RX del pic y viceversa.... gracias por su ayuda, aca el codigo!


hola! mi preguta es la siguiente, como uedo enviar datos al pic desde la pc, lo que quiero es enviar por ejplo,mel numero 1, al cierta variable que tengo en mi programa, la idea es que a travez del teclado mande el numero 1 al pic, este lo guarde en la variable que quiero y luego haga lo que debe hacer.... tengo la tabla ASCII, pero la verdad no tengo mucha idea de como hacerlo. GRACIAS! mi pic es el 16f887 y trabajo en ASM....este el el codigo


;-----------------------------------------------------------------------------------------------------------
; Proyecto: Secuencia 16 colores
; Autor: Lab de digitales2
; Fecha: 2014-2015
; Micro: PIC16F887
; Clock: oscilador interno 4MHz
;-----------------------------------------------------------------------------------------------------------
list p=16f887
#include <p16f887.inc>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
;------------------------------------------------------------------
;configuro inicio del programa con el vector reset/interrupcion
;************************************************* ****************
org 00H
goto inicio

org 04h
goto Interrupcion
;-----------------------------------------------------------------------
; Inicia Programa
; CONFIGURO I/O
;************************************************* *********************
inicio
;-------------------------------------------------------------------------
; Configuro Variables
;************************************************* ************************
CBLOCK 20H
pwm_r, pwm_v, pwm_a ; variables para saber si ya se cumplio mi Ton
W2, Status2 ; variables de respaldo
Var_1,Var_2,Var_3 ; variables para saber si ya se cumplieron los ciclos de trabajo
Var_C ; variable para saber en que color estoy
cont1 ; variable que decremento para saber si ya cumpli tiempo
Var_T ; esta variable se cargara con 1, para T=10ms, 2 para T=20ms... 200 para T=2s
ENDC
;---------------------------------------------------------------------
; configuro Interrupcion cada 40us
;************************************************* ********************
BANKSEL OPTION_REG
Movlw b'00000010'
Movwf OPTION_REG
Movlw b'10100000'
Movwf INTCON
BANKSEL ANSEL
clrf ANSELH
BANKSEL TRISD
clrf TRISB
BANKSEL PORTA
clrf PORTB
;-------------------------------------------------------------------------
; Defino pin de puertos
;************************************************* ************************
#Define Led_r PORTB,0
#Define Led_v PORTB,1
#Define Led_a PORTB,2

;--------------------------------------------------------------------------
; Pregunto la variable "Var_C" para ver en que color me encuentro, dependiendo del valor que tome Var_C decido en que color estar
;************************************************* *************************

Carga_duty
movf Var_C,W
addwf PCL, F
goto rojo
goto Azul
goto verde
goto amarillo
goto agua
goto magenta
goto orange
goto bonito
goto morado
goto marron
goto violeta
goto oscuro
goto verde1
goto rosado
goto verde2
goto blanco
;-------------------------------------------------------------------------
; Cargo las variables con los distintos dutys para generar
;los colores correspondientes
;************************************************* ************************

rojo
movlw .255
movwf pwm_r
movlw .0
movwf pwm_v
movlw .0
movwf pwm_a
goto Pregunto_Pwm

verde
movlw .0
movwf pwm_r
movlw .255
movwf pwm_v
movlw .0
movwf pwm_a
goto Pregunto_Pwm

Azul
movlw .0
movwf pwm_r
movlw .0
movwf pwm_v
movlw .255
movwf pwm_a
goto Pregunto_Pwm

amarillo
movlw .255
movwf pwm_r
movlw .255
movwf pwm_v
movlw .0
movwf pwm_a
goto Pregunto_Pwm
agua
movlw .0
movwf pwm_r
movlw .255
movwf pwm_v
movlw .255
movwf pwm_a
goto Pregunto_Pwm

magenta
movlw .255
movwf pwm_r
movlw .0
movwf pwm_v
movlw .255
movwf pwm_a
goto Pregunto_Pwm

orange
movlw .255
movwf pwm_r
movlw .140
movwf pwm_v
movlw .0
movwf pwm_a
goto Pregunto_Pwm

bonito
movlw .0
movwf pwm_r
movlw .250
movwf pwm_v
movlw .154
movwf pwm_a
goto Pregunto_Pwm

morado
movlw .147
movwf pwm_r
movlw .112
movwf pwm_v
movlw .219
movwf pwm_a
goto Pregunto_Pwm

marron
movlw .139
movwf pwm_r
movlw .69
movwf pwm_v
movlw .19
movwf pwm_a
goto Pregunto_Pwm

violeta
movlw .238
movwf pwm_r
movlw .130
movwf pwm_v
movlw .238
movwf pwm_a
goto Pregunto_Pwm

oscuro
movlw .25
movwf pwm_r
movlw .25
movwf pwm_v
movlw .112
movwf pwm_a
goto Pregunto_Pwm

verde1
movlw .46
movwf pwm_r
movlw .139
movwf pwm_v
movlw .87
movwf pwm_a
goto Pregunto_Pwm

rosado
movlw .220
movwf pwm_r
movlw .20
movwf pwm_v
movlw .60
movwf pwm_a
goto Pregunto_Pwm

verde2
movlw .144
movwf pwm_r
movlw .238
movwf pwm_v
movlw .144
movwf pwm_a
goto Pregunto_Pwm

blanco
movlw .255
movwf pwm_r
movlw .255
movwf pwm_v
movlw .255
movwf pwm_a
goto Pregunto_Pwm

;-------------------------------------------------------------------------
;Pregunto si ya cumplieron los ciclos de trabajo,
; configuro Interrupcion cada 40us
;************************************************* ********************
Pregunto_Pwm
movf Var_T,W ;cargo el valor necesario para generar los distintos
movwf cont1 ; tiempos de 10ms a 2s
BANKSEL TMR0
Movlw .251
Movwf TMR0
Pregunto_Pwm1
movf pwm_r,0
subwf Var_1,0
btfss STATUS,C
goto on_r
goto off_r
off_r
bcf Led_r
goto Pregunto_v
on_r
bsf Led_r
goto Pregunto_v

Pregunto_v
movf pwm_v,0
subwf Var_2,0
btfss STATUS,C
goto on_v
goto off_v
off_v
bcf Led_v
goto Pregunto_a
on_v
bsf Led_v
goto Pregunto_a

Pregunto_a
movf pwm_a,0
subwf Var_3,0
btfss STATUS,C
goto on_a
goto off_a
off_a
bcf Led_a
btfss PORTB,3
goto Pregunto_Pwm1
bcf PORTB,3
clrf Var_1
clrf Var_2
clrf Var_3
decfsz cont1 ;decremento contador, para saber si ya cumpli con mi tiempo
goto Pregunto_Pwm1
goto Carga_duty
on_a
bsf Led_a
btfss PORTB,3
goto Pregunto_Pwm1
bcf PORTB,3
clrf Var_1
clrf Var_2
clrf Var_3
decfsz cont1
goto Pregunto_Pwm1
goto Carga_duty

;--------------------------------------------------------------------
;rutina de interrupcion
;************************************************* *******************

Interrupcion
;---------------------------------------------------------------------
;guardamos registros importantes
;************************************************* ********************
movwf W2
movf STATUS,w
movwf Status2
;--------------------------------------------------------------------
;pregunto si Var_X llego a 255, si es si, la cargo a 0
;verifico si se cumplio el periodo correspondiente
;************************************************* ********************
incf Var_1,f
movlw .255
subwf Var_1,0
btfss STATUS,Z
goto Pregunto_var2
clrf Var_1
bsf PORTB,3
Pregunto_var2
incf Var_2,f
movlw .255
subwf Var_2,0
btfss STATUS,Z
goto Pregunto_var3
clrf Var_2
bsf PORTB,3
Pregunto_var3
incf Var_3,f
movlw .255
subwf Var_3,0
btfss STATUS,Z
goto inte
clrf Var_3
bsf PORTB,3
;-------------------------------------------------------------------
; devuelvo valor a w y status, tambien pongo en bajo Toif
;************************************************* ***************
inte
bcf INTCON,T0IF
Movlw .251
Movwf TMR0

movf Status2,w
movwf STATUS
movf W2,W
retfie
end
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 22 de Febrero de 2015, 17:53:14
A la salida del PIC tendrias 5V o 0V, luego las caidas de tension del led es fija ( ejemplo 2V ) y lo demas deberia caer sobre la resistencia de ese led. No se que estas midiendo vos si la caida de tension del diodo o desde el pin del PIC

Por el tema de conectarlo a la PC lo haces por el UART, tenes que configurar todos los registros ( los baudios, polaridad, etc etc ) y configuras para que cuando reciba un dato active una interrupcion. Luego desde la PC le envias caracteres ASCII. esto no complica mucho, ya que si te fijas los numeros solo se le suman 0x30 hexa...

Es decir si recibis un 0x38 en la PC se escribio 8

Luego haces lo que quieras con todo lo que recibis. Por ejemplo recibir 3 caracteres y eso guardarlo en rojo, luego 3 mas y en azul y asi. lo que llega queda en un registro llamado RCREG.

Con respecto a la parte fisica busca por internet PIC MAX232 y seguro que encontras los circuitos para eso.

Tal ves esto te sirva de ejemplo:
http://www.oz1bxm.dk/PIC/628uart.htm
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 22 de Febrero de 2015, 21:40:02
A la salida del PIC tendrias 5V o 0V, luego las caidas de tension del led es fija ( ejemplo 2V ) y lo demas deberia caer sobre la resistencia de ese led. No se que estas midiendo vos si la caida de tension del diodo o desde el pin del PIC

Por el tema de conectarlo a la PC lo haces por el UART, tenes que configurar todos los registros ( los baudios, polaridad, etc etc ) y configuras para que cuando reciba un dato active una interrupcion. Luego desde la PC le envias caracteres ASCII. esto no complica mucho, ya que si te fijas los numeros solo se le suman 0x30 hexa...

Es decir si recibis un 0x38 en la PC se escribio 8

Luego haces lo que quieras con todo lo que recibis. Por ejemplo recibir 3 caracteres y eso guardarlo en rojo, luego 3 mas y en azul y asi. lo que llega queda en un registro llamado RCREG.

Con respecto a la parte fisica busca por internet PIC MAX232 y seguro que encontras los circuitos para eso.


Tal ves esto te sirva de ejemplo:
http://www.oz1bxm.dk/PIC/628uart.htm


o sea, que si yo quiero enviar a la variable Var_C un 1. debo preguntar por 5 bits, para ver si es Var_C, luego si es si, pregunto por el bits 6 que serie el valor, en este caso un 1??
y gracias!
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 22 de Febrero de 2015, 22:36:28
No, vos recibis de a 1 byte.

Si vos de la PC mandas esto: "12"

recibirias 2 bytes, 0x31 y 0x32

Luego cuando recibas podes hacer que el primer numero vaya a Var_C o que ambos numeros los convertis en binario y alamacenas en Var_C
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 12 de Marzo de 2015, 22:02:25
No, vos recibis de a 1 byte.

Si vos de la PC mandas esto: "12"

recibirias 2 bytes, 0x31 y 0x32

Luego cuando recibas podes hacer que el primer numero vaya a Var_C o que ambos numeros los convertis en binario y alamacenas en Var_C

hola! gracias por tu constante ayuda! :) ya entiendo lo de enviar y recibir datos! el unico problemita que tengo es que al enviar algo atraves de una tabla DT no envio todo completo :( cuando lo hago "paso a paso" si funciona, y no entiendo porque! otra cosa, mi programa utiliza dos interrupciones las del periferico y el timer 0, lo que sucede es que se desborda el timer aunq no le cargo ningun valor, hasta donde entendido solo empieza a contar el timer cuando le cargo algo, pero a mi se me desborda antes de tiempo, les dejo mi configuracion inicial y el codigo de enviar datos



;------------------------------------------------------------------
;configuro inicio del programa con el vector reset/interrupcion
;*****************************************************************
        org 00H
        goto inicio

     org 04h
        goto Interrupcion
;-----------------------------------------------------------------------
; Inicia Programa
; CONFIGURO I/O
;**********************************************************************
inicio
;clrwdt

    ERRORLEVEL   -302
;*********************************************************************
;Configuro para envio y recepcion de datos
; Configuro puertos de entradas y salidas
;---------------------------------------------------------------------
   BANKSEL   ANSEL            ;I/O DIGITALES
   clrf   ANSEL
   clrf   ANSELH
    bcf     BAUDCTL,BRG16       ;BAUD DATA PARA 8BITS

    BANKSEL TRISC
   movlw   B'10000000'
   movwf   TRISC
    movlw   b'00000000'
    movwf   TRISB
    movwf   TRISE
    clrwdt
    BANKSEL TXSTA
    movlw   b'00100100'
    movwf   TXSTA
    bsf     PIE1,RCIE
    movlw   b'10000010'
    movwf   OPTION_REG
    movlw   .25
    movwf   SPBRG

    BANKSEL RCSTA
    bsf     RCSTA,CREN
    bsf     RCSTA,SPEN
    movlw   b'11000000'
    movwf   INTCON

    BANKSEL PORTB
    clrf    PORTB
    movlw   b'00000111'
    movwf   PORTE

cic1
    call    MENU                        ;MENU COLORES, HYPERTERMINAL
    movwf   dato                        ;lo guarda en dato
    sublw   "$"                         ;Compara con el signo "0"
    btfsc   STATUS,Z                    ;
    goto    rep                         ;si es, reinicia
    call    envia                       ;si no es "0" envía el dato
    incf    apun,f                     ;apunta al siguiente carácter
    goto    cic1

rep
   clrf    apun
    clrf    dato
cic2
    call    LISTO
    movwf   dato                        ;lo guarda en dato
    sublw   "$"                         ;Compara con el signo "0"
    btfsc   STATUS,Z                    ;
    goto    rep1                         ;si es, reinicia
    call    envia                       ;si no es "0" envía el dato
    incf    apun,f                      ;apunta al siguiente carácter
    goto    cic2

rep1
    clrf    apun1
    movlw   .16
    subwf   COLORES16,W
    btfss   STATUS,Z
    goto    Carga_duty
    movlw   "$"
    xorwf   MOVIMIENTO,W
    btfsc   STATUS,Z
    goto    Carga_duty
    goto    $-8

envia

    bsf     STATUS,RP0                  ;banco 1
esp
    btfss   TXSTA,TRMT                  ;checa si el buffer de transmisión
    goto    esp                         ;si está ocupado espera
    bcf     STATUS,RP0                  ;regresa al banco 0
    bcf     PIR1,TXIF
    movf    dato,W                      ;rescata dato a enviar
    movwf   TXREG                       ;lo envía
    btfss   PIR1,TXIF
    goto    $-1
    return

;----------RUTINA DE TRANSMISION DE DATOS-----------------
ENVIA                  ;SUBRUTINA DE ENVIO POR TRANSMISOR
   BCF      PIR1,TXIF
   MOVWF   TXREG
   BTFSS   PIR1,TXIF
   GOTO   $-1
   BANKSEL   TXSTA
ENVIANDO
   btfsc   TXSTA,TRMT
   GOTO   ENVIANDO
   BANKSEL   RCSTA
   RETURN

MENU
    movf    apun,W                      ;carga apuntador en W
    addwf   PCL,f
   DT     "Menu:",0x0D
    DT      "Rojo=1",0x0D
    DT      "Verde=2",0x0D
    DT      "Azul=3",0x0D
    DT      "Amarillo=4",0x0D
    DT      "Agua=5",0x0D
    DT      "Magente=6",0x0D
    DT      "Orange=7",0x0D
    DT      "Bonito=8",0x0D
    DT      "Morado=9",0x0D
    DT      "Marrón=10",0x0D
    DT      "Violeta=11",0x0D
    DT      "Oscuro=12",0x0D
    DT      "Verde1=13",0x0D
    DT      "Rosado=14",0x0D
    DT      "Verde2=15",0x0D
    DT      "Blanco=16",0x0D
    DT      0x0D,0x0D,"$"
LISTO
    movf    apun,W
    addwf   PCL,f
    DT      "Escoja Color",0x0D
   DT      0x0D,0x0D
   DT      "$"



Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 12 de Marzo de 2015, 23:12:09
Citar
el unico problemita que tengo es que al enviar algo atraves de una tabla DT no envio todo completo Sad cuando lo hago "paso a paso" si funciona, y no entiendo porque! otra cosa, mi programa utiliza dos interrupciones las del periferico y el timer 0, lo que sucede es que se desborda el timer aunq no le cargo ningun valor, hasta donde entendido solo empieza a contar el timer cuando le cargo algo, pero a mi se me desborda antes de tiempo, les dejo mi configuracion inicial y el codigo de enviar datos

Empecemos por el TIMER1 que es lo mas facil. No veo que estes activando su interrupcion. Lo unico que veo activo es la de recepcion del UART.
Los timer por ahi difieren.. Ejemplo, el timer0 no puede ser parado. esta continuamente contando, el Timer1 es uno de los pocos que se puede parar su marcha con el bit TMR1ON. El Timer 2 tampoco puede ser detenido.
Ninguno comienza a contar cuando le cargas un valor.

Y a que te referis a que no recibis "todo completo" cual es el problema (o que te muestra en la salida)?

Tenes que tener cuidado que si tu tabla tiene mas de 256 caracteres con un solo apuntador no vas a poder hacerlo.
Tambien El addwf   PCL,f modifica solo el registro PCL, lo cual si por ejemplo tu tabla comienza en la direccion: 0x150
Solo podrias ir con esa instruccion de 0x150 a 0x1FF , solo unos 176 caracteres. En cambio un CALL/GOTO son 10bits de direccionamiento dentro del mismo OPCODE.

Lo mas seguro es que no llegues al limite de los 256 caracteres pero que tu tabla este a la mitad. Por las dudas trata de poner tu tabla al comienzo del programa, o de ultima hace un ORG 0x200/0x300 para ubicar las tablas ( y si es que tu programa no es tan largo )
Si ya pasas a 0x400+ deberias de modificar el PCLATH antes de cada call a la tabla ( mas engorroso, proba la posibilidad de ponerlo al comienzo del programa y listo.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 12 de Marzo de 2015, 23:48:18
Citar
el unico problemita que tengo es que al enviar algo atraves de una tabla DT no envio todo completo Sad cuando lo hago "paso a paso" si funciona, y no entiendo porque! otra cosa, mi programa utiliza dos interrupciones las del periferico y el timer 0, lo que sucede es que se desborda el timer aunq no le cargo ningun valor, hasta donde entendido solo empieza a contar el timer cuando le cargo algo, pero a mi se me desborda antes de tiempo, les dejo mi configuracion inicial y el codigo de enviar datos

Empecemos por el TIMER1 que es lo mas facil. No veo que estes activando su interrupcion. Lo unico que veo activo es la de recepcion del UART.
Los timer por ahi difieren.. Ejemplo, el timer0 no puede ser parado. esta continuamente contando, el Timer1 es uno de los pocos que se puede parar su marcha con el bit TMR1ON. El Timer 2 tampoco puede ser detenido.
Ninguno comienza a contar cuando le cargas un valor.


MMM, espera, tenia entendido que el timer0 empezaba a contar cuando le caragba un valor, ejemplo
movlw .100
movwf TMR0

despues de ese momento es que el empezaba a contar no antes... y si lo activo, en el registro OPTION_REG

Y a que te referis a que no recibis "todo completo" cual es el problema (o que te muestra en la salida)?

Tenes que tener cuidado que si tu tabla tiene mas de 256 caracteres con un solo apuntador no vas a poder hacerlo.
Tambien El addwf   PCL,f modifica solo el registro PCL, lo cual si por ejemplo tu tabla comienza en la direccion: 0x150
Solo podrias ir con esa instruccion de 0x150 a 0x1FF , solo unos 176 caracteres. En cambio un CALL/GOTO son 10bits de direccionamiento dentro del mismo OPCODE.

Lo mas seguro es que no llegues al limite de los 256 caracteres pero que tu tabla este a la mitad. Por las dudas trata de poner tu tabla al comienzo del programa, o de ultima hace un ORG 0x200/0x300 para ubicar las tablas ( y si es que tu programa no es tan largo )
Si ya pasas a 0x400+ deberias de modificar el PCLATH antes de cada call a la tabla ( mas engorroso, proba la posibilidad de ponerlo al comienzo del programa y listo.

ya entendi lo de la tabla, el mensaje no se enviaba completo porque se pasaba la variable de 256, lo que hice fue dividirla, se envia un mensaje completo, pero sigo con el problema de desbordamiento del timer 0... aca lo que modifique


inicio
cic1
    call    MENU                        ;MENU COLORES, HYPERTERMINAL
    movwf   dato                        ;lo guarda en dato
    sublw   "#"                         ;Compara con el signo "0"
    btfsc   STATUS,Z                    ;
    goto    rep                         ;si es, reinicia
    call    ENVIA                       ;si no es "0" envía el dato
    incf    apun,f                     ;apunta al siguiente carácter
    goto    cic1

rep
   clrf    apun
    clrf    dato
cic2
    call    Menu1
    movwf   dato                        ;lo guarda en dato
    sublw   "#"                         ;Compara con el signo "0"
    btfsc   STATUS,Z                    ;
    goto    rep1                         ;si es, reinicia
    call    ENVIA                       ;si no es "0" envía el dato
    incf    apun,f                      ;apunta al siguiente carácter
    goto    cic2

rep1
    clrf    apun
    clrf    dato
 aqui
    goto    aqui
MENU
;    clrwdt
    movf    apun,W                      ;carga apuntador en W
    addwf   PCL,f
   DT     "Menu:",0x0D
    DT      "Rojo=0",0x0D
    DT      "Naranja=1",0x0D
    DT      "Amarillo=2",0x0D
    DT      "Amarillo oscuro=3",0x0D
    DT      "Amarillo Claro=4",0x0D
    DT      "Verde=5",0x0D
    DT      "Verde Claro=6",0x0D
    DT      "Cyan=7",0x0D
    DT      "Azul Claro=8",0x0D
    DT      "Azul Cielo=9",0x0D
    DT      "Azul=A",0x0D
    DT      "Azul Oscuro=B",0x0D
    DT      "Azul Lyon=C",0x0D
    DT      "Morado=D",0x0D
    DT      "Indigo=E",0x0D
    DT      "Blanco=F",0x0D
    DT      "#",0x0D

Menu1
    movf    apun,W                      ;carga apuntador en W
    addwf   PCL,f
    DT      "Blanco Leche=G",0x0D
    DT      "Blanco Rosa=H",0x0D
    DT      "Blanco Verde=I",0x0D
    DT      "Blanco Azul=J",0x0D
    DT      0x0D,0x0D,"#"
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 13 de Marzo de 2015, 05:30:02
Citar
MMM, espera, tenia entendido que el timer0 empezaba a contar cuando le caragba un valor, ejemplo
movlw .100
movwf TMR0

despues de ese momento es que el empezaba a contar no antes... y si lo activo, en el registro OPTION_REG

No... Al hacer eso le cargas 100 al TMR0, pero si no le cargas nada, va a contar los pulsos de reloj con lo que tenga en los registros del TMR0, si por ejemplo inicia con 0x00, entonces va a seguir contando hasta que llegue a 0xFF y se produsca el overflow a 0x00, poniendo un 1 en T0IF. SI le cargas 100 como decis va a ocurrir lo mismo (nomas que al cargarle 100 sobrescribis el valor que tenia antes TMR0), va a comenzar con 100, hasta que llegue a 255 ( 0xFF ) se produce el overflow a 0x00 y sigue contando a no ser que vos nuevamente le pongas 100 volviendo a borrar el valor que tenia, suponete que te tardaste 10 ciclos para cargar el 100, entonces estarias sobrescribiendo un 0x05 que habia alli ( 5 por que tiene un prescaler minimo de 2).

el TMR va a activar el flag si o si... por que esta continuamente andando.. no lo podes parar. Ah no ser que a cada rato estes poniendolo a 0 al TMR0, pero no tiene sentido si no lo usas. ( Ya que si no lo usas no preguntarias por T0IF en la interrupcion o tendrias habilitado T0IE )
Si lo usas estarias cargando el nuevo valor en la interrupcion, asi que no tendrias problemas, si buscas algun timer que puedas parar entonces usas el TMR1
Mientras no tengas habilitada la interrupcion (T0IE) no va a haber problemas... es decir no va a entrar a la interrupcion por culpa del timer 0. Si preguntas por el flag obviamente vas a ver que puede estar en 1 (T0IF).

Una forma de parar al TMR0 seria sacrificando un pin, si pones a 0 el pin de T0CKl (dejando a 1 T0CS de OPTION_REG) y seleccionas que esa sea la entrada no contaria nunca por lo cual no activaria T0IF jamas. Podes ver lo que digo mirando el diagrama de TMR0 en el datasheet. Aunque como dije no tiene sentido ( o no te importa el T0IF si no usas el timer, ya que si lo usas seguro le estas cargando un valor  ). Con lo cual esto lleva a una leccion, antes de activar la interrupcion del TMR0, se necesitan 3 instrucciones, 1 para borrar el flag y 2 para cargar el nuevo valor, asi luego podes activar la interrupcion del mismo.
Título: Re: Preguntas sobre assembler
Publicado por: syndu en 14 de Marzo de 2015, 14:38:05
mm ok! :/ desisti de usar ese timer.. no me servia.... otra pregunta.. yo tengo el archivo hex de un pograma... com puedo pasarlo a ASM??
este es el codigo..

:1000000000308A002D2C0000FF00030E8301A100A8
:100010000A08A0008A010408A2007708A300780853
:10002000A4007908A5007A08A6007B08A70083131E
:1000300083120B1E1D288B183028220884002308E9
:10004000F7002408F8002508F9002608FA00270818
:10005000FB0020088A00210E8300FF0E7F0E09009E
:100060008A110A12AA2A0A108A100A118207283451
:100070000C34013406340A108A100A1182070D3438
:1000800009340E34BA3415347134163431341A3418
:100090007A341B3473341C3461341D3477341E3489
:1000A00032342134633422347834233464342434B5
:1000B00065342534343426343334293420342A3416
:1000C00076342B3466342C3474342D3472342E341C
:1000D000353431346E343234623433346834343449
:1000E0006734353479343634363439342C343A3450
:1000F0006D343B346A343C3475343D3437343E34EB
:10010000383441342C3442346B344334693444340D
:100110006F34453430344634393449342E344A341B
:100120002D344B346C344C34F1344D3470344E3403
:1001300027345234B434543460345534A1345A34EE
:100140000D345B342B345D34E73461343C34663435
:100150000834693431346B3434346C3437347034AB
:10016000303471342E347234323473343534743460
:1001700036347534383479342B347A3433347B3430
:100180002D347C342A347D343934003400340A1060
:100190008A100A11CE3E03188A0A82000D340934EF
:1001A0000E34AA3415345134163421341A345A34E6
:1001B0001B3453341C3441341D3457341E34223420
:1001C00021344334223458342334443424344534E1
:1001D000253424342634B734293420342A34563490
:1001E0002B3446342C3454342D3452342E342534AC
:1001F00031344E3432344234333448343434473476
:10020000353459343634263439344C343A344D3458
:100210003B344A343C3455343D342F343E34283456
:1002200041343B3442344B344334493444344F3406
:1002300045343D344634293449343A344A345F3401
:100240004B344C344C34D1344D3450344E343F3430
:100250005234A83454345E345534BF345A340D34D7
:100260005B342A345D34C73461343E346634083438
:10027000693431346B3434346C3437347034303462
:1002800071342E3472343234733435347434363439
:100290007534383479342B347A3433347B342D3418
:1002A0007C342A347D343934003400340A148A1002
:1002B0000A1182070A340D34503443342034413457
:1002C000543420344B346534793462346F346134BF
:1002D00072346434203449346E3474346534723486
:1002E0006634613463346534203456346534723492
:1002F000203431342E343034203462347934203494
:1003000058345034383431343034303400340A14F2
:100310008A100A1182070A340D344134643470346F
:1003200061347034743465346434203466346F342A
:10033000723420343134363446343634323438343E
:100340004134203462347934203452346534643496
:1003500070346934633400340A148A100A11820735
:100360000A340D344434653463346F346434653492
:100370007234203461346E34643420344D346F343C
:100380006E34693474346F34723469346E34673463
:10039000203466346F347234203431343634463489
:1003A0003634323438344134203463346F346E346C
:1003B0006E346534633474346534643420340A3400
:1003C0000D340A340D3400340A148A100A118207DD
:1003D0005F3400340A148A100A1182072034003472
:1003E00083160611831206110830F800F729000061
:1003F000F817082AF813C50C03180615031C061174
:100400007817082A7813F80BFB29062A000006152E
:1004100050308400840B0A2A0D2AF81BFA29781B15
:10042000022A0034F0308316880083120815000079
:10043000081400000808080E0F39CD00081000004D
:100440000814222A232A00000808080E0F39CC00BD
:10045000081000308316880083124D0EF700F0302C
:10046000F70577084C04F80000344D0EF039F7001A
:100470000F30080577048800000008140330F700E7
:10048000F70B402A08100034881012227808CC009C
:10049000CC1B452A4A1C88104A18881400000811F1
:1004A000000008104B0ECC000F30CC054C08CD00DE
:1004B00035224B080F39CC00CD00352200344630B0
:1004C0008400831300080319722A0630F800F7012C
:1004D000F70B682AF80B672A7B30F700F70B6E2AB8
:1004E000800B652A0034470B762A792A4030C800F1
:1004F0007A2AC80101304602C80748088038C90076
:10050000CA014908CB004422003445080C3A0319BB
:10051000902A063A0319982A023A03199E2AA32A16
:10052000CA010130CB0044220230C6005F22A92A52
:100530000130C6000230C7007322A92ACA01103058
:10054000CB004422A92A0130CA004508CB0044222E
:10055000A92A00342D080A3C031CBD2A2D08023CA0
:100560000318BD2A0310C00C831686158312B00130
:100570008619B00A300BBD2AC017AD0B252C4008D8
:10058000C1005B30C500F0214108C3003730C40012
:10059000C41BDA2A0F30F700430EF7050A30770242
:1005A0000318D52A3030F707D72A4408F707770809
:1005B000C500F0210F30C3050A3043020318E22AB8
:1005C0003030E42AC4134408C3074308C500F021AF
:1005D0005D30C500F021B108031D132C4108F03A2D
:1005E0000319FC2AE23A0319FF2A4B3A0319022B9A
:1005F000033A0319052B0D2B0130B100122C0130E9
:10060000B200122C0130B200122CB2010A30C50027
:10061000F0210D30C500F021122CB208031D682B0B
:10062000C2010310420D3B2041020319202B03108D
:10063000420D3B20F800F8080319202BC20A112BA9
:100640000310420D3B204102031D672B0310420D96
:10065000013E3B20C4003C30C500F0214408C500E9
:10066000F0213E30C500F0210310420D013E3B2039
:10067000C400C50085220130A907831689108312A2
:10068000891083160910831209143230C6005F22C4
:1006900083168910831289143230C6005F228316B4
:1006A0000910831209103230C6005F2283168501BB
:1006B0008312290885000310420D013E3B20C4002F
:1006C0000030B40083168701831244088700112C80
:1006D000C2010310420DC72041020319782B0310F9
:1006E000420DC720F800F8080319782BC20A692BBD
:1006F0000310420DC7204102031D112C0310420DAF
:10070000013EC720C4003C30C500F0214408C500AC
:10071000F0213E30C500F0210310420D013EC720FC
:10072000C400C50085220310420D013EC720253CB0
:10073000031DE52B0130C600C7007322AA012A0859
:100740000F3C031CB02BC3014308EA2100380319F6
:10075000AD2BC30AC5008522A42B0130AA079F2B0D
:100760000130C600C70073228316891083128910D6
:1007700083160910831209148316091083120914B1
:10078000FF30A900AA012A080F3C031CE42B2B0808
:100790002E3C0319E42B0130A9078316850183122F
:1007A00029088500FF30B4008316870083120708EC
:1007B000AB002B08C50085220230C300FA30C6000A
:1007C0005F22C30BDE2BC32B112C0130A90783162C
:1007D000891083128910831609108312091432308C
:1007E000C6005F2283168910831289143230C60036
:1007F0005F2283160910831209103230C6005F226F
:10080000831685018312290885000310420D013EDD
:10081000C720C4000030B400831687018312440847
:100820008700122C202CB1014108123A03191C2C0C
:100830004B3A03191E2C202CB201202CB201202C83
:10084000C0010B30AD000130AE000130AE00AF0A88
:100850000B128B108A110A121D2803081F398300FE
:100860005730F7002030840083138001840AF70B8F
:10087000352CF801F901FA01FB01FC01FD01FE0133
:100880005030F700A030840083138001840AF70BF6
:10089000452C6030F7001030840083178001840AF3
:1008A000F70B4E2C83136030F700903084008317D1
:1008B0008001840AF70B582C8313A0018401831351
:1008C0001F308305831606118312061583161F1425
:1008D0009F141F159F1107309C00FF308312A90041
:1008E000AA01B101B201B301B4000430B500A801FE
:1008F0008B1BA8178B13C830C6005F22A81B8B1751
:10090000B50B772C0B30AD00B50135085621B50A73
:10091000F700A8018B1BA8178B137708C500F021DF
:10092000A81B8B172C303502031D852CB50135080B
:100930008721B50AF700A8018B1BA8178B1377082E
:10094000C500F021A81B8B1720303502031D972C02
:10095000B5013508AC21B50AF700A8018B1BA81713
:100960008B137708C500F021A81B8B172F30350299
:10097000031DA92C0330B6002E30A8018B1BA8172D
:100980008B13C500F021A81B8B17B60BBC2C2F3086
:10099000B7003708AC21B70AF700A8018B1BA817CE
:1009A0008B137708C500F021A81B8B173330370253
:1009B000031DC92C0030831688008312881008118B
:1009C0000810A8018B1BA8178B130F30C6005F22DD
:1009D000A81B8B170130B5003508033C031C042D00
:1009E000A8018B1BA8178B130330CD003522A81B41
:1009F0008B17A8018B1BA8178B130530C6005F222D
:100A0000A81B8B17B50AEC2CA8018B1BA8178B13FE
:100A10000230CD003522A81B8B17B5013508033CE9
:100A2000031C212D35083320B600A8018B1BA81705
:100A30008B13CA013608CB004422A81B8B17B50ABA
:100A40000E2DB5013508E42100380319312DB50A02
:100A5000A8018B1BA8178B13C5008522A81B8B1719
:100A6000222D83160614861581130830F700F70B24
:100A7000372D861283128612AF01AE01B0018316A4
:100A8000011383128B100B16C0308B042E0B4B2DD1
:0A0A9000AE018B100B16462D63001B
:02400E003A3F37
:00000001FF
;PIC16F877A
Título: Re: Preguntas sobre assembler
Publicado por: KILLERJC en 14 de Marzo de 2015, 18:40:21
Aca hay un post explicando y debatiendo el tema:

http://www.todopic.com.ar/foros/index.php?topic=23342.0

10 0000 00 - 00 30 8A 00 2D 2C 00 00 FF 00 03 0E 83 01 A1 00 - A8

16 datos (0x10) desde la posicion (0x0000) tipo cadena: datos ( 0x00 ), checksum 0xA8

0000 - 3000
0002 - 008A
0004 - 2C2D
0006 - 0000
0008 - 00FF
000A - 0E03
000C - 0183
000E - 00A1

Te vas a el set de instrucciones del datasheet y comenzas a reemplazar, son 14 bits cada opcode

Código: ASM
  1. MOVLW 0x00
  2. MOVWF 0xA
  3. GOTO  0x42D
  4. NOP
  5. MOVWF 0x7F
  6. SWAPF  0x3,W
  7. CLRF     0x3
  8. MOVWF 0x21

Reemplazando las direcciones por sus registros ( excepto el GOTO que debe apuntar a alguna bandera )

Código: ASM
  1. MOVLW 0x00      ;Vector de reset
  2. MOVWF PCLATH
  3. GOTO  0x42D
  4. NOP               ;Vector de interrupcion
  5. MOVWF 0x7F   ; Ultimo registro de proposito general del banco 0
  6. SWAPF  STATUS,W
  7. CLRF     STATUS
  8. MOVWF 0x21  ; Registro de proposito general tambien

LLeva un buen tiempo :) , pero seguro que hay algun programa por ahi que te lo puede hacer mas simple

La misma info aca:
http://en.wikipedia.org/wiki/Intel_HEX

La otra es abrir el MPLAB X, crear un nuevo proyecto del tipo Prebuilt(hex) project.
Ahi agregas tu archivo .hex y seleccionas el PIC con el cual trabajas.
se crea el proyecto y luego te vas al menu Window -> PIC Memory View -> Program memory

Y ahi te aparece todo en ASM, si queres ponerlo en un archivo busca cual es la ultima linea. click derecho sobre esa ventana, Output to file, de linea 1 a XXXX o te podes manejar por direcciones y te queda algo como lo que voy a adjuntar

Se pierden los nombres de los registros creados por el usuario, y los nombres de las banderas.