Como comparar registros

Vereis, aunque parece fácil para mi es un mundo_Os voy a explicar en que consiste.

Se trata de programar un microcontrolador de microchip modelo pic 16F877

El código a utilizar es en ensamblador.

Lo que no se hacer son los intervalos, hay 10:

0<AN4<0,5
0,5<AN4<1
1<AN4<1,5
1,5<AN4<2
2<AN4<2,5
2,5<AN4<3
3<AN4<3,5
3,5<AN4<4
4<AN4<4,5
4,5<AN4<5

Una señal entra por AN4 y hay que comparar lo que entra con los valores frontera para saber en que intervalo nos encontramos, una vez identificado el intervalo se activa un número en un display de 7 segmentos.

Los valores frontera los he convertido a binario gracias al conversor A/D y los tengo en los registros ADRESH ADRESL

0v ADRESH=00 ADRESL=00000000
0,5v ADRESH=00 ADRESL=01100110
1v ADRESH=00 ADRESL=11001100
1,5v ADRESH=01 ADRESL=00110011
2v ADRESH=01 ADRESL=10011001
2,5v ADRESH=01 ADRESL=11111111
3v ADRESH=10 ADRESL=01100101
3,5v ADRESH=10 ADRESL=11001100
4v ADRESH=11 ADRESL=00110010
4,5v ADRESH=11 ADRESL=10011000
5v ADRESH=11 ADRESL=11111111

¿Como comparo los registros para saber a que intervalo pertenecen?.Espero que alguien pueda ayudarme.
 

Adjuntos

  • ejemplo_176.jpg
    ejemplo_176.jpg
    58.8 KB · Visitas: 40
La única ayuda que puedes recibir, es mirando las directivas del MPLAB 8.20 o el que tengas que puedes utilizar los <,>,=<,=>,(,), cosas así.
 
no está tan complicado, puede haber varias maneras, una de estas:

- cargas W con el byte alto y lo comparas con los 4 bytes altos almacenados en algun registro
- si es igual , ahora lo comparas con alguno de los tres/dos del subconjunto

postea tu avance.
 
Lo que tu quieres no es complicado pero si es tedioso tiene que repasar su aritmectica de numeros binarios.
La gente esta aconstumbrada a programar en C y se olvidan de lo mas basico.
 
Haz lo que dice mabauti. Compara primero el byte mas alto y después el subconjuto de los bytes bajos. Las comparaciones las puedes realizar con operaciones de resta o xor. A mi me gusta utilizar la xor aunque el resultado es el mismo. Carga el valor que quieras comparar a W, por ejemplo movlw 0x00, luego has el xor con la instrucción XORWF REGISTRO,w, por ultimo para ver si son iguales checa el bit Z del registro STATUS, si son iguales ese bit será 1.
 
He pensado hacerlo asi:

movf var1,w ; w= var1
subwf var2,w ; w= var2-var1 ; Si la resta es positiva C=1
btfsc STATUS,C ; si C=0 => var1>var2; C=1 => var1<var2
goto var1<var2
goto var1>var2

Con la instrucción SUBWF
 
pic-man dijo:
Haz lo que dice mabauti. Compara primero el byte mas alto y después el subconjuto de los bytes bajos. Las comparaciones las puedes realizar con operaciones de resta o xor. A mi me gusta utilizar la xor aunque el resultado es el mismo. Carga el valor que quieras comparar a W, por ejemplo movlw 0x00, luego has el xor con la instrucción XORWF REGISTRO,w, por ultimo para ver si son iguales checa el bit Z del registro STATUS, si son iguales ese bit será 1.

Bueno, me interesa saber si el contenido de dos registros es igual.Pero....tambien necesito saber si el contenido de un registro es mayor o menor tal y como lo he explicado arriba.

0<AN4<0,5
0,5<AN4<1
1<AN4<1,5
1,5<AN4<2
2<AN4<2,5
2,5<AN4<3
3<AN4<3,5
3,5<AN4<4
4<AN4<4,5
4,5<AN4<5

AN4 lo mando a un registro llamado X. Pues X lo comparo con 0 y 0,5 y si está dentro del rango pues el porgrama hace una cosa y asi sucesivamente con todos. ¿Pero y si la lectura de X resulta que corresponde al rango 4,5<AN4<5 ? tengo que hacer comparaciones para cubrir todos los rangos, no se si me explico.
 
Oye son variables de 10bits utiliza 2bytes para las operaciones.
Esa opeación no vasta es una pequeña parte de lose debe hacer yó ya lo hice eso hace mucho tiempo.
Esas operaciones no lo encuentras en los libros de pics, eso lo encuentras en los libros de digitales I.
Y luego lo tienes que adaptarlo al asm del pic.
 
Hola amigos, tengo novedades, he avanzado con el programa pero aún no funciona correctamente.Pero lo que está hecho está bien, estoy seguro porque lo he consultado con una persona que sabe más que yo de programación.Y me falta muy poco para terminar!, espero que con vuestra ayuda consiga terminar lo poco que queda.

Recordaros que como entrada analógica lo que entra es una señal alterna, la señal alterna varia con el tiempo y eso quiere decir que el voltaje va variando.Ese voltaje se almacena en ADRESH ADRESL y el programa va tomando lectura del valor contenido en dichos registros para asi saber en que intervalo nos encontramos:

0<AN4<0,5 --->Display número 0
0,5<AN4<1 --->Display número 1
1<AN4<1,5 --->Display número 2
1,5<AN4<2 --->Display número 3
2<AN4<2,5 --->Display número 4
2,5<AN4<3 --->Display número 5
3<AN4<3,5 --->Display número 6
3,5<AN4<4 --->Display número 7
4<AN4<4,5 --->Display número 8
4,5<AN4<5 --->Display número 9


A continuación os pongo el porgrama completo.

Código:
LIST	P=16F877
	#INCLUDE <P16F877.INC>
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF 
        CONTADOR	  EQU	0x20
        DATO1H             EQU	0x21
        DATO1L              EQU       0x22
        
        
BANCO_0 MACRO
         BCF STATUS,RP0
         BCF STATUS,RP1
        ENDM
BANCO_1 MACRO
         BSF STATUS,RP0
         BCF STATUS,RP1
        ENDM
BANCO_2 MACRO
         BCF STATUS,RP0
         BSF STATUS,RP1
        ENDM
BANCO_3 MACRO
         BSF STATUS,RP0
         BSF STATUS,RP1
        ENDM

#DEFINE	INT_1	PORTC,5
#DEFINE	INT_2	PORTD,7
#DEFINE	INT_3	PORTB,4
#DEFINE	INT_4	PORTB,5
#DEFINE	PUL_1	PORTA,4
#DEFINE	PUL_2	PORTC,0
#DEFINE	PUL_3	PORTC,1
#DEFINE	PUL_4	PORTE,2
#DEFINE	DIS_A	PORTD,5	
#DEFINE	DIS_B	PORTD,6
#DEFINE	DIS_C	PORTD,0
#DEFINE	DIS_D	PORTD,1
#DEFINE	DIS_E	PORTD,2
#DEFINE	DIS_F	PORTD,4
#DEFINE	DIS_G	PORTD,3
#DEFINE	DIS_P	PORTE,1
#DEFINE	LED_1	PORTC,2
#DEFINE	AD_EXT1	PORTA,5

	CBLOCK	0x070	; VARIABLES TODOS BLOQUES (max 16)
	 W_TEMP		 
	 STATUS_TEMP	
	 PCLATH_TEMP
	ENDC		

	CBLOCK 0x30   	; VARIABLE BANCO 0 (max 79)

	; ----- VARIABLES DE PROGRAMA

	ENDC

	ORG	0x00
	GOTO	INICIO
	ORG	0X04
	MOVWF	W_TEMP		; GUARDA W
	SWAPF	STATUS,W	
	MOVWF	STATUS_TEMP	; GUARDA STATUS
	MOVF	PCLATH,W	
	MOVWF	PCLATH_TEMP	; GUARDA PCLATH
	CLRF	PCLATH		

	; ----- RUTINA DE TRATAMIENTO DE INTERRUPCIÓN

	MOVF	PCLATH_TEMP,W	
	MOVWF	PCLATH		; RECUPERA PCLATH
	SWAPF	STATUS_TEMP,W	 
	MOVWF	STATUS		; RECUPERA STATUS
	SWAPF	W_TEMP,F
	SWAPF	W_TEMP,W	; RECUPERA W
	RETFIE

INICIO	

        
        
        BANCO_0
        
        MOVLW   b'10100001' 
        MOVWF   ADCON0    ;Tad=Fosc/32. Canal 4. go/done#=0. Activa el conversor
        
        BANCO_1

        MOVLW  b'00000111'
        MOVWF  OPTION_REG
        
        MOVLW   b'10000010'         
        MOVWF   ADCON1
        
        MOVLW	b'00000000'
        MOVWF	TRISD
        BSF     TRISA,5   ;Entrada analogica
        BANCO_0


INICIO_2 ;TIEMPO DE ADQUISICIÓN--> 20us=NºCONTADOR*3*Tciclo instrucción, Fosc=4MHz
        MOVLW    d'7'
        MOVWF    CONTADOR
ESPERAR
        DECFSZ   CONTADOR
        GOTO     ESPERAR
        BSF      ADCON0,2  ;Inicia la conversión
FIN_AD
        BTFSC    ADCON0,2  ;Salta si es cero indicando que la conversión ha terminado
        GOTO     FIN_AD

        MOVF     ADRESH,W  ;El resultado de la conversión lo almacenamos en dos registros
        MOVWF    DATO1H
        BANCO_1
        MOVF     ADRESL,W 
        BANCO_0
        MOVWF    DATO1L
        
               CALL     MAYOR
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	ES_CERO
               CALL     MAYOR_1
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	UNO
               CALL     MAYOR_2
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	DOS 
               CALL     MAYOR_3
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	TRES
               CALL     MAYOR_4
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	CUATRO
               CALL     MAYOR_5
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	CINCO
               CALL     MAYOR_6
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	SEIS
               CALL     MAYOR_7
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	SIETE
               CALL     MAYOR_8
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	OCHO
               CALL     MAYOR_9
	SUBWF	0X00,W
	BTFSS	STATUS,Z
	GOTO	NUEVE
               CALL     MAYOR_10



MAYOR
        
                MOVF	DATO1H,W
	SUBWF	0x00,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x00,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1	; si DATO1<CONSTANTE

MAYOR_1
        
                MOVF	DATO1H,W
	SUBWF	0x00,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x66,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1

MAYOR_2
        
                MOVF	DATO1H,W
	SUBWF	0x00,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0xcc,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


MAYOR_3
        
                MOVF	DATO1H,W
	SUBWF	0x01,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x33,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1
        


MAYOR_4
        
                MOVF	DATO1H,W
	SUBWF	0x01,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x99,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1       


MAYOR_5
        
                MOVF	DATO1H,W
	SUBWF	0x01,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0xff,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


MAYOR_6
        
                MOVF	DATO1H,W
	SUBWF	0x02,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x65,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


MAYOR_7
        
                MOVF	DATO1H,W
	SUBWF	0x02,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0xcc,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1

MAYOR_8
        
                MOVF	DATO1H,W
	SUBWF	0x03,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x32,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


MAYOR_9
        
                MOVF	DATO1H,W
	SUBWF	0x03,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0x98,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


MAYOR_10
        
                MOVF	DATO1H,W
	SUBWF	0x03,W
	BTFSS	STATUS,C     ; BRINCA SI DATO2H>=DATO1H
	RETLW	.0           ; DEVUELVE 0 INDICANDO QUE DATO1>DATO2	
	BTFSS	STATUS,Z     ; BRINCA SI NULO
	RETLW	.1	     ; DEVUELVE 1 INDICANDO QUE DATO1<DATO2
	MOVF	DATO1L,W     ; COMPARA LA PARTE BAJA CUANDO LAS PARTES ALTAS SON IGUALES
	SUBWF	0xff,W
	BTFSS	STATUS,C	
	RETLW	.0
	RETLW	.1


        



ES_CERO        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_D
        BSF     DIS_F
        BSF     DIS_E
        BSF     DIS_B
        BSF     DIS_C
        
        GOTO    INICIO

UNO	
        CLRF    PORTD
        BSF     DIS_B
        BSF     DIS_C
        
        GOTO    INICIO
        
DOS        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_B
        BSF     DIS_G
        BSF     DIS_E
        BSF     DIS_D
	
        GOTO    INICIO
        
TRES        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_B
        BSF     DIS_G
        BSF     DIS_C
        BSF     DIS_D
        
        GOTO    INICIO
        
CUATRO        
        CLRF    PORTD
        BSF     DIS_F
        BSF     DIS_G
        BSF     DIS_B
        BSF     DIS_C
        
        GOTO    INICIO
CINCO        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_F
        BSF     DIS_G
        BSF     DIS_C
        BSF     DIS_D
        
        GOTO    INICIO
       
SEIS        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_F
        BSF     DIS_G
        BSF     DIS_E
        BSF     DIS_C
        BSF     DIS_D
       
        GOTO    INICIO
        
SIETE        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_B
        BSF     DIS_C
        
        GOTO    INICIO
        
OCHO        
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_F
        BSF     DIS_G
        BSF     DIS_B
        BSF     DIS_E
        BSF     DIS_C
        BSF     DIS_D
        
        GOTO    INICIO
        
NUEVE
        CLRF    PORTD
        BSF     DIS_A
        BSF     DIS_F
        BSF     DIS_G
        BSF     DIS_B
        BSF     DIS_C
	
        GOTO    INICIO

        END
 
porque estas poniendo SUBWF 0X00,W a 0x00 no lo veo declarado como un registro en este caso es un literal , o no?
tal vez deberia ser SUBWF registrox,w
 
movf valorA,0 ; Mueve el valor A al regristro 0
subwf valorB,0 ; Resta el valor B al valor A
btfss Status,Z ; si la bandera de Z es 0 los numeros son iguales.
goto no_igual
goto si_igual

es para hacer una igualdad


para ser mayor que testeas la bandera de carry en lugar de la de zero

espero te sirva camarada, saludos y exito.
 
Atrás
Arriba