Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
Para ayudarte te explicare todo el código y la utilización de los comandos empezando con la función SELECT CASE que es una estructura de control que proporciona PBP para utilizarse se debe empezar con select case y terminar la operación con end select.
Su propósito es el simplificar las estructuras anidadas if, Then, else que utilizamos cuando se da una condición, en los casos en que sea siempre la mima variable y se necesiten varias decisiones en función de los valores posibles, y su estructura es la siguiente:
SELECT CASE variable
CASE valor1: instruccion1
…
END SELECT
En el ejemplo que posteaste se utiliza de la siguiente manera me tome la liberta de utilizar con el pic 16f877A:
@ DEVICE xt_osc ; definimos Oscilador externo
define osc 4
TRISA=1 ; puerto A como entradas digitales
ADCON1=7
Pause 2000
Loop: ;Bucle principal
Select case PORTA ; condición determinada por el Puerto A del pic 16F877A
; Los casos utilizados se desarrollan bajo las posibles variables obtenidas del puerto A del pic 16F877A, defeneciendo cuatro por las entradas que son dos RA0 y RA1 respectivamente.
Case 0
Gosub izquierda
; En esta condición (PRIMERA) RA1 y RA 0 están a cero lógico con lo que se pretende ir a la rutina de izquierda con el comando GOSUB.
Case 1
Gosub adelante
; En esta condición (segunda) RA1 y RA0 están a cero lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
Case 2
Gosub atras
; En esta condición (tercera) RA1 y RA0 están a uno lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
Case 3
Gosub derecha
; En esta condición (Cuarta) RA1 y RA0 están a uno lógico con lo que se pretende ir a la rutina de derecha con el comando GOSUB.
End select ; fin Del condicional
Goto loop ; crea un bucle cerrado ir a Loop
; En estas rutinas se utiliza el puerto b del pic como complemento siendo cero (0) a cinco (5) RB0 a RB5 respectivamente si te fijas siempre cero (RB0) y tres (RB3) estén a uno lógico ya que habitan los driver para los motores que deben ser servos ya que si fueran dc normales se embalan y no hay control en el giro, la única posibilidad es la utilización de los comandos PWM y HPWM, cuando se ha ejecutado se retorna a la función que fue precedida con el comando RETURN. Los otro pines son los habilitadores de polaridad del motor para que giro en sentido horario y antihorario los cuales son (1, 2, 4,5) o (RB1, RB2, RB4, RB5).
adelante:
high 0:high 1: low 2
high 3:high 4: low 5
return
atras:
high 0:low 1: high 2
high 3:low 4: high 5
return
izquierda:
high 0:low 1: high 2
high 3:high 4: low 5
return
derecha:
high 0:high 1: low 2
high 3:low 4: high 5
return
end
Espero te sea de ayuda para tu proyecto amigo.
amigo atricio me equivoque en condicion tres caso dos es a uno logico en RA1 y cero logico en RA0.
Case 2
Gosub atras
; En esta condición (tercera) RA1 y RA0 están a uno lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
En esta condición (tercera) RA1 y RA0 están a uno lógico y a cero lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
• 0101: CAPTURE, CADA FLANCO DE SUBIDA EN RC2/CCP1
mira este enlace especifica como utilizar el CCP como modulo de captura:
http://iesmachado.org/web insti/dep...royectos/pic_f_877/TEMA_21_modulo_ccp_pwm.pdf
bien te dejo este proyecto como ayuda para lo que deseas
@ Device XT_OSC '
@ Device WDT_ON '
@ Device PWRT_ON '
@ Device BOD_ON '
@ Device LVP_OFF '
@ Device CPD_OFF '
define __16F877A 1
define OSC 20
DEFINE INTHAND DO_ISR
DEFINE DEBUG_REG PortC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
' ------------- Direcciones de hardware---------------------------
GIE VAR INTCON.7 'habilitación de interrupción Global
PEIE VAR INTCON.6 ' Perif. Eq. Habilitación de interrupción
ADIE VAR PIE1.6 ' A-2-D convertidor de habilitación de interrupción
TMR1IE VAR PIE1.0 ' PIE direccion 10h
TMR2IE VAR PIE1.1
TMR1ON VAR T1CON.0 ' Registros en PIC.inc
TMR2ON VAR T2CON.2
EnaPin VAR PORTC.2 ' PWM pin
FwdPin VAR PORTB.5
RevPin VAR PORTB.4
QuadPin1 Var PORTC.0
LED var PORTC.3
' ------------- Espacio para Asignar la interrupción de almacenamiento --------
wSave VAR BYTE $20 SYSTEM ; Guardar registro W en bank0
wSave1 VAR BYTE $A0 SYSTEM ; Guardar reg W en bank1
; wSave2 VAR BYTE $120 SYSTEM ;
; wSave3 VAR BYTE $1A0 SYSTEM ;
sSave VAR BYTE Bank0 SYSTEM ; Guardar localizacion en registro STATUS
pSave VAR BYTE Bank0 SYSTEM ; Guardar localizacion en reg PCLATH
StatFlag VAR BYTE Bank0
GyroTaskFlag VAR StatFlag.0
OddCycleFlag VAR StatFlag.1
QuadStateFlag var Statflag.2
QuadCount VAR Byte Bank0 ; Contar [-127..0..127] encoder
QuadPins Var Byte Bank0 ; estado actual de los pines
QuadPrev VAR Byte Bank0 ; estado del pin del encoder
QuadByte Var Byte Bank0
' -------------- Asignar variables---------------------------
ADVal Var Word
DutyCycle Var Byte
nLoops VAR Byte
'============================================================================
CodeStart:
Goto InitSeq ' Pasar a subrutinas
'============================================================================
'Do_ISR
'Servicio de rutina de interrupción
'Manejar todad las interupciones
Asm
DO_ISR
IF (CODE_SIZE <= 2)
movwf wsave ; guardar registro W
swapf STATUS,W ; guardar registro Status
clrf STATUS ; cambiar al banco 0
movwf ssave ; guardar estado de área en el banco 0
movf PCLATH,W ; guardar conteo de programa
movwf psave ; guardar en el Banco 0 la localizacion
EndIF
; ==========================================================================
; ver quinen causó la interrupción.
; vector a las rutinas correctas
clrf STATUS ; cambio en el banco 0
BTFSC PIR1,TMR1IF ; Timer1 desbordamiento?
GOTO T1_INT ; Sí - Pase a la rutina de Timer1
BTFSC PIR1,TMR2IF ; Desbordamiento Timer2?
GOTO T2_INT ;Sí - Pase a la rutina Timer2
CLRF PIR1
GOTO ISR_Done ; Error - no maneja la interrupción
; ==========================================================================
; Volver -1,0,1 en W reg
; Lo que debe ser de rutina en pzge 0
QUAD1_JUMP
CLRF PCLATH ; PÁGINA CERO
ADDWF PCL,F ; salto Indirectos
RETLW 0 ; 00 -> 00
RETLW 1 ; 00 -> 01
RETLW 1 ; 00 -> 10
RETLW 1 ; 00 -> 11
RETLW 1 ; 01 -> 00
RETLW 0 ; 01 -> 01
RETLW 1 ; 01 -> 10
RETLW 1 ; 01 -> 11
RETLW 1 ; 10 -> 00
RETLW 1 ; 10 -> 01
RETLW 0 ; 10 -> 10
RETLW 1 ; 10 -> 11
RETLW 1 ; 11 -> 00
RETLW 1 ; 11 -> 01
RETLW 1 ; 11 -> 10
RETLW 0 ; 11 -> 11
; ==========================================================================
T1_INT ; Timer1 desbordamiento
BCF T1CON,TMR1ON ; Apague el timer1
BCF PIR1, TMR1IF ; Desactive la bandera de interrupción
; BCF PORTB,5 ; Apagar Pin pulso - a su veztodos los pines
; BCF PORTB,4 ;
GOTO ISR_Done
; ============================================================================
; Obtener los datos del codificador de cuadratura
; Inc / Dec durante interupcion ,@1.25 kHz frecuencia de muestreo
; limpiar QuadCount durante el ciclo de dirección
T2_INT ; Timer2 / PWM de interrupción
BCF PIR1, TMR2IF ; Desactive la bandera de interrupción
MOVF PORTC,W ; Leer cuádruple sensor Pins - esto tiene que cambiar
ANDLW 1 ; AND con 0001
MOVWF _QuadPins
MOVF _QuadPrev,W
ADDWF _QuadPins,W
MOVWF _QuadByte
BTFSC _QuadByte.0 ; Chequear Bit 0
INCF _QuadCount,F
MOVF _QuadPins,W
MOVWF _QuadPrev
GOTO ISR_Done
; BCF PORTB,4
; INCF _QuadCount,F
; ------
BCF STATUS,C ; Borrar bit
MOVF PORTC,W ; Leer cuádruple sensor Pins - esto tiene que cambiar
ANDLW 1 ; AND con 0001
; ANDLW 6 ; AND con 0110
MOVWF _QuadPins
; RRF _QuadPins,F ; Roll derecho -> 0011
RLF _QuadPrev,F ; Roll pines anterior en bits superior
RLF _QuadPrev,W ; Roll en W Reg: 1100
IORWF _QuadPins,W ; O anterior y los estados CRNT: PPCC
MOVWF _QuadPrev ; guardar para la próxima vez
; Movlw 1
MOVF _QuadPrev,W ; parece innecesario
CALL QUAD1_JUMP
ADDWF _QuadCount,F
; ===============================
ISR_Done
Movf psave,w ; Restaurar el registro PCLATH
Movwf PCLATH
swapf ssave,w ; Restaurar el registro STATUS r
;(banco establece a su estado original)
Movwf STATUS ; mover W al reg Status
swapf wsave,f ; Swap w_guardar
swapf wsave,w ; Swap w_guardar en W
RETFIE
EndASM
'============================================================================
'============================================================================
' Subrutinas para leer voltajes A/D convertidor
Read_Pot1:
ADCON0 = %10000001 '
Read_AD:
nLoops = 0
Pauseus 10 '
ADCON0.2 = 1 ' iniciar conversion
wLoop:
nLoops = nLoops + 1
Pauseus 5 ' tiempo para conversion
IF ADCON0.2 = 1 then wLoop
adval.HIGHBYTE = ADRESH
adval.LowBYTE = ADRESL
Return
'-----------------------------------------------------------------------
'-----------------------------------------------------------------------
InitSeq:
TRISA = %00000001 'configuracion PORTA
TRISB = %00000000 ' PORTB
TRISC = %10000001 ' PORTC
ADCON1 = %10000000 '
CCP1CON = 0 ' MOdulo CCP en OFF
HIGH FwdPin
LOW RevPin
QuadCount = 0
QuadPrev = 0
StatFlag = 0
T2CON = %00000011 ' Timer2 Pre-Scaler = 1:16, Timer OFF
TMR2 = 0 ' limpiar Timer2
PR2 = 255 ' SPWM = 1.25 kHz
CCPR1L = 63 ' Duty Cycle a 25%
CCP1CON = %00101100 ' modo PWM ,ciclo util= 10
TMR2ON = 1
Pause 500
HIGH LED
DEBUG 13,10,"Velocidad", 13
Pause 500
GIE = 1 ' Habilitst interrpcion clobal
PEIE = 1 ' Periférico de habilitación de interrupción
TMR2IE = 1 ' habilitar bit de interrupcion del Timer2
Low LED
debug "Hecho que el bucle principal!", 13
pause 1000
'-----------------------------------------------------------------------
mainloop:
Toggle LED
Gosub Read_Pot1 ; devuelve el valor 0 .. 1023
adval = adval / 2 ; Ahora 0 .. 511
' Debug "Pot: ", DEC ADval, 13
if adval > 255 then
adval = adval - 256
fwdpin = 0
revpin = 1
else
adval = 255 - adval
fwdpin = 1
revpin = 0
Endif
Adval = 255 - Adval ; 0 = velocidad completa
Debug "Ciclo Util: ", DEC ADval, "qCount: ", dec QuadCount, "qPrev: ", dec QuadPrev, 13
QuadCount = 0
CCPR1L = ADval MIN 255 ; Establecer Ciclo 0 .. 255
Pause 400
Goto mainloop
' debug 13, "All Done.", 13
End
End
@ DEVICE MCLR_OFF, INTRC_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF
CMCON = 7 ' desactivo el convertidor AD del puerto A
TrisA=%11111111 'todo el port A como entrada
TrisB=%00000000 'todo el port B como salida
PORTA = %11111111 'todo el port A en 1
PORTB = %00000000 'todo el port B en 0
ojoder var bit
ojoizq var bit
inicio:
FREQOUT portb.4,50,38500
ojoder = porta.0
ojoizq = porta.1
if ojoder = 0 then giroder
if ojoizq = 0 then giroizq
goto inicio
giroder:
portb = %00000101 'port B 0 y port B 2 a nivel 1 giro a la derecha
goto inicio
giroizq:
portb = %00001010 'port B 1 y port B 3 a 1 giro hacia la izquierda
goto inicio