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

Software vs Hardware UART on PIC16f877a
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

Software vs Hardware UART on PIC16f877a
PostPosted: Mon Oct 10, 2005 11:04 am     Reply with quote

Hi all I have some code below which I'm using to interface my PIC16f877a with a GPS module, I have stripped this down to illustrate my question.

Code:
#use delay (clock=20000000)
#use RS232(STREAM=gps,BAUD=2400, PARITY=N, BITS=8, XMIT=PIN_C6, FORCE_SW, RCV=PIN_C7, DISABLE_INTS)
#use RS232(STREAM=dbg,BAUD=9600, XMIT=PIN_D0, FORCE_SW, INVERT)


void main()
{
   char  str[80];
   char  ch;

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);

   setup_wdt(WDT_2304MS);

   set_tris_b(0b11111011);


   while(1)
   {
      output_high(PIN_B0);

      delay_ms(500);

      output_low(Pin_B0);

      delay_ms(500);

      fprintf(dbg,"blink yah\n\r");

      fprintf(dbg, "fgetc ");


      while(1)
      {
         ch = fgetc(gps);
         fputc( ch, dbg );

         restart_wdt();
      }
   }

}


This works just great the way it is but if I add a FORCE_SW to the RS232 statement for the GPS Stream that it fails. The issue of course being that for some reason the GPS works just fine with the Hardware UART but not with software.

I can use this same circuit with the same GPS And PIC with Pic Basic Pro and the software Serial port works just fine. Now I was using the UART for something else so I'd like to figure out why it's not working with a software UART, does anyone have any ideas?

thanks!

-Raman
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 12:38 pm     Reply with quote

If you can post a small program in PicBasicPro that works, then do so.
Especially post the setup code for the serial ports, because I wonder
if PBP is really using a software USART.
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 2:05 pm     Reply with quote

PCM programmer wrote:
If you can post a small program in PicBasicPro that works, then do so.
Especially post the setup code for the serial ports, because I wonder
if PBP is really using a software USART.


Certainly here's a sample. I know it's using the software UART because I'm using different PINs!!! I moved it to these pin's because I was having an issue and wanted to try the hardware UART out to see if that worked, which it did. here's a line of code it PBP that works:

Code:
GPSIn VAR PORTB.2

    SerIn2 GPSIn,396,[wait("GPGGA,"),firstchar, DEC timeInt, DEC timeDec, DEC latInt, DEC latDec, DEC longInt, DEC longDec,DEC quality, DEC cSats]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 3:30 pm     Reply with quote

1. What is your version of the compiler ? This will be a number such
as 3.191, or 3.236, etc. It's given at the top of the .LST file, which
is in your project directory.

2. Does the program you posted do anything, or does it lock up ?
Describe what it does. Does it display the text from these two lines ?
Code:

fprintf(dbg,"blink yah\n\r");
fprintf(dbg, "fgetc ");


3. Post your #fuses statement. It looks like you're using PCW or
PCWH. I believe CCS puts the #fuses statement in some small
little .h file in your project directory.

4. In the program you posted, you're echoing incoming bytes from
the GPS out to the Debug port. In your PBP program, did you
do a test very similar to this ?

5. What is the byte data rate of the incoming GPS data ? Are there
any gaps between bytes ? If so, what are the size of the gaps in ms ?
Guest








PostPosted: Mon Oct 10, 2005 3:39 pm     Reply with quote

Okay I'm using the 30day demo to see if I can do somethings with it that I can't get our existing copy of the Hi-Tech compiler to do (So far I can!) so we're planning on purchasing.

1) the compiler version is shown as: CCS PCM C Compiler, Version 3.236d, 11660 07-Oct-05 16:27

2) Yes it outputs the blink yah line, and the fgetc line then it output complete garbage, although it's consistent garbage, i.e. it looks just like it's at slightly the wrong baud rate or something. Removing the Force_SW line to make it use the Hardware UART on those two pins causes it to work as expected, producing the expected output. So it's almost as if the hardware UART as the correct BAUD rate but the software one does not.

3) Fuses statement ( in fact complete header file)

Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)



4) Yes I did something similar in PBP and it works as expected

5) I'm not sure, I don't currently have a scope available to me to do this with, but I do know that if I use PBP or the Hardware UART I get the expected data.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 4:24 pm     Reply with quote

Code:
#FUSES LVP                     

The first thing to do is change that fuse to NOLVP.
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 4:48 pm     Reply with quote

PCM programmer wrote:
Code:
#FUSES LVP                     

The first thing to do is change that fuse to NOLVP.


No good, same result. I should mention that I'm using EPICWin to program, so I went and checked the fuse settings there (Configuration) and I have the following set

Watch Dog
Brown Out
Flash Program Write

thank you!

-R
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2005 5:07 pm     Reply with quote

To test your problem further, I need to make a split RS232 cable adapter.
I might have one somewhere, but I can't work on it until tomorrow
morning.
Guest








Re: Software vs Hardware UART on PIC16f877a
PostPosted: Mon Oct 10, 2005 10:23 pm     Reply with quote

I noticed that the only "tris" statement in your code is for port_b.

Once you revert from the hardware USART to a software UART, you'll likely need also to provide a "tris_a" statement to assure your receive pin is an input and your transmit pin is set as an output.
Guest








Re: Software vs Hardware UART on PIC16f877a
PostPosted: Mon Oct 10, 2005 10:25 pm     Reply with quote

oops, meant to say a "tris_c" statement...
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

PostPosted: Tue Oct 11, 2005 9:40 am     Reply with quote

Definitely a good thought. As that's left over from when I moved the device from the pins I had been using to the hardware UART to test that. Changing the statement to "set_Tris_c" has no effect, I get the same output.

Here's the output in case it's helpful:

Code:

blink yah
fgetc $#��R��c�,��kF#�c�,��#QLHt�YT#�K��c�,'�F���$#��R��c�,��KF#�c�,��#QLHt�Y
T#�k��c�,'�F���$#��R��c�,��KF#�c�,��#QLHt�YT#�K��c�,'�F���$#��R��c�,��KF#�c�
,��#QLHt�YT#�K��c�,'�F���$#��R��c�,��kF#�c�,��#QLHt�YT#�K��c�,'�F���$#��R��c�
,��KF#�c�,��#QLHt�YT#�K��c�,'�F���
ckielstra



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

View user's profile Send private message

PostPosted: Tue Oct 11, 2005 10:16 am     Reply with quote

Code:
      while(1)
      {
         ch = fgetc(gps);
         fputc( ch, dbg );

         restart_wdt();
      }
A problem with this code using software UARTs is that while you are transmitting data to the dbg port you are missing the first few bits of data comming in on the gprs port. With hardware UARTs this is no problem as these will buffer data while handling the other port.

If the data you are receiving is terminated with a newline character you can try an easy workaround using fgets() instead of fgetc().

I also added fast_io as it results in shorter code and to make sure the compiler doesn't mess with your TRIS settings.

Code:
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No 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     //<-- Changed  //Disable Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay (clock=20000000)
#use RS232(STREAM=gps,BAUD=2400, PARITY=N, BITS=8, XMIT=PIN_C6, FORCE_SW, RCV=PIN_C7, DISABLE_INTS)
#use RS232(STREAM=dbg,BAUD=9600, XMIT=PIN_D0, FORCE_SW, INVERT)

#use fast_io(B);      // <-- ADDED
#use fast_io(C);      // <-- ADDED


void main()
{
   char  str[80];
   char  ch;

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);

   setup_wdt(WDT_2304MS);

   set_tris_b(0b11111011);
   set_tris_c(0b10111111);     // <-- Added


   while(1)
   {
      output_high(PIN_B0);

      delay_ms(500);

      output_low(Pin_B0);

      delay_ms(500);

      fprintf(dbg,"blink yah\n\r");

      fprintf(dbg, "fgetc ");


      while(1)
      {
         fgets(str, gps);    // <-- Changed fgetc() to fgets()
         fputs(str, dbg);    // <-- Changed fputc() to fputs()

         restart_wdt();
      }
   }

}
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

PostPosted: Tue Oct 11, 2005 11:02 am     Reply with quote

First let me say Wow, this is great, I've gotten almost no feedback from my questions for That other compiler having this level of response is definitely making this the one to be using.

Now on to my experiments with the latest suggestions:

I added the fast_io code in (had to remove the ; at the end to get it compile, I think that's correct)

and no dice. What ends up happening is the watch dog timer ends up resetting before anything comes in off of the port. and I end up just getting repeated fgetc blink yah lines out. Disabling the watchdog timer causes a hang after the fgetc output.

Again switching off the software port, and using the hardware one causes it to behave as expected.

-R
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 11, 2005 11:29 am     Reply with quote

I don't have your exact hardware, but I made a test setup that
should be similar. I made a Rx/Tx splitter cable and connected
one cable to COM1 and the other to COM2 on my PC. I opened
two terminal windows, one for each COM port, and set one to 2400
and the other to 9600.

If I just type in text from the keyboard, there's little or no problem.
If I mash several keys at once ("asdf"), then I get bad characters
displayed. But that's what I'd expect. Here's a sample. The first part
is typed normally, and then I start mashing four keys at a time:
Quote:
asdfasdfasdfasdfasdfasdfasdfasdfafsdf�sdfX�df�d�f��dsf�df�d�

But I think you have implied that somehow this all works flawlessly
with PicBasicPro. So I'm curious. I have PBP on my system.
Can you post a short but complete PBP test program, and do the same
test that I did above ? I would like to test it, and look at their .LST
file.

Here's my test program. The code generates two software UARTs.
Code:

#include <16F877A.H>
#fuses  HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)

#use RS232(STREAM=gps,BAUD=2400, RCV=PIN_C7)

#use RS232(STREAM=dbg,BAUD=9600, XMIT=PIN_C6) 

//======================================
main(void)
{
char ch;

while(1)
 {
  ch = fgetc(gps);
  fputc( ch, dbg);
 }

}
ramans



Joined: 10 Oct 2005
Posts: 9

View user's profile Send private message

PostPosted: Tue Oct 11, 2005 12:20 pm     Reply with quote

Here's some PBP code that works:

Code:

DEFINE OSC 20

INCLUDE "modedefs.bas"

DEFINE DEBUG_REG PORTD
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 1

baud VAR WORD
onoff VAR BYTE

LET baud = 396

again: Debug $0d,$0a
        Debug "[Not Inverted] [",DEC baud,"] Hello."
       
LET onoff = 0

GoSub GetCurrentPosition


GoTo again


'
' Get Current GPS Position
'
GetCurrentPosition:


loop:
instr VAR BYTE[80]

   IF onoff = 0 Then
      High PORTB.0
      onoff = 1
   Else
      Low PORTB.0
      onoff = 0
      EndIF
      
   bvar1 VAR BYTE
   bvar2 VAR BYTE
   

    SerIn2 PORTC.7,baud,[STR instr\80\$0d]
    Debug STR instr,$0d,$0a

    GoTo loop
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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