Truncated match.
PICList
Thread
'USART problems....'
1999\09\23@152922
by
David Williams
|
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
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
|
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_OUTralTakeThisOuT
lcfltd.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...