HC-05 PIC18f4550

Muy buenas noches, disculpen las molestias pero estoy tratando de montar una comunicación serial a través de un celu con el pic, cosa que leo miles de tutoriales pero no logro hacerlo andar. Trate de hacer lo mas simple, prender un led, pero en arduino si me funciona, la cuestión está cuando lo intento con pic, no lo logro, aclaro que soy autodidacta y ya me estoy dando por vencido. Por eso acudo a ustedes. Muchas gracias y disculpen las molestias.

Código del Receptor:
Código:
#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12                    //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV4                  //System Clock by 4
#FUSES USBDIV                   //USB clock source comes from PLL divide by 2
#FUSES VREGEN                   //USB voltage regulator enabled
#FUSES ICPRT                    //ICPRT enabled

#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)

char dato;

#int_rda
rda_isr(){
   dato=getc();
}

void main()
{
   set_tris_a(0x00);

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   enable_interrupts(int_rda);
   enable_interrupts(global);
   
   if(dato=='1')
   {
      output_high(pin_a0);
      delay_ms(5000);
   }
   
   if(dato=='2')
   {
      output_low(pin_a0);
      delay_ms(5000);
   }
}

Circuito:
16c5pxi.png


El emisor no subo el código porque ya lo probé en arduino y funciona, la cuestión es cuando lo paso a pic. Muchas gracias y espero una pronta respuesta ...


P.D.: Aclaro que la tensión con la cual alimento todo es de 3,7 V y que entre MCLR y Vcc tengo una resistencia de 10k. El oscilador que utilizo es de 20MHz con capacitores de 20pF, que creo que son para eliminar las armonicas
 
Última edición:
aver intenta asi:


Código:
#include <18f4550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB 

#use delay(clock=48M) //para un cristal de 20Mhz

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=N)


char dato;

#int_rda             
void rda_isr()
{
   dato=getc();
}

void main()
{
  
   enable_interrupts(int_rda);
   enable_interrupts(global);
   
   if(dato=='1')
   {
      output_high(pin_a0);
      delay_ms(5000);
   }
   
   if(dato=='2')
   {
      output_low(pin_a0);
      delay_ms(5000);
   }
}


no me gustan los delays tan largos que metiste

en arduino funciona por que es para bebes
 
aver intenta asi:


Código:
#include <18f4550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB 

#use delay(clock=48M) //para un cristal de 20Mhz

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=N)


char dato;

#int_rda             
void rda_isr()
{
   dato=getc();
}

void main()
{
  
   enable_interrupts(int_rda);
   enable_interrupts(global);
   
   if(dato=='1')
   {
      output_high(pin_a0);
      delay_ms(5000);
   }
   
   if(dato=='2')
   {
      output_low(pin_a0);
      delay_ms(5000);
   }
}


no me gustan los delays tan largos que metiste

en arduino funciona por que es para bebes

Buenas tardes amigo, muchas gracias por la ayuda que me brindas, pero sigo sin lograr prender el led. Lo compile tal cual al programa pero no sucede nada, lo que me llama a la duda es que en el "#use delay" pones 48MHz, siendo que utilizo un cristal de 20, porque lo haces?.
Lo que quisiera averiguar a demás de eso es si estoy recibiendo datos en el pic. Cuento con un display con el siguiente adaptador, que compre cuando estaba aprendiendo a utilizar arduino. Lo comento por si sirve para ver si recibo el dato. El mismo es:
Buscar en Mercadolibre: MLA-585815151-adaptador-i2c-display-lcd-pcf8754-serie-paralelo-arduino-_JM


Bueno, espero poder recibir una pronta respuesta y muchas gracias por la mano que me están dando...! Un abrazo
 
espera acabo de ver mi error es que no hay bucle infinito intenta esto:
void main()
{

enable_interrupts(int_rda);
enable_interrupts(global);


while(1)// bucle infinito
{
if(dato=='1')
{
output_high(pin_a0);
delay_ms(500); //no recomiendo usar delays mas grandes a 10ms
}

if(dato=='2')
{
output_low(pin_a0);
delay_ms(500);//no recomiendo usar delays mas grandes a 10ms
}

}//fin del bucle infinito
}


la razon por la que pongo 48M

es por que el 18f4550 tiene un prescaler PLL que lo que hace es elevar la frecuencia de reloj a 48Mhz por razones de compatibilidad hardware USB.

el USB trabaja a 48Mhz y para estar a la par con el harware el con la computadora debe estar a 48 Mhz el CPU del 18f4550 puede trabajar a un clock diferente a 48Mhz puden ser 10 ,4 ,8 ,20 Mhz.

lo puse asi por que es asi como me funciono cuando usaba boot loader

enseguida te doy los remapeos de memoria para que puedas trabajar con el bootloader de microchip

#include <18f2550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB
#use delay(clock=48M)


#include <usb_bootloader.h>
#build (reset=0x1000,interrupt=0x1008)
#org 0x0000,0x0FFF {}


funciona para el 18f4550 y el 18f2550.
el 2550 es el mismo que el 4550 solo que le faltan pines


no recuerdo si para entrar a modo bootloader es con el boton en B4 o en B5

es mas o menos asi el diagrama:

getfile.php


solo que no recuerdo si el boton va en B4 o en B5

y colocale 2 leds en C0 y C1 asi podras ver cuando entra en modo bootloader
 

Adjuntos

  • bootloader2550.zip
    56.8 KB · Visitas: 32
Última edición:
espera acabo de ver mi error es que no hay bucle infinito intenta esto:
void main()
{

enable_interrupts(int_rda);
enable_interrupts(global);


while(1)// bucle infinito
{
if(dato=='1')
{
output_high(pin_a0);
delay_ms(500); //no recomiendo usar delays mas grandes a 10ms
}

if(dato=='2')
{
output_low(pin_a0);
delay_ms(500);//no recomiendo usar delays mas grandes a 10ms
}

}//fin del bucle infinito
}


la razon por la que pongo 48M

es por que el 18f4550 tiene un prescaler PLL que lo que hace es elevar la frecuencia de reloj a 48Mhz por razones de compatibilidad hardware USB.

el USB trabaja a 48Mhz y para estar a la par con el harware el con la computadora debe estar a 48 Mhz el CPU del 18f4550 puede trabajar a un clock diferente a 48Mhz puden ser 10 ,4 ,8 ,20 Mhz.

lo puse asi por que es asi como me funciono cuando usaba boot loader

enseguida te doy los remapeos de memoria para que puedas trabajar con el bootloader de microchip

#include <18f2550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB
#use delay(clock=48M)


#include <usb_bootloader.h>
#build (reset=0x1000,interrupt=0x1008)
#org 0x0000,0x0FFF {}


funciona para el 18f4550 y el 18f2550.
el 2550 es el mismo que el 4550 solo que le faltan pines


no recuerdo si para entrar a modo bootloader es con el boton en B4 o en B5

es mas o menos asi el diagrama:

http://www.hobbielektronika.hu/forum/getfile.php?id=3688

solo que no recuerdo si el boton va en B4 o en B5

y colocale 2 leds en C0 y C1 asi podras ver cuando entra en modo bootloader


Disculpa mi ignorancia, pero para que es el bootloader que me acabas de pasar???
 
el bootloader

es un programa recidente dentro del micro "SI OCUPA RAM Y ROM" que se encarga de reescribir el micro sin necesidad de un grabador externo.

es decir el micro con su hardware minimo se reprograma asi mismo, el Arduino es eso un vulgar bootloader y un pequeño administrador de tareas.

el bootloader tiene la ventaja de:

usar el hardware minimo para hacer pruebas.
dejar de usar un grabador externo
ser rapido de ver una falla en el programa

desventajas de bootloader:
al ocupar RAM y ROM
al declarar siertas instrucciones dejan de ejecutarse.

un ejemplo es hacer mucho uso de variables

int16 array[60];

un ejemplo de un array de 60 en RAM cuando el programa corre no pasa nada pero si ocupamos mas RAM el programa empieza a hacer cosas que no pedimos por que se acaba la RAM

lo que pasa es que si trabajamos en CCS el CCS tiene mapeados los bancos de memoria del 18f4550 solo para variables y hay otro banco de memoria para trabajar con USB

en C18 puedes hacer uso de esos bancos de memoria con un archivo llamado LINKER que mapea los bancos de memoria y puede uno trabajar normalmente pero en CCS se acaban y uno o almenos yo no los se usar.

si es util el bootloader para proyectos como leer un puerto RS232 , escribir en una pantalla LCD , prender un rele o un led

pero para proyectos mas grandes como

una matriz de leds , generar colores con PWM y cositas asi que demandan mas RAM, pues la RAM se acaba , el compilador no te lo dice por que previamente el bootloader hace uso de la RAM.

y al acabarse la RAM el micro hace tonterias
 
el bootloader

es un programa recidente dentro del micro "SI OCUPA RAM Y ROM" que se encarga de reescribir el micro sin necesidad de un grabador externo.

es decir el micro con su hardware minimo se reprograma asi mismo, el Arduino es eso un vulgar bootloader y un pequeño administrador de tareas.

el bootloader tiene la ventaja de:

usar el hardware minimo para hacer pruebas.
dejar de usar un grabador externo
ser rapido de ver una falla en el programa

desventajas de bootloader:
al ocupar RAM y ROM
al declarar siertas instrucciones dejan de ejecutarse.

un ejemplo es hacer mucho uso de variables

int16 array[60];

un ejemplo de un array de 60 en RAM cuando el programa corre no pasa nada pero si ocupamos mas RAM el programa empieza a hacer cosas que no pedimos por que se acaba la RAM

lo que pasa es que si trabajamos en CCS el CCS tiene mapeados los bancos de memoria del 18f4550 solo para variables y hay otro banco de memoria para trabajar con USB

en C18 puedes hacer uso de esos bancos de memoria con un archivo llamado LINKER que mapea los bancos de memoria y puede uno trabajar normalmente pero en CCS se acaban y uno o almenos yo no los se usar.

si es util el bootloader para proyectos como leer un puerto RS232 , escribir en una pantalla LCD , prender un rele o un led

pero para proyectos mas grandes como

una matriz de leds , generar colores con PWM y cositas asi que demandan mas RAM, pues la RAM se acaba , el compilador no te lo dice por que previamente el bootloader hace uso de la RAM.

y al acabarse la RAM el micro hace tonterias

Pero yo en este momento no puedo utilizar el bootloader por falta de componentes, lo que quisiera hacer es hacerlo funcionar sin el mismo. Se puede?



Buenas, ahora e intentado utilizar algo como las banderas de programación para ver hasta donde llega mi programa, y e podido ver que el mismo no entra a la parte de la comunicacion serial. Lo que hace es prender y apagar el led antes del bucle, pero no llama al método o funcion "void rda_isr()".
Probé con el siguiente código. Espero de su ayuda

Código:
#include <18f4550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB 

#use delay(clock=48M) //para un cristal de 20Mhz

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=N)


char dato;

#int_rda             
void rda_isr()
{
   dato=getc();
   output_high(pin_a0);
   delay_ms(500);
   output_low(pin_a0);
         delay_ms(500);
   
}

void main()
{
   set_tris_a(0x00);
   output_high(pin_a0);
   delay_ms(500);
   output_low(pin_a0);
   delay_ms(500);
   output_high(pin_a0);
   delay_ms(500);
   output_low(pin_a0);
   delay_ms(500);
   output_high(pin_a0);
   delay_ms(500);
   output_low(pin_a0);
   delay_ms(500);
   output_high(pin_a0);
   delay_ms(500);
   output_low(pin_a0);
   delay_ms(500);
   
   while(1)// bucle infinito
   {
      enable_interrupts(int_rda);
      enable_interrupts(global);
      
      if(dato=='1')
      {
         output_high(pin_a0);
         delay_ms(500); //no recomiendo usar delays mas grandes a 10ms
      }
      
      if(dato=='2')
      {
         output_low(pin_a0);
         delay_ms(500);//no recomiendo usar delays mas grandes a 10ms
      }
   }//fin del bucle infinito
}
 
Última edición:
te puse lo del bootloader por que me preguntaste
¿por que los 48M?
ya explique por que.

ahora lo de las banderas pues casi no se les mueve por que CCS hace todo el trabajo cosa que C18 no hace es programacion directo de registros pero no tocare ese tema por que eres muy nuevo.

ahora tu error ¿donde fue?

pues que un programa en C consta de:

1.-funciones
2.-un principal "MAIN"
3.-un bucle para repetir n veces el programa puede ser finito o infinito

ejemplo del 1:

void leer()
{
//contenido
}

int leer(int num)
{
//contenido
return num;
}

char leer(char letra)
{
//contenido
return letra;
}

ejemplo del 2:

void main()
{
//interrupciones declaradas
//variables
//tareas del principal
}
//se acabo

ahora como se veria metiendo funciones externas

void main()
{
char tecla;
leer=leer();
//programas
}
//fin


ejemplo del 3:

como vimos el programa se ejecuta una vez pero nada mas si queremos que se ejecute todo el tiempo necesitamos un bucle

void main()
{
//declaraciones
//interrupciones
//variables

while(1) //bucle infinito
{

//programa que correra todo el tiempo

} //bucle infinito

}



y no no no no

no se te ocurra meter DELAYS dentro de una interrupcion

si metes delays menos van a funcionar los programas, el que te di deberia funcionar medianamente bien por que tienes delays es mas sere bueno contigo y veras que si va a funcionar.


Código:
#include <18f4550.h>
#fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN,WRTB,CPB 

#use delay(clock=48M) //para un cristal de 20Mhz

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=N)


char dato;

#int_rda             
void rda_isr()
{
   dato=getc();
}

void main()
{
  
   enable_interrupts(int_rda);
   enable_interrupts(global);
   
for(;;) { //bucle infinito
   if(dato=='1')
   {
      output_high(pin_a0);
   }
   
   if(dato=='2')
   {
      output_low(pin_a0);
   }

}//fin del bucle
}

¿que hise ?

le quite el delay

no sirve para nada solo sirve para frustrar
 
Última edición:
te puse lo del bootloader por que me preguntaste
¿por que los 48M?
ya explique por que.

ahora lo de las banderas pues casi no se les mueve por que CCS hace todo el trabajo cosa que C18 no hace es programacion directo de registros pero no tocare ese tema por que eres muy nuevo.

Muchísimas gracias por la mano que me estas dando y disculpa mi ignorancia, sólo que deseo poder introducirme un poco en lo que son comunicaciones inalámbricas. Esta tarde cuando salga del trabajo intento lo que me pasaste, muchas gracias nuevanente. Un abrazp
 
Última edición por un moderador:
Muchísimas gracias por la mano que me estas dando y disculpa mi ignorancia, sólo que deseo poder introducirme un poco en lo que son comunicaciones inalámbricas. Esta tarde cuando salga del trabajo intento lo que me pasaste, muchas gracias nuevanente. Un abrazp

Amigo..! Muy buenos días, hoy me di el tiempo en el trabajo y probé lo que me mandaste, y no lo puedo hacer funcionar ni siquiera en el proteus. Te paso un código que si me anda en el proteus, pero que no puedo hacer funcionar fisicamente :p Muchas gracias por la mano que me estas dando

Código:
Código:
#include <18f4550.h>
#fuses NOWDT,XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay (clock = 20000000 )
#use fast_io(B)
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
 
 
char valor;
 
void main()
{
   set_tris_b(0b00);  //Configura en o, osea
                    //se configura como salida
   //puts(string): esta función envía la cadena de texto contenida
   // dentro de los paréntesis al pin que hayamos configurado en el parámetro XMIT de la directiva #use RS232
 
   Output_low(PIN_B0);
   Output_low(PIN_B1); 
 
   while(true) 
   {
      valor=getc();//recibe el dato del pc y lo guarda en valor
      switch (valor)
      {
            case '1':///IZQUIERDA
            Output_high(PIN_B0);   //se prende el led 
            puts("1"); //saca un letrero en el hiperterminal
            break;
 
            case '2'://DERECHA
            Output_low(PIN_B0);   //se prende el led 
            puts("2"); //saca un letrero en el hiperterminal
            break;
 
            case '3'://REVERSA
            Output_high(PIN_B1);   //se prende el led 
            puts("3"); //saca un letrero en el hiperterminal
            break;
 
            case '4'://ADELANTE
            Output_low(PIN_B1);   //se prende el led 
            puts("4"); //saca un letrero en el hiperterminal
            break;
      }
   }
}
 
Última edición por un moderador:
pues ahi no hay interrupcion , todo es por poleo.

aver intenta con switch case en lugar de if

no se que vercion de CCS estes usando ami me dio muchos fallos CCS 5 y proteus 8
 
bueno yo busque el 4.084 que no me ha fallado

el 5 tiene varias fallas en el 18f4550 no se si en otros micros no falle

mientras que el 4.084 me falla el 16f886

son pros y contras
 
Hola amigos del foro!
de cuantos MHz debe ser el cristal para comunicar bien el Bluetooth con el Pic ? o no tiene nada que ver ?

saludos!
 
jaja nada que ver
en lo absoluto

bueno en realidad si pero no tocare el porque.

lo que importa nadamas es el baudrate digamos 9600 en el pic y 9600 en el bluetooth que por default biene en 9600
 
Buenas, disculpen el retraso pero he estado con el trabajo y no he tenido tiempo. Ya probé con lo de cambiar de compilador pero no me a dado resultados, lo que quería hacer es aprender a utilizar Basic para poder llevar a cabo dicha comunicación y si me recomiendan algún compilador. Debido a que no encuentro. Muchas gracias y que tengan un excelente día
 
Última edición por un moderador:
Atrás
Arriba