Problema con Select Case

#1
buen dia muchachos espero esten bien, tengo una pequeña duda con el siguiente codigo es algo sencillo pero no encuentro la falla, estoy usando un pic16f874 y el proton ide como compilador, la cuestion en si es que cuando puldo en la entrada RB1 o RB0 se me incrementa un contador que va activar unas salidas en el puerto D segun lo indique el select case, pero este no trabaja, ya lo he corrido en frio en la simulacion del proteus y veo que aun asi indique por ejemplo CONT1 = 2 a la hora de entrar en el CASE 2 no lo hace sino que sigue de largo como si nada..

Código:
Device  = 16F874A
 Declare XTAL 20 'Cristal de 20 Mhz
  
 TRISB=%1100000
 TRISD=0
 Dim cont1 As byte
 cont1 = 0 'detalle: inicializacion puede ser muy al azar de donde este ubicado el rotor

BUCLE:
DelayMS 200
'CONTROL DE LOS DEDOS
    If PORTB.0 = 0 Then 
        cont1 = cont1 + 1
        If PORTB.0 = 0 And cont1 > 4 Then
        cont1 = 1
        EndIf
        Call DEDOS
    EndIf
    If PORTB.1 = 0 Then 
        cont1 = cont1 - 1
        If PORTB.1 = 0 And cont1 = -1 Then
            cont1 = 4
        EndIf
        Call DEDOS
    EndIf
GOTO BUCLE

'Rutina de pausa
pausa:
DelayMS 150
Return

DEDOS:
Select Case cont1
        Case 1:
        PORTd=%00001010 'energizar bobina A
        GoSub pausa  'temporiza
        
        Case 2:
        PORTd=%00001001  'energiza bobina C
        GoSub pausa 'temporiza
        
        Case 3:
        PORTd=%00000101 'energiza bobina B
        GoSub pausa 'temporiza
        
        Case 4:
        PORTd=%00000110 'energiza bobina D
        GoSub pausa 'temporiza
        
    End Select
Return
End
 
Última edición por un moderador:
#2
Estás declarando los bits 4 a 0 del puerto B como salidas, pero usas los bits 1 y 0 como entradas.

Elimina la instrucción TRISB=%1100000 para que todo el puerto B quede como entradas.
(No es necesario que los pines no usados sean salidas)

También quita los dos puntos al final de cada valor de la sentencia Select Case
Y por último, te conviene activar las resistencias Pull-Up internas del puerto B para no usar externas.
 
#3
Hola. Gracias por responder.
Hice lo que me dijiste, puse el trisb = 1 para tener todo como entradas y los puntos se los quité.

por ejemplo:
Código:
Case 3
        PORTd=%00000101 'energiza bobina B
        GoSub pausa 'temporiza
Pero sigue igual, hay algo que me llamó la atención y es lo siguiente, es muy raro...
Dentro de la rutina:
Código:
Select Case cont1
IF CONT1 = 0 THEN
ENDIF
        Case 1:
        PORTd=%00001010 'energizar bobina A
        GoSub pausa  'temporiza
        
        Case 2:
        PORTd=%00001001  'energiza bobina C
        GoSub pausa 'temporiza
        
        Case 3:
        PORTd=%00000101 'energiza bobina B
        GoSub pausa 'temporiza
        
        Case 4:
        PORTd=%00000110 'energiza bobina D
        GoSub pausa 'temporiza
        
    End Select
Al colocar esa línea lógica, todo se normaliza y el select case hace su trabajo, de lo contrario, nada que ver :S !?
 
Última edición por un moderador:
#5
Ah, perdón, copié el que no era!

Código:
SELECT cont1
        case 1
        PORTd=%00001010 'energizar bobina A
        GoSub pausa  'temporiza
        case 2
        PORTd=%00001001  'energiza bobina C
        GoSub pausa 'temporiza
        case 3
        PORTd=%00000101 'energiza bobina B
        GoSub pausa 'temporiza
        case 4
        PORTd=%00000110 'energiza bobina D
        GoSub pausa 'temporiza
end select
 
Última edición por un moderador:
#6
OK. Te mencioné lo de quitar los dos puntos, por este motivo:

Error mostrado por el compilador.
Error_001.jpg
Descripción.
Error_002.jpg
El compilador nos indica que los dos puntos : (Colon) no son permitidos después de Case.

No me quedó claro si ya funcionó tu programa. :confused:
 
#7
hola le quite los puntos tal como me dijiste, pero no compañero sigue igual.. la unica manera de que funcione la sentencia SELECT es que le ponga esa linea de IF CONT1=0 THEN ENDIF

DEDOS:
IF CONT1=0 THEN
ENDIF

Select Case cont1
Case 1:
PORTd=%00001010 'energizar bobina A
GoSub pausa 'temporiza

Case 2:
PORTd=%00001001 'energiza bobina C
GoSub pausa 'temporiza

Case 3:
PORTd=%00000101 'energiza bobina B
GoSub pausa 'temporiza

Case 4:
PORTd=%00000110 'energiza bobina D
GoSub pausa 'temporiza

End Select
Return


y despues de eso, si entra en los "case" Ó que no use la función CALL DEDOS sino que lo deje asi en el programa principal, pero no deberia ser pienso yo.. la funcion select deberia funcionar bajo esas condiciones del codigo no entiendo por que pierde la lógica
 
Última edición:
#8
Mira. Si estás usando una variable de 8 bits sin signo, "cont1", nunca va a llegar a -1
En todo caso antes de que esta variable se desborde, va a llegar a 255.

Prueba de esta forma:
PHP:
    Device  = 16F874A
    
    Reminders = Off
    Config HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF
    Reminders = On
    Declare Xtal 20 'Cristal de 20 Mhz

    Declare Create_Coff = On        ; Crear archivo de depuración (*.cof)
    Declare PortB_Pullups On        ; Activar resistencias pull-up en puerto B
  
    ;TRISB=%1100000
    TRISD = 0
    Dim cont1 As Byte
    cont1 = 0 'detalle: inicializacion puede ser muy al azar de donde este ubicado el rotor
    PORTD = 0                       ; Puerto D en 0 al iniciar

BUCLE:
    DelayMS 200
    'CONTROL DE LOS DEDOS
    If PORTB.0 = 0 Then 
        cont1 = cont1 + 1
        If cont1 > 4 Then cont1 = 1 
        Call DEDOS
    EndIf
    
    If PORTB.1 = 0 Then 
        cont1 = cont1 - 1
        If cont1 >4 Then cont1 = 4  ; No permitir que "cont1" sea mayor a 4 (Evitar desborde por conteo regresivo)
        Call DEDOS
    EndIf
    
    GoTo BUCLE

'Rutina de pausa
pausa:
    DelayMS 150
    Return

DEDOS:
    Select Case cont1
        Case 1
            PORTD=%00001010 'energizar bobina A
            GoSub pausa  'temporiza
        
        Case 2
            PORTD=%00001001  'energiza bobina C
            GoSub pausa 'temporiza
        
        Case 3
            PORTD=%00000101 'energiza bobina B
            GoSub pausa 'temporiza
        
        Case 4
            PORTD=%00000110 'energiza bobina D
            GoSub pausa 'temporiza
        
    End Select
    
    Return
    
    End
 
#9
ah ya lo probe, y ese si da, al entrar al case si sigue la logica ! estoy es analizando en que se diferencia del mio ! gracias de antemano compañero !!
 
Última edición:
#10
sumaria tambien un antirebote con while u otra manera que funcione similar; Calculo yo que en circuito real fuera de la simulacion, puede interpetar mas de un pulso en el puerto si lo tenemos presionado mas del tiempo tiempo necesario por software...Saludos
 

Temas similares

Arriba