Que tipo de puerta usar ?

Hola buenas a tod@s, estoy realizando un circuito que incluye un microprocesador, por tanto no se exactamente donde colocar el post... si alguien considera que me equivoco agradeceria que me lo dijese ;)
Bueno, el tema es que quiero controlar un motor por pasos con un PIC16F877A, (el tema de la programacion del PIC está resuelta), yo quiero que:

RB0 RB4
1 1 = Motor ON, Gira Derecha
0 1 = Motor ON, Gira Izquierda
X 0 = Motor OFF

(adjunto una imagen para mejor compresión)

He probado con distintas puertas lógicas, pero no consigo resultados, ¿tendría que usar una puerta de tres entradas? ¿un triestado?

En la imagen se pueden apreciar los tres estados que busco, si el interruptor giratorio está en:

-posición 1 el motor gira a derecha,
-posición 3 el motor gira a izquierda,
-posición 2 el motor se detiene,

Gracias por la ayuda, si falta información me deciis! ;)

Gromek
 

Adjuntos

  • Logica Gromek Crane.jpg
    Logica Gromek Crane.jpg
    162 KB · Visitas: 20
  • Gromek Crane.zip
    290.6 KB · Visitas: 7
Última edición:
Gracias por vuestra rápida respuesta.
Pues verás Scooter, soy nuevo en el mundo del PIC, autodidacta y tiendo a complicar siempre las cosas, es bastante fácil que mi pregunta sea una burrada o una tontería.
Lo que me está pasando, es que al dejar el SW1 en posición 2 (en proteus me lo colorea gris) el PIC me lo interpreta como "0", por tanto en RB0 tengo "0", (el "0" interpretado), y en RB4 también tengo "0".

He probado diferentes formas de conectar y he reprogramado el PIC 10 o 12 veces, pero, o no se me detiene el motor, o siempre que inicio el sistema el motor está girando, o sólo gira en un sentido.
Como dije, estoy seguro que hay una forma super simple de realizar este circuito, además me explico bastante mal. Sorry .

Voy a probar no obstante algo que se me ha ocurrido mientras escribía estas lineas.



Me acabo de dar cuenta que en el archivo 16F877_code.c falta un trozo de código que quité para hacer una prueba.

El código:
PHP:
else                                 //Si no se da ninguna condición
  {                                    //Ejecuta este codigo
   lcd_putc("\f");                  //Limpia LCD
   lcd_gotoxy(1,1);               //Puntero Posicion 1, Linea 1
   lcd_putc("STOP!");            //Escribe texto
   delay_ms (250);               //Retardo 25ms
   output_c(0x00);               //Puerto C = 0
   output_d(0x00);               //Puerto D = 0
   continue;                        //
  }
Falta después del último else if, y me sobra un else if, por tanto el código quedaría así:
PHP:
#include <16f877a.h>
#fuses HS, NOWDT, RC, PUT, NOPROTECT,NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay (clock = 4000000)
#byte TRISA = getenv("SFR:TRISA")      //
#byte TRISB = getenv("SFR:TRISB")      //
#byte TRISC = getenv("SFR:TRISC")      //
#byte TRISD = getenv("SFR:TRISD")      //
#byte TRISE = getenv("SFR:TRISE")      //
#byte PORTA = 0x05                     //Address del PORTA
#byte PORTB = 0x06                     //Address del PORTB
#byte PORTC = 0x07                     //Address del PORTC
#byte PORTC = 0x08                     //Address del PORTD
#byte PORTC = 0x09                     //Address del PORTE
#byte OPTION_REG = 0x81                //Address del registro OPTION_REG
#define LCD_ENABLE_PIN  PIN_E0         //Configuración del PIN ENABLE (E)
#define LCD_RS_PIN      PIN_E1         //Configuración del PIN REGISTER SELECT (RS)
#define LCD_RW_PIN      PIN_E2         //Configuración del PIN READ/WRITE (RW)
#define LCD_DATA4       PIN_A0         //Configuración del PIN DATA4
#define LCD_DATA5       PIN_A1         //Configuración del PIN DATA5
#define LCD_DATA6       PIN_A2         //Configuración del PIN DATA6
#define LCD_DATA7       PIN_A3         //Configuración del PIN DATA7
#include "lcd.c"


void main(){
bit_set(OPTION_REG,7);                 //Resistencia Pullout desactivada   0=Activada 1=Desactivada
setup_psp(PSP_DISABLED);               //Configura el Modo PSP             0=Desactivado 1=Activado

set_TRIS_A(0x00);                      //Todos los pines del Puerto A configurados como salidas
set_TRIS_B(0xFF);                      //Todos los pines del Puerto B configurados como entradas
set_TRIS_C(0x00);                      //Todos los pines del Puerto C configurados como salidas
set_TRIS_D(0x00);                      //Todos los pines del Puerto D configurados como salidas
set_TRIS_E(0xFF);                      //Todos los pines del Puerto E configurados como entradas

//output_b(0xff);                      //Limpia el registro del Puerto B
output_c(0x00);                        //Limpia el registro del Puerto C
output_d(0x00);                        //Limpia el registro del Puerto D

lcd_init();                            //Llamada a LCD_INIT
lcd_gotoxy(1,1);                       //Puntero Posicion 1, Linea 1
lcd_putc("Hola Pablo");                //Escribe texto
lcd_gotoxy(1,2);                       //Puntero Posicion 1, Linea 2
lcd_putc("Bienvenido...");             //Escribe texto
delay_ms(850);
lcd_putc("\f");                        //Limpia LCD

int in=0;                              //
while(TRUE)                            //
{
 if(bit_test(PORTB,0) == 1)            //
 {
    for (in=0; in<=44; in++)           //
    {
      lcd_putc("\f");                  //Limpia LCD
      lcd_gotoxy(1,1);                 //Puntero Posicion 1, Linea 1
      lcd_putc("M-1 Derecha");         //Escribe texto
      output_c(0b00001000);            //Paso 1
      delay_ms (25);                   //Retardo 25ms
      output_c(0b00000100);            //Paso 2
      delay_ms (25);                   //Retardo 25ms
      output_c(0b00000010);            //Paso 3
      delay_ms (25);                   //Retardo 25ms
      output_c(0b00000001);            //Paso 4
      delay_ms (25);                   //Retardo 25ms
      break;                           //Break
    }
 } 
 else if(bit_test(PORTB,1) == 1)       //
 {
     for (in=0; in<=44; in++)          //
     {
      lcd_putc("\f");                  //Limpia LCD
      lcd_gotoxy(1,1);                 //Puntero Posicion 1, Linea 1
      lcd_putc("M2 - Derecha");        //Escribe texto
      output_c(0b10000000);            //Paso 1
      delay_ms (25);                   //Retardo 25ms
      output_c(0b01000000);            //Paso 2
      delay_ms (25);                   //Retardo 25ms
      output_c(0b00100000);            //Paso 3
      delay_ms (25);                   //Retardo 25ms
      output_c(0b00010000);            //Paso 4
      delay_ms (25);                   //Retardo 25ms
      break;                           //Break
    }
  }
 else if(bit_test(PORTB,2) == 1)       //
 {
     for (in=0; in<=44; in++)          //
     {
      lcd_putc("\f");                  //Limpia LCD
      lcd_gotoxy(1,1);                 //Puntero Posicion 1, Linea 1
      lcd_putc("M-3 Derecha");         //Escribe texto
      output_d(0b00001000);            //Paso 1
      delay_ms (25);                   //Retardo 25ms
      output_d(0b00000100);            //Paso 2
      delay_ms (25);                   //Retardo 25ms
      output_d(0b00000010);            //Paso 3
      delay_ms (25);                   //Retardo 25ms
      output_d(0b00000001);            //Paso 4
      delay_ms (25);                   //Retardo 25ms
      break;                           //Break
    }
  }
 else if(bit_test(PORTB,3) == 1)       //
 {
     for (in=0; in<=44; in++)          //
     {
      lcd_putc("\f");                  //Limpia LCD
      lcd_gotoxy(1,1);                 //Puntero Posicion 1, Linea 1
      lcd_putc("M4 - Derecha");        //Escribe texto
      output_d(0b10000000);            //Paso 1
      delay_ms (25);                   //Retardo 25ms
      output_d(0b01000000);            //Paso 2
      delay_ms (25);                   //Retardo 25ms
      output_d(0b00100000);            //Paso 3
      delay_ms (25);                   //Retardo 25ms
      output_d(0b00010000);            //Paso 4
      delay_ms (25);                   //Retardo 25ms
      break;                           //Break
    }
  }
 else                                 //Si no se da ninguna condición
 {                                    //Ejecuta este codigo
   lcd_putc("\f");                     //Limpia LCD
   lcd_gotoxy(1,1);                    //Puntero Posicion 1, Linea 1
   lcd_putc("STOP!");                  //Escribe texto
   delay_ms (250);                     //Retardo 25ms
   output_c(0x00);                     //Puerto C = 0
   output_d(0x00);                     //Puerto D = 0
   continue;                           //
 }
}
}
Gracias de nuevo, y siento la molestia.
 
Última edición por un moderador:
Te funciono con los cambios?
Entiendo que la parte que maneja el motor esta resuelta y lo que buscas es que este responda segun las señales de entrada, es correcto? Un diagrma que incluya todo el conjunto ayudaria bastante. Que dispositivo es el que aparece como un cuadro con signo de interrogacion?
Nunca he programado un PIC, solo Atmel AVR, pero los principios deben ser semejantes. Creo que lo que pasa es que cuando conmutas el sw, los pines quedan en un estado flotante, de modo que habría que mantenerlos en un estado definido. De esa forma me imagino que ya sea que tengas un "1" o un "0" en cada pin, según sea el caso, podes utilizar la logica boolena interna del pic y definir la acción de salida mediante el programa....
 
Hola Lamas, no me funcionó el cambio... tienes razón, la parte que majeja el motor está resuelta, y como bien dices, cuando conmuto el sw1 queda en estado flotante. El dispositivo con el signo de interrogación es el componente por el cual surge mi pregunta, porque cuando queda en estado flotante el PIC interpreta un 0, segun el dibujo, al tener RB0 y RB4 en 0 el motor se detiene y nunca gira a derecha, como le decia antes a Scooter

RB0(0) + RB4(1) = Motor gira Derecha
RB0(1) + RB4(1) = Motor gira Izquierda
RB0(x) + RB4(0) = Motor detenido

cuando RB0(x) el PIC entiende RB0(0), y yo no quiero eso porque me detiene el motor

No se a que te refieres con "usar la logica booleana interna del PIC y definir la accion de salida mediante el programa", porque RB0 y RB4 son entradas... las salidas del PIC son RC0 a RC7 y RD0 a RD7.

Gracias
 
Como te decia Scooter, no necesitas compuertas externas si las puedes implementar internamente en el pic. A eso me referia. Tambien puedes leer el estado de los pines y con condicionales puedes definir que accion debería tomar el motor.
 
Pues no se como hacerlo... la verdad es que voy aprendiendo sobre la marcha... investigaré como se hace.... muchas gracias

Creo que te refieres a que no me hace falta usar RB4, que mejor "pregunto" al PIC si en RB0 el estado es 1, 0 o Float, no?
 
Última edición:
Se pone un if o un case y se selecciona lo que quieras.
Para verificar que se cumplen las dos condiciones mira el uso de los operadores lógicos .
 
Refiriéndome al ultimo mensaje de Scooter, usas los operadores lógicos para verificar el estado de ambos pines, no solo uno. Flotante no es un estado, de modo que tenes que tener valores totalmente predecibles.
Ej: yo los pondría en este orden:
Si RB4=0 > motor no gira (proceso de salida para que motor no gire)
RB4=1 > motor aun no gira ya que debo leer el estado de RB0 para definir la dirección
RB0=0; > motor gira a la izquierda, de lo contrario (si es 1) gira a la derecha

te toca traducirlo al lenguaje de los PIC porque ese no lo domino....
Por si acaso dale un vistazo a estos mensajes en el foro...
https://www.forosdeelectronica.com/f27/leer-dato-pin-pic-51806/
 
muchas gracias, me voy a poner manos a la obra!!! ;)
no creo tener problema para traducirlo,

estube mirando por google y ya me han dejado claro que Flotante no es un estado.... jeje y por tanto no podia poner algo como "bit_test(PORTB,0) == NULL" que era mi pretensión, tan inocente como un chaval de 4 años!!!

os iré comentando!

Gracias again! ;)
 
Atrás
Arriba