duda 16f877a

#1
Hola a todos
tengo una duda, me dieron este codigo para el 16f877a el cual conecto a un modulo bluetooth rn41 para conectarme via bluetooth al pic, ya programe (o eso creo) el pic usando una placa pg2c y el winpc800, segui esta guia sin problemas http://www.ece.nus.edu.sg/ee2001/html/Common/WinPICprogrammerUserGuide.htm

pero tengo una duda respecto de la salida pues como explica el codigo utiliza el puerto b como salida entonces segun eso deberia conectar un led en el pin 33 del pic, que es el RB0/INT para probar si se prende cuando presiono un 1?

aqui dejo el codigo para su analisis
Saludos

Código:
#include <16F877a.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)

///////////////////////Principio del programa//////////////////////////////////

void main(void)
{
 int dato=0;//declaracion de variables
 set_tris_b(0b11111111);//puerto b como salida
 set_tris_c(0b10111111); //RC7/Rx entrada, RC6/Tx salida
 output_b(0b00000000); //pone en ceros todo el puerto b

while(TRUE)//Ciclo
{
   if(kbhit())//si ha llegado un dato
   {
      dato=getc(); //Lee el dato recibido
      if (dato==1)//si el dato es 1
      {
          output_high(PIN_B0); 
      }
       if (dato==2)//si el dato es 2
      {
      output_low(PIN_B0); 
      }
   }   
}
}
 
#2
En set_tris_b(); creo que te has confundido, ya que si esos pines van como salidas se debe de poner todo a cero (0b00000000) y sin van como entradas son uno (0b11111111), por ahí va tu equivocación y no prende el LED.

Un saludo
 
#3
hola
no entendi mucho :oops:
quiere decir que esa no es la salida siempre?
te cuento yo pregunte por un codigo que me permitiera entregar un valor alto al apretar un 1 y un valor bajo al apretar un 2, ya que pretendo abrir una puerta con el pic via bluetooth, por el momento tengo un led para ver si se prende o no.

Saludos
 
#4
Me refiero al pin donde está conectado el LED, si no prende es porque no configuraste bien el TRISB ya que para que el puerto b sea salida (el pin RB0) se escribe cero y en tu código escribes todo '1' haciendo todos los pines del puerto b como entrada y aunque escribas output_high/output_low ese pin no te va hacer caso.

Bueno como es el CCS y como no usas la directiva #USE FAST_IO(), realmente no le hace caso a la instrucción 'set_tris_', pero eso no es indispensable.

Probarías con un interruptor o pulsador para que veas si te prende el LED, luego ya pasa a lo del bluetooth y como es del bluetooth, estás seguro que realmente envía en '1' y '2' a la velocidad correcta?... Otra forma más segura de recibir datos es vía interrupción del PIC como dice en este post
conexion RS232 bidireccional

Un saludo
 
#5
hola
no se si entiendes bien lo del modulo bluetooth es para simular el puerto serie y no tiene mayor complicacion ni influencia en el pic pues solo conecto el tx del modulo con el rx del pic y el rx del modulo con el tx del pic entonces mi problema esta con el pic
y no veo como si el pic se supone que esta programado para que al apretar 1 funcione, el apretar el interruptor serviria para eso. o quizas este mal

Saludos
 
#6
Ya veo... pero se prende o no el LED?, NO, entonces una es por la mala configuración del TRIS como ya dije antes (0 = salidas, 1 = entradas) y otra es porque de esa forma no recibe o recibe mal el dato (no digo que se envíe mal por el bluetooth), el lío está en el PIC y una forma de recibir correctamente el dato es vía interrupción, como explican en el link que puse antes.

Un saludo
 
#7
ah dale
que cambio podria hacerle al codigo para que funcione como quiero, porque como dije antes el codigo me lo dieron porque no cacho mucho de programar pics :oops:

Saludos
 
#8
Reemplaza
set_tris_b(0b00000000); //puerto b como salida (cero para que sean salidas)
set_tris_c(0b10111111); //RC7/Rx entrada, RC6/Tx salida (va bien porque solo usas RC7 y RC6)

Con eso vuelve a probar, pero tengo una duda... cuando envías '1' por el bluetooth ¿es un '1' en decimal o en ASCII?, pues según el código del PIC lo que recibe es un número decimal (1 y 2) y por parte del bluetooth debe ser del mismo formato, revisa eso.

Sigue igual, prueba con interrupción. Solo para probar este código debe ir arriba de Main:
Código:
#int_RDA
void serial_isr() {    // Interrupción recepción serie USART
   rcvchar= 0x00;    // Inicializo caracter recibido
   if(kbhit()){          // Si hay algo pendiente de recibir ...
       valor= getc(); // lo descargo y se puede comparar algo... por decir una parte de tu código...
       if (dato==1)//si el dato es 1
      {
          output_high(PIN_B0); 
      }
       if (dato==2)//si el dato es 2
      {
          output_low(PIN_B0); 
      }
   }
}
En Main agregas el código para que se permita la interrupción y dejas vacío el bucle While
Código:
enable_interrupts(int_rda);  // Activa interrupción por USART
enable_interrupts(global);   // Activa interrupción global
while(TRUE){

}
Entonces, si el dato enviado por bluetooth es un decimal '1', el PIC lo recibe vía interrupción e inmediatamente hace el trabajo de encender el LED en RB0. Pero si fuese un ASCII "1" cambia lo de arriba por:

Código:
if (dato=='1') // Ahora está entre comas, indica que es ASCII
      {
          output_high(PIN_B0); 
      }
       if (dato=='2')   
      {
          output_low(PIN_B0); 
      }
Saludos
 
Última edición:
#9
hola
por ahora es un 1 decimal porque estoy ocupando el hyperterminal del pc para enviar el 1 al pic
luego que cambiare el pc por un celular no se que si sera decimal o ascii, pero por ahora lo dejare sin las ''

finalmente el codigo me quedo asi
Código:
#include <16F877a.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#int_RDA

///////////////////////Principio del programa//////////////////////////////////

void serial_isr() {    // Interrupción recepción serie USART
   rcvchar= 0x00;    // Inicializo caracter recibido
   if(kbhit()){          // Si hay algo pendiente de recibir ...
       valor= getc(); // lo descargo y se puede comparar algo... por decir una parte de tu código...
       if (dato==1)//si el dato es 1
      {
          output_high(PIN_B0); 
      }
	  if (dato==2)//si el dato es 2
      {
          output_low(PIN_B0); 
      }
}
void main(void){
 int dato=0;//declaracion de variables
 set_tris_b(0b00000000);//puerto b como salida
 set_tris_c(0b10111111); //RC7/Rx entrada, RC6/Tx salida
 output_b(0b00000000); //pone en ceros todo el puerto b
}
}
con que programa me recomiendas generar el .hex para el pic? porque con el codigo anterior me costo caleta generarlo bien probe con varios incluido el picc

Saludos
 
Última edición:
#10
Esa manera de escribir el código C es para el PICC, otros compiladores en C no reconocen declaraciones como #use o #fuses... porque no es el estándar C.
No elimines el while(TRUE); debajo de output_b(); para que el programa principal se quede en un bucle infinito mientras solo atiende a la interrupción y te falta poner

enable_interrupts(int_rda); // Activa interrupción por USART
enable_interrupts(global); // Activa interrupción global

antes del while(TRUE);, de otro modo no le va hacer caso a la interrupción.

Saludos
 
#11
Hola de nuevo..

Estoy tratando de leer un ID del lector RFID ID20, el ID del tag en Hex es : x2400CC572897xx

utilizando el pic 16f887 y al leer el caracter "2" encender un led..

Mi consulta, deseo leer los datos en Hex, cómo se define eso y como armar la trama..


Mi código es:

#include <16F887.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)
#BYTE TRISB = 0X86
#BYTE PORTB = 0X06
#BYTE OPTION_REG = 0X81


int16 a;

char value[12];

void main()
{
output_low(PIN_D7);

bit_clear(OPTION_REG,7);
bit_set(TRISB,0);
bit_clear(TRISB,1);
bit_clear(PORTB,1);

for (a=1; a<12; a++)

{
value[a]=getc();
// no comprendo armar la trama
ID=(value[1] value[2]..

}
{
// ID de mi tag Hex: tag1: x2400CC392AFBxxx; tag2: x2400CC572897xxx

if (value[2]="2")
{
output_high(PIN_B0);
delay_ms(1000);
}else
{
output_low(PIN_B0);
}
}
}

si puedo armar la trama luego puedo cambiar la condición if..
if (ID="2400CC392AFB")
{
output_high(PIN_B0);
delay_ms(1000);
}else
{
output_low(PIN_B0);
}

gracias desde ya por su ayuda..
 
Última edición:

Temas similares

Arriba