Programación Específica > Microcontroladores

 Instrucciones De La Programacion Del Pic 16f84

(1/1)

Joscar:
Hola a todos, mi duda es la siguiente: tengo el siguiente programa, pero existe unas intrucciones que no entiendo (GOTO    $-1), por favor me lo pueden explicar. Gracias por sus respuestas
el programa controla la velocidad, el sentido de giro (horario, antihorario) de un motor paso a paso.

;********************************************************
;
;               Stepper Motor controller
;
;                                
;********************************************************
 
        LIST            P=PIC16F84A
        INCLUDE         P16F84A.INC
        LIST
; P16F84A.INC  Standard Header File, Version 2.00'(modify)
        LIST
       __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;****************  Label Definition  ********************
        CBLOCK  H'0c'
 MODE                            ;Operation mode
                                ;0=stop 1=right 2=left
 COUNT1                          ;Wait counter
 COUNT2                          ;Wait counter(for 1msec)
 ENDC
 
RB0     EQU     0               ;RB0 of PORTB
RB1     EQU     1               ;RB1 of PORTB
RB2     EQU     2               ;RB2 of PORTB
RB5     EQU     5               ;RB5 of PORTB
RB7     EQU     7               ;RB7 of PORTB
 
;****************  Program Start  ***********************
 ORG     0               ;Reset Vector
        GOTO    INIT
        ORG     4               ;Interrupt Vector
        CLRF    INTCON          ;Clear Interruption reg
 
;****************  Initial Process  *********************
INIT
 BSF     STATUS,RP0      ;Change to Bank1
 CLRF    TRISA           ;Set PORTA all OUT
 MOVLW   B'00100111'     ;RB0,1,2.5=IN RB7=OUT
 MOVWF   TRISB           ;Set PORTB
 MOVLW   B'10000000'     ;RBPU=1 Pull up not use
 MOVWF   OPTION_REG      ;Set OPTION_REG
 BCF     STATUS,RP0      ;Change to Bank0
 CLRF    MODE            ;Set mode = stop
 CLRF    COUNT1          ;Clear counter
 CLRF    COUNT2          ;Clear counter
 MOVLW   B'00000101'     ;Set PORTA initial value
 MOVWF   PORTA           ;Write PORTA
 BSF     PORTB,RB7       ;Set RB7 = 1
 BTFSC   PORTB,RB5       ;RB5 = 0 ?
 GOTO    $-1             ;No. Wait
 
START
VALUE
;*************  Check switch condition  *****************
 BTFSC   PORTB,RB1       ;RB1(stop key) = ON ?
 GOTO    CHECK1          ;No. Next
 CLRF    MODE            ;Yes. Set stop mode
 GOTO    DRIVE           ;No. Jump to motor drive
CHECK1
 BTFSC   PORTB,RB2       ;RB2(right key) = ON ?
 GOTO    CHECK2          ;No. Next
 MOVLW   D'1'            ;Yes. Set right mode
 MOVWF   MODE            ;Save mode
 GOTO    DRIVE           ;No. Jump to motor drive
CHECK2
 BTFSC   PORTB,RB0       ;RB0(left key) = ON ?
 GOTO    DRIVE           ;No. Jump to motor drive
 MOVLW   D'2'            ;Yes. Set left mode
 MOVWF   MODE            ;Save mode
 
;********************  Motor drive  *********************
DRIVE
  MOVF    MODE,W          ;Read mode
  BZ      START           ;mode = stop
  BSF     PORTB,RB7       ;Set RB7 = 1
  BTFSC   PORTB,RB5       ;RB5 = 0 ?
  GOTO    $-1             ;No. Wait
  MOVLW   D'5'            ;Set loop count(5msec)
  MOVWF   COUNT1          ;Save loop count
LOOP    CALL    TIMER           ;Wait 1msec
  DECFSZ COUNT1,F        ;count - 1 = 0 ?
  GOTO    LOOP            ;No. Continue
  BCF     PORTB,RB7       ;Set RB7 = 0
  BTFSS   PORTB,RB5       ;RB5 = 1 ?
  GOTO    $-1             ;No. Wait
  MOVF    PORTA,W         ;Read PORTA
  SUBLW   B'000000101'    ;Check motor position
  BNZ     DRIVE2          ;Unmatch
  MOVF    MODE,W          ;Read mode
  SUBLW   D'1'            ;Right ?
  BZ      DRIVE1          ;Yes. Right
  MOVLW   B'00001001'     ;No. Set Left data
  GOTO    DRIVE_END       ;Jump to PORTA write
DRIVE1
  MOVLW   B'00000110'     ;Set Right data
  GOTO    DRIVE_END       ;Jump to PORTA write
 ;-------
DRIVE2
  MOVF    PORTA,W         ;Read PORTA
  SUBLW   B'000000110'    ;Check motor position
  BNZ     DRIVE4          ;Unmatch
  MOVF    MODE,W          ;Read mode
  SUBLW   D'1'            ;Right ?
  BZ      DRIVE3          ;Yes. Right
  MOVLW   B'00000101'     ;No. Set Left data
  GOTO    DRIVE_END       ;Jump to PORTA write
;VALUE

DRIVE3
 MOVLW   B'00001010'     ;Set Right data
 GOTO    DRIVE_END       ;Jump to PORTA write
;-------
DRIVE4
 MOVF    PORTA,W         ;Read PORTA
 SUBLW   B'000001010'    ;Check motor position
 BNZ     DRIVE6          ;Unmatch
 MOVF    MODE,W          ;Read mode
 SUBLW   D'1'            ;Right ?
 BZ      DRIVE5          ;Yes. Right
 MOVLW   B'00000110'     ;No. Set Left data
 GOTO    DRIVE_END       ;Jump to PORTA write
DRIVE5
 MOVLW   B'00001001'     ;Set Right data
 GOTO    DRIVE_END       ;Jump to PORTA write
;-------
DRIVE6
 MOVF    PORTA,W         ;Read PORTA
 SUBLW   B'000001001'    ;Check motor position
 BNZ     DRIVE8          ;Unmatch
 MOVF    MODE,W          ;Read mode
 SUBLW   D'1'            ;Right ?
 BZ      DRIVE7          ;Yes. Right
 MOVLW   B'00001010'     ;No. Set Left data
 GOTO    DRIVE_END       ;Jump to PORTA write
DRIVE7
 MOVLW   B'00000101'     ;Set Right data
 GOTO    DRIVE_END       ;Jump to PORTA write
;-------
DRIVE8
 MOVLW   B'00000101'     ;Compulsion setting
 
DRIVE_END
 MOVWF   PORTA           ;Write PORTA
 GOTO    START           ;Jump to start

;*************  1msec Timer Subroutine  *****************
TIMER
 MOVLW   D'200'          ;Set loop count
 MOVWF   COUNT2          ;Save loop count
TMLP    NOP                     ;Time adjust
 NOP                     ;Time adjust
 DECFSZ  COUNT2,F        ;count - 1 = 0 ?
 GOTO    TMLP            ;No. Continue
 RETURN                  ;Yes. Count end
 
;********************************************************
;             END of Stepper Motor controller
;********************************************************
 
 END

oldkami:
Hola..

Te recomiendo leer completamente las ayudas que vienen con el compilador MPLAB para que aprendas más sobre lo relacionado a la programacion.

goto $-1 realiza un salto a la operación inmediatamente anterior.

Aunque este y muchos programas de ejemplo vienen en codigo Absoluto, no te recomiendo  te acostumbres mucho a este estilo de programación, ya que tiende a ser un gran "generador de errores" de dificil solucion ademas de ser demorado de desarrollar.  Cosas como

BSF STATUS,RP0  para seleccionar el banco del registro TRISA, es eficiente en codigo pero creeme, tarde o temprano te equivocas en programas extensos y luego no encuentras el error. utiliza por ejemplo

banksel TRISA
clrf TRISA

con eso no solo estas seguro de  que seleccionaste el banco adecuado, sino que no necesitas consultar en todo momento el manual para saber el banco adecuado.

   Aprende a programar haciendo modulos (Relocatable modules) que te permite hacer tus programas mucho más legibles, y faciles de portar de un pic a otro. y utiliza macros para hacer secciones de codigo similares (DRIVE 2, DRIVE4, DRIVE6).  de esa forma es más facil leer lo que hace el programa. te recomiendo empieces a hacerlo con este mismo programa. con eso  no solo tu, sino varias personas aprenden a programar de esta manera.

Saludos..

oldkami

Meta:
A veces me he dado cuenta que BANKSEL no funciona o no es fiable al 100 % o simplemente no se usarlo bien. En esas cosas de cambiar bancos mejor usar macros.

Navegación

[0] Índice de Mensajes

Ir a la versión completa