|
|
View previous topic :: View next topic |
Author |
Message |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
RS232 async 16F887 vs 18f4520 |
Posted: Tue Aug 04, 2009 6:02 pm |
|
|
Using combined PCM PCH ver 4.085
( a search for PCH serial problem returns 1300+ hits - )
RS232 converting to 18f4520 is way off of speed.
The 16f887 program below works perfectly.
BUT
the 18f4520 converted versions only produces a short burst of VERY hi baud rate data - that evaluates to a single 0xfd - 0xFF when received at 38400.
I have set the TRIS in C and the SPEN bit per the data sheet but something fundamental is still wrong and I am just not seeing it.
Below WORKS fine
Code: |
#include <16f887.h>
// 18f #include <18f4520.h>
#include <stdlib.h>
#FUSES NOPROTECT,NOMCLR,INTRC_IO,NOWDT,NODEBUG,NOLVP,NOIESO,
#fuses NOFCMEN,PUT,NOWRT,NOFCMEN,NOBROWNOUT,
// above old '16f887 fuses new 18f fuses added below
// 18f #fuses CCP2C1,NOPBADEN,NOLPT1OSC,
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use delay( clock=8000000,INTERNAL ) // clock 8 mhz int
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS )
int NumberOfArguments;
char ArgumentString[12]; // used to be 10
void minorVER(void){
printf(__DATE__); printf(__TIME__); printf( " Ver FX\r"); //
}
void greetmsg(void){ printf ( "ECIS MH2 \r" ); //output message
}
void baddie(void){ printf( "-\r"); } // bad arg problem
void goodie(){ printf( "!\r"); } // bad arg problem
//***********************************
void InitHDW ( void ) {
//***********************************
setup_oscillator ( OSC_8MHZ );
output_a (0); output_b (0); output_c (0); output_d (0); output_e (0xFF);
set_tris_a (0); // all output
set_tris_b (0); // all output
set_tris_c (3); // 00000011 low = C0,C1 are inputs
set_tris_d (0xFF); // all input
set_tris_E ( 0xE9 ); // 1110 1001 with Parallel Slave Port mode off
setup_adc_ports( NO_ANALOGS );
setup_adc( ADC_OFF );
setup_timer_0( RTCC_DIV_128 ); // set for rollovers 10 ms 8 mhz
}
void PodType ( void ) {
printf ( "podis3\r" ); // send back pod well count
}
int ParseCommand ( char NewChar ) {
int Command; int i;
static char ReceiveBuffer[10]; // MAX CMD LEN =10 actuall 1 + 6+1
static int BufferIndex = 0;
NumberOfArguments = 0;
ReceiveBuffer[BufferIndex++] = NewChar;
// Error if command is too long
if ( BufferIndex == 11 ) {
BufferIndex = 0;
return ( 0 ); // BAD value we overflowed
}
// CR= command is complete
// CR vs LF so check for them both
// ignore 0 length commands because probably just a CR/LF combination
if ( (NewChar == '\r') || (NewChar == '\n') ) {
// Ignore it
if ( BufferIndex == 1 ) {
BufferIndex = 0;
Return 0;
}
Command = ReceiveBuffer[0] ;
ReceiveBuffer[BufferIndex] = 0;
if ( BufferIndex == 2 ) {
NumberOfArguments = 0;
} else {
for (i=0;i<11;i++){
ArgumentString[i] = ReceiveBuffer[i+1];
}
NumberOfArguments = 1;
}
BufferIndex = 0;
return Command;
}
// If here then still just building the command
return 0;
}
void ProcessCommand ( int Command ) {
switch ( Command ) {
case '?': PodType(); break; // P!
case '-': minorVer(); break; //P!
case '*': greetmsg(); break; //P!
default : baddie();
}
}
//
//******
main() {
//******
char NewChar;
int Command;
InitHDW();
greetmsg();
while (1) {
while ( kbhit() ) { // chgd from IF to clean QUE
// There is a character so read it
NewChar = getc();
// Add the new character to the buffered command
Command = ParseCommand ( NewChar );
switch ( Command ) {
case 0: // A complete command has not yet been received - do nothing
break;
default:
// A complete (but not necessarily valid) command received - process it
ProcessCommand ( Command );
break;
}
}
}
}
|
Below rets ONE obviously WAY overbaud burst as seen on scope
Code: |
#include <18f4520.h>
#include <stdlib.h>
#FUSES NOPROTECT,NOMCLR,INTRC_IO,NOWDT,NODEBUG,NOLVP,NOIESO,
#fuses NOFCMEN,PUT,NOWRT,NOFCMEN,NOBROWNOUT,
// above old '16f887 fuses new 18f fuses added below
#fuses CCP2C1,NOPBADEN,NOLPT1OSC,noxinst,
#use delay( clock=8000000,INTERNAL ) // clock 8 mhz int
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS )
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#bit spen = 0xFAB.7
int NumberOfArguments;
char ArgumentString[12]; // used to be 10
void minorVER(void){
printf(__DATE__); printf(__TIME__); printf( " Ver FX\r"); //
}
void greetmsg(void){ printf ( "ECIS MH2 \r" ); //output message
}
void baddie(void){ printf( "-\r"); } // bad arg problem
void goodie(){ printf( "!\r"); } // bad arg problem
//***********************************
void InitHDW ( void ) {
//***********************************
setup_oscillator ( OSC_8MHZ |OSC_INTRC|OSC_PLL_OFF );
output_a (0); output_b (0); output_c (0); output_d (0); output_e (0xFF);
set_tris_a (0); // all output
set_tris_b (0); // all output
// 18f TRIS bit 6,7 chgs
set_tris_c (0b11000011); // 00000011 low = C0,C1 are inputs
set_tris_d (0xFF); // all input
set_tris_E ( 0xE9 ); // 1110 1001 with Parallel Slave Port mode off
spen=1; // 18f SPEN change
setup_adc_ports( NO_ANALOGS );
setup_adc( ADC_OFF );
setup_timer_0( RTCC_DIV_128 ); // set for rollovers 10 ms 8 mhz
}
void PodType ( void ) {
printf ( "podis3\r" ); // send back pod well count
}
int ParseCommand ( char NewChar ) {
int Command; int i;
static char ReceiveBuffer[10]; // MAX CMD LEN =10 actuall 1 + 6+1
static int BufferIndex = 0;
NumberOfArguments = 0;
ReceiveBuffer[BufferIndex++] = NewChar;
// Error if command is too long
if ( BufferIndex == 11 ) {
BufferIndex = 0;
return ( 0 ); // BAD value we overflowed
}
// CR= command is complete CR vs LF so check for them both
// ignore 0 length commands because probably just a CR/LF combination
if ( (NewChar == '\r') || (NewChar == '\n') ) { // Ignore it
if ( BufferIndex == 1 ) {
BufferIndex = 0;
Return 0;
}
Command = ReceiveBuffer[0] ;
ReceiveBuffer[BufferIndex] = 0;
if ( BufferIndex == 2 ) {
NumberOfArguments = 0;
} else {
for (i=0;i<11;i++){
ArgumentString[i] = ReceiveBuffer[i+1];
}
NumberOfArguments = 1;
}
BufferIndex = 0;
return Command;
} // If here then still just building the command
return 0;
}
void ProcessCommand ( int Command ) {
switch ( Command ) {
case '?': PodType(); break; // P!
case '-': minorVer(); break; //P!
case '*': greetmsg(); break; //P!
default : baddie();
}
}
//
//******
main() {
//******
char NewChar;
int Command;
InitHDW();
greetmsg();
while (1) {
while ( kbhit() ) { // chgd from IF to clean QUE
// There is a character so read it
NewChar = getc();
// Add the new character to the buffered command
Command = ParseCommand ( NewChar );
switch ( Command ) {
case 0: // A complete command has not yet been received - do nothing
break;
default:
// A complete (but not necessarily valid) command received - process it
ProcessCommand ( Command );
break;
}
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 04, 2009 6:37 pm |
|
|
Clues:
What additional feature does Timer0 have in the 18F4520, that it doesn't
have in the 16F887 ? What is the compiler's default setting for that
feature in the 18F4520 ? How can you configure Timer0 to be compatible
with the 16F887 ? What is to be found in the 18F4520.h file in the Timer0
section ? |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
excellent asnwer |
Posted: Tue Aug 04, 2009 6:54 pm |
|
|
working on it
BUT the first thing i tried was using the 18f4620 instead
no other change except the #device line
and bang it WORKS for the F8620
SO i am
decoding the default state of timer0 from the .H file is proving more of a challenge than i thought
16 bit ? WDT on ? even with the fuse set NO ?
no other obvious interaction with EUASART system / master clock timing but back to the spec sheet i go |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Aug 04, 2009 7:15 pm |
|
|
holy heck !!!
i thought the #fuse that i set
took care of the whole issue
meaning i did not have to exlicitly disable the darned 'feature' thingie !!!
since i never use that bit of kit
i always assumed the the NOWDT fuse handled the problem
got it now
BUT how come i DON'T have to disable the same item on the 18f4620 ?????? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 04, 2009 7:42 pm |
|
|
Maybe I misunderstood your problem. I was literally just about to leave
the office for the day. I saw a problem in the configuration of Timer0
and I jumped on it. (the 18F part defaults to a 16-bit Timer. The 16F
is 8-bit only). |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Aug 04, 2009 7:51 pm |
|
|
naw -
the 4620 worked with NO other changes except
TRIS_C bits 6,7 and SPEN - did not matter if i was using deflt 16 bit or 8 bit timer0
then for the 4520 i added the RTCC_8bit to my timer0 setup but still no fix
//** 4520
problem finally went away when i
added setuP_wdt( no_wdt); EARLY in my INIT function
even tho
i had done the NO_WDT fuse for the same part
very very weird
any ideas ?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 04, 2009 7:53 pm |
|
|
Post your compiler version. It's given at the top of the .LST file.
It will be like this: 4.096 (or whatever it is). |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Aug 04, 2009 7:56 pm |
|
|
i did - and always do
it was the FIRST line of my original post
and still is 4.085 ;-)) |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
further amplifying |
Posted: Tue Aug 04, 2009 8:15 pm |
|
|
for sure - the magic change was disabling the WDT - then chip worked
- serial came on all fine - no other change did bupkis
other notes - i did NOT assert WDT32768 -
nor BORV20 - yet there it is
from the .LST for the 4520
Word 1: 0800 NOIESO NOFCMEN INTRC_IO
Word 2: 1E18 NOBROWNOUT NOWDT BORV20 PUT WDT32768
Word 3: 0100 NOPBADEN CCP2C1 NOLPT1OSC NOMCLR RESERVED
Word 4: 0081 STVREN NODEBUG NOLVP NOXINST RESERVED
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: E00F NOWRT NOWRTD NOWRTC NOWRTB
Word 7: 400F NOEBTR NOEBTRB
word 2 does NOT look exactly right to me but i could be wrong
i think NOwdt is asserted properly but the BORV20 and WDT32768 are not my doing
anybody make better sense of the fuse mess ?
- IF WDTEN is actually 0
then the doc says that SWDTEN now controls WDT operation
SWDTEN is in WDTCON and is the ONLY bit in the register
and sez IT defaults to 0 on power up per doc
am i misreading it ?
is it me - or the compiler ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 04, 2009 8:29 pm |
|
|
If you have a baud rate problem, my advice is to strip it down and
see if you still have the problem:
Code: | #include <18f4520.h>
#FUSES NOPROTECT,NOMCLR,INTRC_IO,NOWDT,NODEBUG,NOLVP,NOIESO,
#fuses NOFCMEN,PUT,NOWRT,NOFCMEN,NOBROWNOUT,
#fuses CCP2C1,NOPBADEN,NOLPT1OSC,noxinst
#use delay( clock=8000000,INTERNAL) // clock 8 mhz int
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS )
//====================================
void main()
{
printf("Hello World\n\r");
while(1);
} |
If you do, then change the main() code to this and look at the signal
with an oscilloscope:
Code: | void main()
{
while(1)
{
putc(0x55);
}
} |
|
|
|
|
|
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
|