CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RS232 problem with PIC18f452

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








RS232 problem with PIC18f452
PostPosted: Wed Dec 22, 2004 9:57 pm     Reply with quote

I am using a serial LCD to debug my PIC programs.
I have been using it fine with the PIC16f84a which has no hardware USART. Since the PIC and the serial LCD were directly wired, I used the INVERT option.

Now, I am trying to use a PIC18f452, which has a hardware USART. I don't want to use the software USART (by changing the xmit pin or using the option FORCE_SW).

The problem is that the LCD is getting garbage characters. How can I fix this problem???.

Here is some code snipet:

Code:
#include <18F452.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,WDT128,XT, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=2400,parity=N,invert,xmit=PIN_C6,rcv=PIN_C7,bits=8)



Code:
#define COUNT_TO 31
byte count;
unsigned int num;
int printmsg;

void clearScreen(void);

#INT_RTCC
clock_isr() {
   if(--count==0) {
      num++;
      count = COUNT_TO;
      printmsg = 1;
   }
}

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);

      count = COUNT_TO;
   num = 0;
   printmsg = 1;
   
   /* give plenty of time to the LCD to initialize */
   delay_ms(1000);

   set_rtcc(0);
   setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   while(1) {
      if (printmsg) {
         clearScreen();
         printf("Count: %u", num);
         printmsg = 0;
      }   
   }
}

void clearScreen(void)
{
   putc(254);
   putc(1);
return;
}
Guest








PostPosted: Wed Dec 22, 2004 9:59 pm     Reply with quote

I forgot... This program is supposed to count seconds.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 22, 2004 10:55 pm     Reply with quote

Have you really compiled this code ? If I try to compile your program,
the line below causes this error message:
"USE parameter value is out of range H/W USART can not invert"
Code:
#use rs232(baud=2400,parity=N,invert,xmit=PIN_C6,rcv=PIN_C7,bits=8)
Guest








PostPosted: Thu Dec 23, 2004 8:43 am     Reply with quote

You get this error message because of the invert in the fuse statement. If you remove that invert option, the code compiles fine.

Anyway, I did get it to count seconds and display the result correctly on the LCD by forcing the compiler to use the Software USART on C6 and C7 pins.

But I was hoping there was another way to do this (using just hardware USART).

here is the most updated version of the code (working)

Code:
#include <18F452.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,WDT128,XT, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,FORCE_SW,invert,bits=8)



Code:
#define COUNT_TO 31
byte count;
unsigned int num;
int printmsg;

void clearScreen(void);

#INT_TIMER0
clock_isr() {
   if(--count==0) {
      num++;
      count = COUNT_TO;
      printmsg = 1;
   }
}

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128 | RTCC_8_BIT);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);

      count = COUNT_TO;
   num = 0;
   printmsg = 1;
   
   /* give plenty of time to the LCD to initialize */
   delay_ms(1000);

   set_timer0(0);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   while(1) {
      if (printmsg) {
         clearScreen();
         printf("Count: %u", num);
         printmsg = 0;
      }   
   }
}

void clearScreen(void)
{
   putc(254);
   putc(1);
return;
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Dec 23, 2004 11:25 am     Reply with quote

The hardware UART doesn't support the invert option. Sending non-inverted data to the LCD will result in garbage.
Inverting the data yourself before sending it to the hardware UART won't work because the start- and stopbits will still be non-inverted. Your only option for using the hardware UART is to add an hardware inverter (cheap).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group