Searching \ for 'USART problems....' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/io/serials.htm?key=usart
Search entire site for: 'USART problems....'.

Truncated match.
PICList Thread
'USART problems....'
1999\09\23@152922 by David Williams

flavicon
face
Hello all,

I'm having a problem with USART.  Here's the situation:  I'm using a
PIC16F877 and I've set it up
at 9600 baud.  I'm ready the program memory  and then dumping it out the
USART to COM1 on the computer.  I'm using Windows 95 Hyperterminal 9600
8-N-1 Autodetect.  The first line of program memory (addresses 0x0000 to
0x0007) look like this:

0183 3000 008A 2804 0183 120A 118A 2FE4   ........

Here's my original code in C using HI-TECH PIC-C compiler:

#include <pic.h>
#define PROGRAM_MEMORY_SIZE    0x1FFF   //This is 8k
#define RS_232_OUT      RC6
#define RS_232_OUT_IO   TRISC6
#define RS_232_IN_IO    TRISC7

/* This function intitalizes the PIC pins associated with program
validation */
void initialize(void){

   PCFG3 = LOW;
   PCFG2 = HIGH;   //Sets ports E and A to Digital I/O
   PCFG1 = HIGH;

   RS_232_OUT_IO = LOW;       //Output
   RS_232_IN_IO = HIGH;

   RS_232_OUT = HIGH;   //Initialize to high

}

/* The RS 232 serial interface is set up by this function.  The PIC16F87X
  manual contains the information on why bits in this function are set
the
  way they are.  Refer mostly to section 10, starting on pages 105. */
static void setUSARTLines(void){

   /* These first two may have to be adjusted depending on the baud rate,
crystal
      frequency so see PIC16F87X datasheet, pg 107 for details */
   BRGH = 1;           /* high baud rate */
   SPBRG = 129;        /* set the baud rate at 9600 for 20Mhz crystal.
See table 10-5
                          on page 109 of PIC16F87X manual */

   SYNC = 0;   /* asynchronous transmission*/
   SPEN = 1;   /* enable serial port pins */
   CREN = 0;   /* disable reception */
   TXIE = 0;   /* disable tx interrupts */
   RCIE = 0;   /* disable rx interrupts */
   TX9  = 0;   /* 8 bit transmission */
   TXEN = 1;   /* enable the transmitter */

   RS_232_OUT = HIGH;    // A delay is needed (I've probably overkilled
here) to
   delayMs(1000);               // give the COM1 port time to setup or
something i suppose....
   delayMs(1000);
}

/* This function waits until the the TXIF flag sets and then sends the
LSByte followed
   by the MSByte of the program memory word */
static void writeImageByte(void){

   while(!TXIF);       /* Set when TXREG register is empty */
       TXREG = EEDATA;                                 // Send the LSByte
first

   while(!TXIF);       /* Set when TXREG register is empty */
       TXREG = EEDATH;                    //Send MSByte
}

/* This function reads a word from the program memory at address specified
by
  the EEADR and EEADRH registers.  These variables are then incremented
  to reflect the next location in program memory. See PIC manual on
memory,
  Section 4, pg. 41 for specific details on read and write ops. */
static void readImageByte(void){

   RD = HIGH;              // Set the read cycle

   asm("nop");         // Memory not available until third cycle after RD
   asm("nop");         // Several clocks need to pass before operations
can be
   asm("nop");         // performed again (like the if statement below)

   // Increment the address bytes
   if(EEADR == 0xFF){
       EEADR = 0x00;
       EEADRH++;
   }
   else
       EEADR++;
}


/* This function begins the process of sending the program memory out the
  serial line.  Data is sent starting at memory address 0000 hex and
continues
  until the last address of program memory is sent. */
static void writeMemoryImage(void){
   int i;
   EEADR = 0x00;
   EEADRH = 0x00;

   EEPGD = HIGH;  // This provides access to PROGRAM memory

   for(i = 0; i <= PROGRAM_MEMORY_SIZE; i++){
       readImageByte();
       writeImageByte();
   }
   TXEN = 0;  /* Disable the transmitter */
}

/* MAIN*/
void main(void){

   initialize();
   setUSARTLines();
   writeMemoryImage();

   while(1);
}

I'm a rookie programmer and a very rookie PIC guy so this is probably all
wrong but anyways.  Now, I dumped the data to Hyperterminal and captured
in a file, looked at the file with a HEX editor and here's what I got:

83 01 30 00 28 01 12 11 2F .........
compared to the actual:
0183 3000 008A 2804 0183 120A 118A 2FE4   .....

So, the first word is captured (reversed 'cause that's how I coded it) but
after that only the MSBytes are sent out the USART.  I fixed this by
changing "while(!TXIF)" in function writeImageByte() to "while(!TRMT)".
After doing that the output looked like:

83 01 30 8A 04 28 83 01 0D 0A 12 8A 11 E4 2F   .....
compared to original:
0183 3000 008A 2804 0183 120A 118A 2FE4   .....

Now this is what I wanted (sort of, you'll notice no 00's and an unwanted
0D, but I'll get into that in a second). And this leads me to QUESTION 1:
Why didn't TXIF flag work and TRMT work?  The manual says I can use
TXIF.....

Now for the sort of.....Hyperterminal reads 00 as null and it interpretes
0D and 0A as something funny because the PIC DOES transmit the 00's (I
know this for certain)and it DOES NOT transmit the 0Ds.  Hence the actual
code that comes out of the PIC looks like this:

83 01 00 30 8A 00 04 28 83 01 0A 12 8A 11 E4 2F   .....
which is a copy of the original ( with MSBytes and LSBytes reversed as I
programmed it):
0183 3000 008A 2804 0183 120A 118A 2FE4   .....

So this leads me to my second, and finally final question: Why does
hyperterminal put a 0D alongside every 0A and why does it forget 00s?  In
addition to this whenever hyperterminal reads an 0x18 it repeats the next
data byte received?  Why?

I hope someone can help me out there...especially with the USART flag
bits.....

Thanks!
Dave

1999\09\23@173002 by paulb

flavicon
face
David Williams wrote:

> So this leads me to my second, and finally final question: Why does
> hyperterminal put a 0D alongside every 0A and why does it forget 00s?

 00 is ASCII NUL, used in text communications as an idle character and
thus ignored by terminal programs.  0D is Carriage Return and 0A Line
Feed.  If it sees Line Feed without Carriage Return, it assumes UNIX
mode and adds the necessary CR automatically.

 For a text mode terminal, you need a routine in your PIC to break
bytes into halves (Nibbles) and display them as printables (add $30 to
values below $0A, and $40-9 = $37 to values $0A to $0F).

 Or use a terminal with a binary mode.
--
 Cheers,
       Paul B.

1999\09\23@174052 by Robert A. LaBudde

flavicon
face
At 07:28 AM 9/24/99 +1000, Paul wrote:
>David Williams wrote:
>
>> So this leads me to my second, and finally final question: Why does
>> hyperterminal put a 0D alongside every 0A and why does it forget 00s?
>
>  00 is ASCII NUL, used in text communications as an idle character and
>thus ignored by terminal programs.  0D is Carriage Return and 0A Line
>Feed.  If it sees Line Feed without Carriage Return, it assumes UNIX
>mode and adds the necessary CR automatically.
>
>  For a text mode terminal, you need a routine in your PIC to break
>bytes into halves (Nibbles) and display them as printables (add $30 to
>values below $0A, and $40-9 = $37 to values $0A to $0F).
>
>  Or use a terminal with a binary mode.

You can configure this under "settings" for hyperterminal.

================================================================
Robert A. LaBudde, PhD, PAS, Dpl. ACAFS  e-mail: spam_OUTralTakeThisOuTspamlcfltd.com
Least Cost Formulations, Ltd.                   URL: http://lcfltd.com/
824 Timberlake Drive                            Tel: 757-467-0954
Virginia Beach, VA 23464-3239                   Fax: 757-467-2947

"Vere scire est per causae scire"
================================================================

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...