Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

30/08/2012 #1


Comunicación serie RS-232 con PIC18F4550 ¿Por qué no funciona?
Que tal estoy haciendo un proyecto de comunicacion serie RS-232 entre 2 pics 18f4550 pero resulta que no funciona supongo que es una parte del programa, ya que este mismo proyecto lo hice con pics 16f877a y al simularlo en proteus funcionó correctamente, yahe intentado varios cambios al prgrama y no funciona, quisiera ver si me podrian ayudar a verificar que los programas del pic transmisor y del receptor sean correctos,gracias.

Programa del trasnmisor:

Código:
//Programa para el transmisor
#include <18F4550.h>
#include <stdio.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                   //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#USE STANDARD_IO(A)
#USE STANDARD_IO(b)
#USE STANDARD_IO(C)
char a=0xd;
int8 c=0;

#int_TIMER1
void  TIMER1_isr(void) 
{
c++;
if(c==3){
output_toggle(pin_a1);  
c=0;}
set_timer1(0);
}

void main()
{

   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!
   
   While(1){
  
   //RB0,RB1,RB2,RB3 Y RB4 botones
       if(input(pin_b0)==1){  //BOTON1
    putc('E');  //Enciende Pin B1 en el Receptor
    putc('P');
    putc('B');
    putc('1');
    putc(a);}

   
       if(input(pin_b1)==1){  //BOTON2
    putc('E');  //Enciende Pin B2 en el Receptor
    putc('P');
    putc('B');
    putc('2');
    putc(a);}


       if(input(pin_b2)==1){  //BOTON3
    putc('E');  //Enciende Pin B3 en el Receptor
    putc('P');
    putc('B');
    putc('3');
    putc(a);}

    
       if(input(pin_b3)==1){  //BOTON4
    putc('E');  //Enciende Pin B4 en el Receptor
    putc('P');
    putc('B');
    putc('4');
    putc(a);}

    
       if(input(pin_b4)==1){  //BOTON5
    putc('E');  //Enciende Pin B1 en el Receptor
    putc('P');
    putc('B');
    putc('5');
    putc(a);}
    
    
      }

}
Programa del receptor:

Código:
//Programa Receptor
#include <18F4550.h>

#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)  //---------------------------------------------

#use rs232(baud=9600,parity=N,xmit=PIN_c6,rcv=PIN_c7,bits=8)

#include <stdio.h>


#USE STANDARD_IO(A)
#USE STANDARD_IO(B)
#USE STANDARD_IO(C)
#USE STANDARD_IO(E)


int1 llave[5]={0,0,0,0,0};
int16 cont[5]={0,0,0,0,0};
const int16 ciclo=800;
char cant[5];
//signed int16  pwm1=511,pwm2=1023;

void main()
{

 //setup_adc_ports(NO_ANALOGS|VSS_VDD);
 //setup_adc(ADC_OFF);
 //setup_spi(SPI_SS_DISABLED);
 //setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,249,1);
 //setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  // setup_ccp1(CCP_PWM);
   //setup_ccp2(CCP_PWM);
   //set_pwm1_duty(pwm1);
  // set_pwm2_duty(pwm2);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!;                    

   while(1){
 
 if(kbhit()){
 gets(cant);

 }
 else {    
  cant[0]='0';
   cant[1]='0';
   cant[2]='0';
   cant[3]='0';
   cant[4]='0';}
  

   if(cant[0]=='E'&&cant[1]=='P'&&cant[2]=='B'&& cant[3]=='1'){
   output_high(pin_b1);  //Activa B1
   llave[0]=1;
   cont[0]=0;}
  
   if(cant[0]=='E'&&cant[1]=='P'&&cant[2]=='B'&& cant[3]=='2'){
   output_high(pin_b2);  //Activa RB2
   llave[1]=1;
   cont[1]=0;}
 
   
   if(cant[0]=='E'&&cant[1]=='P'&&cant[2]=='B'&& cant[3]=='3'){
   output_high(pin_b3);  //Activa RB3
   llave[2]=1;
   cont[2]=0;}
 
   
   if(cant[0]=='E'&&cant[1]=='P'&&cant[2]=='B'&& cant[3]=='4'){
   output_high(pin_b4);  //Activa RB4
   llave[3]=1;
   cont[3]=0;}
 
   
   if(cant[0]=='E'&&cant[1]=='P'&&cant[2]=='B'&& cant[3]=='5'){
   output_high(pin_b5);  //Activa RB5
   llave[4]=1;
   cont[4]=0;}
 
      
    if(llave[0]==1){      
    cont[0]=cont[0]+1;
    if(cont[0]==ciclo){
    output_low(pin_B1);
    llave[0]=0;}    }
    
    if(llave[1]==1){     
    cont[1]=cont[1]+1;
    if(cont[1]==ciclo){
    output_low(pin_b2);
    llave[1]=0;}    }
    
    if(llave[2]==1){     
    cont[2]=cont[2]+1;
    if(cont[2]==ciclo){
    output_low(pin_b3);
    llave[2]=0;}    }
    
    if(llave[3]==1){    
    cont[3]=cont[3]+1;
    if(cont[3]==ciclo){
    output_low(pin_b4);
    llave[3]=0;}    }
    
    if(llave[4]==1){   
    cont[4]=cont[4]+1;
    if(cont[4]==ciclo){
    output_low(pin_b5);
    llave[4]=0;}    }
         
   }

}
30/08/2012 #2

Avatar de ByAxel

Hola:
Por lo pronto se me ocurre que configures bien los Fuses de este PIC ya que los veo incompletos y especialmente los del oscilador. El 18F4550 es muy distinto que el 877A.

saludos
30/08/2012 #3


ByAxel dijo: Ver Mensaje
Hola:
Por lo pronto se me ocurre que configures bien los Fuses de este PIC ya que los veo incompletos y especialmente los del oscilador. El 18F4550 es muy distinto que el 877A.

saludos
Justamente me parece que es eso pero no se configurar los fuses de este pic ya que apenas empecé a trabajar con este pic
30/08/2012 #4

Avatar de ByAxel

Para eso necesitas revisar la hoja de datos del 18F4550 en la sección del oscilador, guiarte por el diagrama de bloques y sugiero que utilices el Wizard del CCS para configurar.

pic18f4550

Te darás cuenta que comparten nombres similares entre el diagrama y el wizard.

Lee esto para guiarte un poco como configurar el oscilador a la frecuencia que requieras.
http://picmania.garcia-cuervo.net/conceptos.php#USB4Mhz

saludos
31/08/2012 #5


Que tal me handicho que en el pic c compiler 4.104 tiene problemas al compilar este tipo de pics (4550) y que instale el pic c compiler 4.068 que en ese no hay problemas no se si sepan algo sobre eso...
31/08/2012 #6

Avatar de ByAxel

Si, de echo por lo general el CCS sufre de varios bugs, solo queda probar y a ver que tal .
Tengo una más que el 4.104 y no pasa nada hasta ahora, pero es bueno saber de ASM ya que cuando llegan problemas, basta con abrir el archivo *.lst que genera para revisar el "porque no funciona como quiero ".
01/02/2013 #7


Comunicación entre PICS 18F4550 por RS232
Buenas, estoy intentando comunicar dos pics 18f4550 por rs232, quiero que el pic 1 envíe un número ingresado por teclado al pic 2, este pic número dos habilita la interrupción rda y verifica que el número que llega sea menor o igual a 3 si es así entonces incrementa una variable y retorna al programa principal, donde con esta variable recién incrementada, entra en un if que permite enviar por la 232 al pic número uno, una constante llamada tecla con valor de 57 para que sea entonces habilitada la interrupción rda en el pic uno y mostrar por una lcd este num 57.

El problema ocurre en que el pic uno cuando presiono un número sea cual sea lo envía por PUTC() y ahí mismo se activa en este mismo pic la INT_RDA y muestra el valor que acabo de transmitir sin que pase por el pic dos. Anexo mi programa esperando que puedan ayudarme, un saludo.

PIC 1

Código:
#include <18f4550.h>

#FUSES INTRC_IO
#FUSES NOIESO
#FUSES FCMEN
#FUSES NOMCLR
#FUSES NOXINST

#use delay(clock=8000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7,ERRORS)

#define use_portb_lcd TRUE
#define use_portb_kbd TRUE
#include <lcd420.c>
#include <kbd.c>

   int valor;                
   char tecla;                //Dato ASCII tecla pulsada 
  

#int_RDA                               //Interrupción por recepción de datos

void RDA_isr(){

   valor=getc();                 //En "valor" el dato recibido via RS232
   printf(lcd_putc, "\fRecibido %d ", valor);   //Se muestra en pantalla información recibida
   delay_ms(500);
   }



void main () {
   
   setup_oscillator(0xF6);
   port_b_pullups(TRUE);
   lcd_init();                   //Inicialización del display
  
   enable_interrupts(INT_RDA);   //Habilitación interrupción por recepción RS232
   enable_interrupts(GLOBAL);
   set_tris_c(0x80);
  
   while(1){
         tecla=kbd_getc();       //En "tecla" la tecla pulsada
         valor=tecla-48;         //Valor ASCII se pasa a su valor numérico
         if(tecla!=0){           //Si se pulsa tecla...
            disable_interrupts(INT_RDA);
            putc(valor);         //...se envía contenido de "valor" (tecla pulsada)
            printf(lcd_putc, "\fEnviado %d", valor);   //Se muestra en pantalla información enviada
            delay_ms(500);  
         }
         enable_interrupts(INT_RDA);
   }
}
PIC 2
Código:
#include <18f4550.h>

#FUSES INTRC_IO
#FUSES NOIESO
#FUSES FCMEN
#FUSES NOMCLR
#FUSES NOXINST

#use delay(clock=8000000)

#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7,ERRORS)

#define use_portb_lcd TRUE
#define use_portb_kbd TRUE
#include <lcd.c>
#include <kbd.c>

   int valor;                 
   int tecla=57;               
   int x;
  

#int_RDA                               //Interrupción por recepción de datos

void RDA_isr(){

   valor=getc();                 //En "valor" el dato recibido via RS232
   if(valor<=3){ 
   valor=valor*3;
   x=x+1;
   }
}


void main () {
   
   setup_oscillator(0xF6);
   port_b_pullups(TRUE);
   lcd_init();                   
  
   enable_interrupts(INT_RDA);   //Habilitación interrupción por recepción RS232
   enable_interrupts(GLOBAL);
   set_tris_c(0x80);
  
   while(1){
       
         if(x!=0){               
            disable_interrupts(INT_RDA);
            putc(tecla);         
            delay_ms(500);
            x=0;
            enable_interrupts(INT_RDA);
         }
   }
}
29/10/2014 #8


Hola gente, buenas tardes.
Resulta que estoy haciendo un pequeño sistema, en donde tengo que censar 9 entradas, las cuales están conectadas a un multiplexor, y éste al pin B0 del pic 18f4550.

El caso es que cuando la entrada x es activada, el pic, recibe el dato de la posición del multiplexor, justo un instante después de la interrupción. y lo manda a unos leds, de esa forma puedo ver que la entrada numero x estaba activa. hasta allí, todo bien, tal como necesito.

El problema resulta cuando quiero enviar datos desde el puerto serial a una PC, justo en el instante de la interrupción.
Intento mandar un "" pero manda un signo "=", y aunque cambie el dato a enviar, el pic, continua mandando el signo "=".

Vi algunos ejemplos y pensé que debería haber agregado la librería string.h... sin resultados.
intenté agregar la librería stdlib, porque pensé que seria un problema de tipo de dato... negativo.

Necesito mandar "hola" y que en la PC (o terminal) aparezca "hola" y así...

Aún soy un novato en esto de los PICs, pero son bastante interesantes.
¿Alguien me echa una mano?
Gracias de antemano.
Adjunto mi programa y la simulación. Uso CCS y proteus

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

#include <string.h>
#include <stdlib.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz 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,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#int_EXT
void  EXT_isr(void) 
{
   output_toggle(PIN_D0);
   output_bit(PIN_D1, input(PIN_B1));
   output_bit(PIN_D2, input(PIN_B2));
   output_bit(PIN_D3, input(PIN_B3));
   output_bit(PIN_D4, input(PIN_B4));
   putc('1');
}

#int_RDA
void  RDA_isr(void) 
{

}



void main()
{

   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_EXT);
   ext_int_edge (H_TO_L);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   while(true){
   }

}
Archivos Adjuntos
Tipo de Archivo: zip serialeinterrupciones.zip (21,7 KB (Kilobytes), 4 visitas)
29/10/2014 #9


podes desactivar las interrupciones, o la int ext, antes de enviar los datos por el puerto rs232, y volverlas a activar cuando termine, pero tene en cuenta lo que ocurra si hubiese una int en el intervalo que esta desactivada

EDIT: creo que no es este tu problema, mejor proba poniendo printf("1"); o putc("1"); o lo que quieras enviar, pero entre comillas dobles
29/10/2014 #10

Avatar de Saint_

Hola, te comento que no hay problemas en el programa que subiste.
es mas, solamente lo recompile y funciono "al turo".
este el codigo que compile.

Código:
#include <18F4550.h>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV21                   //Brownout reset at 2.1V
#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,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#int_EXT
void  EXT_isr(void) 
{
   output_toggle(PIN_D0);
   output_bit(PIN_D1, input(PIN_B1));
   output_bit(PIN_D2, input(PIN_B2));
   output_bit(PIN_D3, input(PIN_B3));
   output_bit(PIN_D4, input(PIN_B4));
   putc('1');
}

#int_RDA
void  RDA_isr(void) 
{

}



void main()
{

   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_EXT);
   ext_int_edge (H_TO_L);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   while(true){
   }

}
El problema estaba en el uso de las herramientas de proteus, si se usa el COMPIM este saca los datos por el puerto serie de la PC pero a esta herramienta dentro de proteus hay que entregarle señales rs232 TTL o en el caso no usar el max232 ta que este invierte la lógica
0=>+12v 1 =>-12v, si quieres usar el max 232 en proteus y ver las tramas puedes usar la herramienta del virtual terminal, normalmente a este también se le entrega señales rs232 TTL peor también se lo puede configurar para que reciba señales invertidas y así poder usar el max232.

Imágenes Adjuntas
Tipo de Archivo: png Dibujo.PNG (86,5 KB (Kilobytes), 11 visitas)
Archivos Adjuntos
Tipo de Archivo: rar Nueva carpeta (3).rar (149,6 KB (Kilobytes), 8 visitas)
16/01/2015 #11


¿Alguien pudo trabajar a 48Mhz conjuntamente con el bus RS-232 del PIC?
Al momento de recepcionar los datos mediante el bus RS-232 con INT_RDA, éste se queda trabado como si estuviere entrando al modo Sleep.
Éstos son los fuses que declaré.
¿Alguien me puede decir dónde estoy errando o me si falta declarar algún fuse?

Código:
#include <18F4550.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOVREGEN //USB voltage regulator disabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#FUSES CPUDIV1 
#FUSES PLL5 
#FUSES HSPLL 
#FUSES PUT 
#FUSES MCLR 
#FUSES USBDIV 
#FUSES NOIESO 

#use delay(clock=48000000,crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8,stream=PORT1,restart_wdt)

#define LED PIN_B3
#use standard_io(b)

#int_rda
void interup_ird()
{
output_toggle(LED);

}

void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);


//Example blinking LED program
output_low(LED);
while(true)
{
output_toggle(PIN_B4);
delay_ms(300);
}
17/01/2015 #12
Moderador

Avatar de D@rkbytes

washington14 dijo: Ver Mensaje
¿Alguien pudo trabajar a 48Mhz conjuntamente con el bus RS-232 del PIC?
Al momento de recepcionar los datos mediante el bus RS-232 con INT_RDA, éste se queda trabado como si estuviere entrando al modo Sleep.
Éstos son los fuses que declaré.
¿Alguien me puede decir dónde estoy errando o me si falta declarar algún fuse?
Cuando ocurre una interrupción por recepción, se pone en 1 el bit 5 del registro PIR1 (RCIF: EUSART Receive Interrupt Flag bit)
Este bit únicamente se pone en 0 cuando se lee el buffer de recepción (RCREG)
Entonces, si durante el servicio de interrupción no se lee RCREG, el programa se queda creando un bucle dentro del servicio de interrupción.

Por lo tanto, durante el servicio de interrupción por EUSART, se debe leer forzosamente el registro RCREG para que el bit RCIF sea puesto en 0 (No sirve poner en 0 por código ese bit)

Prueba con este código para que realices una prueba de lo que menciono.
Código PHP:
#include <18f4550.h>
// Palabra de configuración para usar un cristal de 20MHz y llevar el CPU a 48MHz.
#fuses   NOFCMEN,NOIESO,HSPLL,CPUDIV1,PLL5,NOPBADEN,NOLVP
#use     delay(clock = 48MHz)
// Configuración por defecto para el módulo EUSART:
#use     rs232(UART1)   // 9600,N,8,1

#define  LED_INT  PIN_B6         // LED en RB6
#define  LED_RB7  PIN_B7         // LED en RB7

#int_rda
void sdi_rx_eusart (void)
{
   
int8 dato getc();           // Leer el registro RCREG
   
output_d(dato);               // Puerto D = 8 bits de datos del registro RCREG
   
output_toggle(LED_INT);       // Cambiar de estado "LED_INT"
}

void main (void)
{
   
enable_interrupts(INT_RDA);
   
enable_interrupts(GLOBAL);

   
output_low(LED_INT);          // "LED_INT" en 0 al iniciar.
   
output_d(0x00);               // Puerto D en 0 al iniciar.
   
   
putc(0x00);                   // Inicializar el bus RS-232
   
delay_ms(100);                // Retardo de 100ms.
   
puts("Hola Mundo");           // Enviar algo al iniciar.
   
   
while(true)
   {
      
output_toggle(LED_RB7);    // Cambiar de estado "LED_RB7"
      
delay_ms(500);             // Retardo de 500ms.
   
}

Este programa ha sido probado físicamente. (CPU = 48MHz. EUSART = 9600 Bps.)
17/01/2015 #13


Gracias he si ha funcionado. este detallito no lo sabia.
02/05/2015 #14


Saludos a todos.
Yo estoy haciendo un proyecto donde adquiero datos de varios sensores: (Temperatura, presión, humedad, giroscopio y magnetómetro)
Los proceso en el PIC luego los despliego con LabView en la PC, ésto último mediante serial.

Apenas estoy en las primeras etapas y no sé mucho sobre PICs.
Mi problema es que cuando envío datos o imprimo cadenas con printf al puerto serial, deben ser cadenas cortas o inevitablemente cortará mi mensaje (se come mi último dato en el caso de ser variables lo que envío).
Tengo el PIC C Compiler versión 5.010.

Mi código:

Código:
#include <18f4550.h>

 #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
 #use delay(clock=48000000)
 
#define LCD_RS_PIN PIN_D0                                                    
#define LCD_RW_PIN PIN_D1         
#define LCD_ENABLE_PIN PIN_D2                           
#define LCD_DATA4 PIN_D4                                                          
#define LCD_DATA5 PIN_D5                                    
#define LCD_DATA6 PIN_D6                                                                            
#define LCD_DATA7 PIN_D7   
 #include <LCD.C>
 
 #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
void main()
 {
 int8 i1=9;
 lcd_init(); //función de inicialización del LCD
//Mostramos una cadena en la terminal
 delay_ms(1000);
 printf("Esto es una cadena\n"); //Esta cadena se despliega completa
 delay_ms(1000);
 //Mostramos una cadena de texto junto con el valor de una variable    
 //en la terminal.
 printf("El valor de la variable i1 es: %1d jajaja\n",i1); //esta cadena no me sale incompleta en el serial, sólo me sale: "El valor de la variable i1 es: "
//
 printf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",i1,i1,i1,i1,i1,i1,i1,i1,i1,i1,i1,i1,i1,i1,i1);
 //Esta última cadena es de prueba, probé imprimir 10 variables, me imprime 9, con 15 me imprime 14, es decir siempre me corta la ultima variable
 //Mostramos el valor de la variable por el LCD
 printf (lcd_putc,"El valor de i1\n es: %d",i1);

 }
02/05/2015 #15
Moderador

Avatar de D@rkbytes

¿Qué cristal estás usando para llevar el CPU a 48 MHz.?
Porque al parecer tienes mal la palabra de configuración.
02/05/2015 #16


uno de 4MHz.. ya se que ese no es forzosamente de HS, alta velocidad, pero todo lo demas me corre bn, cuando lo cambio por uno de 20 Mhz cambio el fuse PLL a PLL5...
03/05/2015 #17
Moderador

Avatar de D@rkbytes

OK. Como el cristal que usas es de 4MHz, de preferencia utiliza el fuse XT.
Eso hace que el oscilador trabaje mejor dentro del rango de esa frecuencia.

Pero mira esto, yo si recibo completas las cadenas que escribes: Cadenas electring1620.jpg

Y si yo mando una cadena larga, también la recibo completa: Cadena D@rkbytes.jpg

¿Qué estás empleando para adaptar los niveles del puerto serie?
¿Usas un adaptador de USB a RS-232? Estas pruebas las realicé con un adaptador genérico.

Para no estar adivinando, siempre debes incluir toda la información necesaria. (Incluyendo esquema.)

Saludos.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.