TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: LucasBols en 24 de Febrero de 2009, 23:03:45

Título: 16F877 y 16F628 - Sumar, restar y comparar
Publicado por: LucasBols en 24 de Febrero de 2009, 23:03:45
Hola

Necesito realizar estas operaciones:

Sumo 12 variables, del resultado debo obtener el siguiente mayor múltiplo de 8 y al múltiplo obtenido le tengo que restar el resultado de la suma, todo esto en un 16F877 y en un 16F628

para sumar y restar utilizo ADDWF o ADDLW y SUBWF pero no deduzco como comparar, me dan una ayuda?

Muchas gracias.
Título: Re: 16F877 y 16F628 - Sumar, restar y comparar
Publicado por: kain589 en 25 de Febrero de 2009, 00:01:08
Para comparar puedes restar un numero(1) al otro(2), y ver si el resultado es positivo(2 es mayor), negativo(1 es mayor) o cero(son iguales).

De todas formas si vas a sumar 12 variables tendras, tendras que hacer rutinas para sumar datos de mas de 8 bit (el dato nativo del pic). Es decir, tendras que hacer una rutina de aritmetica extendida, que a partir de la suma de 8 bits que implementa el pic, puedas hacer sumas de 16bits,24bits,32bits...
Título: Re: 16F877 y 16F628 - Sumar, restar y comparar
Publicado por: Leon Pic en 25 de Febrero de 2009, 00:55:00
Para saber si un número es múltiplo de 8, este tiene que ser capaz de ser dividido por 8 tantas veces como sea necesario y que el resultado sea cero. Para dividir un número, la división son susecivas resta. La cantidad de veces que tuviste que dividir, es el resultado. Por ejemplo 25; 25 - 8 = 17 Es positivo. 17 - 8 = 9 Es positivo 9 - 8 = 1 Es positivo. 1 - 8 = -7 Es negativo, por lo tanto nos exedimos. 25 / 8 = 3,125. Si nos fijamos bien, restamos 3 veces y fueron positivos. Restamos una cuarta vez y nos dio negativo.

Si hacemos 24 / 8 = 3

1) 24 - 8 = 16

2) 16 - 8 = 8

3) 8 - 8 = 0

Acá vemos que 24 es múltiplo de 8.
Título: Re: 16F877 y 16F628 - Sumar, restar y comparar
Publicado por: LucasBols en 25 de Febrero de 2009, 15:18:03
Hola

Bueno, gracias a vuestra ayuda, pude terminar la rutina.

Es una rutina para generar el checksum del protocolo ContactID utilizado para la comunicación de alarmas.

Este es el código:

;##############################################################################

   list      p=16f877            ; list directive to define processor
   #include <p16f877.inc>        ; processor specific variable definitions
   
   __CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _RC_OSC & _WRT_ENABLE_ON & _LVP_ON & _DEBUG_OFF & _CPD_OFF

;##############################################################################
; Variables ****
;***************

dtCtIDusr1   equ   0x20   ; |
dtCtIDusr2   equ   0x21   ; |   Número de
dtCtIDusr3   equ   0x22   ; |   usuario
dtCtIDusr4   equ   0x23   ; |
dtCtIDid1   equ   0x24   ; Identificador...
dtCtIDid2   equ   0x25   ; ...de Contact ID
dtCtIDnev   equ   0x26   ; Indicador de nuevo evento (1 nuevo)
dtCtIDev1   equ   0x27   ; |
dtCtIDev2   equ   0x28   ; |   Tipo de evento
dtCtIDev3   equ   0x29   ; |
dtCtIDprt1   equ   0x2A   ; Número de...
dtCtIDprt2   equ   0x2B   ; ...partición
dtCtIDzn1   equ   0x2C   ; |
dtCtIDzn2   equ   0x2D   ; |   Número de zona
dtCtIDzn3   equ   0x2E   ; |
dtCtIDcksm   equ   0x2F   ; Checksum
dtCtIDFIN   equ   0x30   ; FIN
dtCtIDSum   equ   0x31
tmpChkSum   equ   0x32

;##############################################################################
; Direcciones de memoria ****
;****************************

         ORG     0x000            ; processor reset vector
         clrf    PCLATH            ; ensure page bits are cleared
           goto    Inicio            ; go to beginning of program

;##############################################################################
; Inicio ****
;************

Inicio      ; inicializa los datos fijos
         movlw   0x01
         movwf   dtCtIDid1         ; Identificador de Contact ID
         movlw   0x08            ; 18
         movwf   dtCtIDid2         ;-------------------
         movlw   0x01            ; Indicador de nuevo evento 1
         movwf   dtCtIDnev         ;-------------------
         movlw   0x0A            ; Número de...
         movwf   dtCtIDprt1         ; ...partición
         movlw   0x01            ; 01
         movwf   dtCtIDprt2         ;-------------------
         movlw   0x02            ; Número de...
         movwf   dtCtIDusr1         ; ...usuario
         movlw   0x0A            ;
         movwf   dtCtIDusr2         ;
         movlw   0x05            ;
         movwf   dtCtIDusr3         ;
         movlw   0x04            ; 2054
         movwf   dtCtIDusr4         ;-------------------
         ; setea los datos variables
         movlw   0x01
         movwf   dtCtIDev1         ; Tipo...
         movlw   0x03            ; ...de...
         movwf   dtCtIDev2         ; ...evento
         movlw   0x01            ; 131
         movwf   dtCtIDev3         ;-------------------
         movlw   0x0A            ; Número...
         movwf   dtCtIDzn1         ; ...de...
         movlw   0x0A            ; ...zona
         movwf   dtCtIDzn2         ;
         movlw   0x04            ; 004
         movwf   dtCtIDzn3         ;-------------------
         call   CalcChkSum
         goto   Inicio

;##############################################################################
; Suma y calcula el checksum ****
;********************************

CalcChkSum   clrw
         bcf      STATUS, C         ; limpia los...
         bcf      STATUS, DC         ; ...registros
         bcf      STATUS, Z         ;-------------------
         addwf   dtCtIDusr1, 0      ; suma los...
         addwf   dtCtIDusr2, 0      ; ...componentes del...
         addwf   dtCtIDusr3, 0      ; ...paquete
         addwf   dtCtIDusr4, 0      ;
         addwf   dtCtIDid1, 0      ;
         addwf   dtCtIDid2, 0      ;
         addwf   dtCtIDnev, 0      ;
         addwf   dtCtIDev1, 0      ;
         addwf   dtCtIDev2, 0      ;
         addwf   dtCtIDev3, 0      ;
         addwf   dtCtIDprt1, 0      ;
         addwf   dtCtIDprt2, 0      ;
         addwf   dtCtIDzn1, 0      ;
         addwf   dtCtIDzn2, 0      ;
         addwf   dtCtIDzn3, 0      ;-------------------
         movwf   dtCtIDSum         ; almacena el resultado de la suma
         
         clrf   tmpChkSum         ; vacia la var temporal del checksum
ClcCkSm_Cnt   movlw   0x0F            ; carga 0x15 en W...
         addwf   tmpChkSum, 1      ; ...y lo suma al contenido de tmpChkSum
         movf   dtCtIDSum, 0      ; copia la suma del paquete en W
         subwf   tmpChkSum, 0      ; resta la suma (W) de tmpChkSum para ver si el resultado es negativo
         btfss   STATUS, C         ; verifica el bit de signo de la operación
         goto   ClcCkSm_Cnt         ; si es negativo, vuelve para sumar 15
         btfsc   STATUS, Z         ; pero si es positivo, el resultado queda en W y si es cero...
         movlw   0x0F            ; ...escribe 0x0F en W
         movwf   dtCtIDcksm         ; escribe el checksum con el contenido de W
         return

;##############################################################################

         end

;##############################################################################

Gracias por la ayuda.

Saludos-