# HC-05 PIC18f4550



## AECP95 (Oct 31, 2015)

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:

```
#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:






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


----------



## TRILO-BYTE (Oct 31, 2015)

aver intenta asi:



```
#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


----------



## AECP95 (Nov 1, 2015)

TRILO-BYTE dijo:


> aver intenta asi:
> 
> 
> 
> ...



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


----------



## TRILO-BYTE (Nov 1, 2015)

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:






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


----------



## AECP95 (Nov 1, 2015)

TRILO-BYTE dijo:


> espera acabo de ver mi error es que no hay bucle infinito intenta esto:
> void main()
> {
> 
> ...




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


----------



## TRILO-BYTE (Nov 1, 2015)

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


----------



## AECP95 (Nov 1, 2015)

TRILO-BYTE dijo:


> 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.
> 
> ...



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


```
#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
}
```


----------



## TRILO-BYTE (Nov 1, 2015)

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.



```
#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


----------



## AECP95 (Nov 2, 2015)

TRILO-BYTE dijo:


> 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


----------



## TRILO-BYTE (Nov 2, 2015)

es que antes de hacer cosas imposibles debes hacer ejercicios simples.

por eso critico yo Arduino, por que no aprenden a programar


----------



## AECP95 (Nov 2, 2015)

TRILO-BYTE dijo:


> es que antes de hacer cosas imposibles debes hacer ejercicios simples.
> 
> por eso critico yo Arduino, por que no aprenden a programar



Es que se me complica con lo que es transmisiones inalámbricas, y si, arduino es para aquellos que buscan hacer las cosas rápidas sin consultar. Espero que funcione


----------



## AECP95 (Nov 4, 2015)

AECP95 dijo:


> 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  Muchas gracias por la mano que me estas dando

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;
      }
   }
}
```


----------



## TRILO-BYTE (Nov 4, 2015)

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


----------



## AECP95 (Nov 4, 2015)

TRILO-BYTE dijo:


> 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



Me podrías pasar el compilador que utilizas tu para así comprobar que no es un fallo del mismo. Muchas gracias y disculpa la molestia...!


----------



## TRILO-BYTE (Nov 4, 2015)

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


----------



## ilcapo (Nov 7, 2015)

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!


----------



## TRILO-BYTE (Nov 7, 2015)

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


----------



## AECP95 (Nov 20, 2015)

Buenas, disculpen el retraso pero *h*e estado con el *trabajo* y no *h*e 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


----------



## TRILO-BYTE (Nov 20, 2015)

pero no entiendo en que falla

alomejor el que falla es el programador y no el compilador


----------



## ilcapo (Nov 23, 2015)

Y cual seria el codigo completo que esta probando ? y el circuito ?


----------



## jose palacin (Abr 12, 2021)

TRILO-BYTE dijo:


> pero no entiendo en que falla
> 
> alomejor el que falla es el programador y no el compilador


Hola buenas noches, quizas me podria dar unos alcances, tengo el mismo inconveniente probe varias maneras en proteus funciona bien, descarte el modulo bluetooth, para verificar si estaba mal pero lo probe con la pc con un modulo ftdi y el bluetooth tx y rx de datos si llegan bien los caracteres y en viceversa, pero al grabarlo al Pic18f4550 resutla que el app no me responde, alguna sugerencia de antemano muchas gracias.


----------



## TRILO-BYTE (Abr 12, 2021)

Huuuu eso fue hace 6 años 

Pero que estás haciendo o sube tu código.
Adivino no soy.

El 4550 debes tener en cuenta el PLL prescaler. Para que no tengas problemas.


----------

