|
|
View previous topic :: View next topic |
Author |
Message |
jameszum
Joined: 31 Jan 2012 Posts: 14
|
RS232 problem |
Posted: Wed Sep 19, 2012 3:25 pm |
|
|
I am using 2 16F877A one each on a separate board, and i am using soft rs232 communication to pass information between the boards. The "Generator" boards sends a single byte in this case a 0x52 (R) to the "Controller" board, and the "Controller" board responds with a 0x58 (X).
I have No problem sending the byte from the "Generator" boards to the "Controller" Board but when the "Controller" board sends it a response the generator board receives garbage.
By garbage I mean the following
the generator board sends
sending 52
"hex data"
7365 6E64 696E 6720 3532 0A
and the generator receives the following
"return information"
return 00 NOTE some times there are 3 characters here
"hex data"
7265 7475 726E 2030 300A
"last printed data"
got a 00
"hex Data"
676F 7420 6120 3030 0A
Just monitoring the Receive line for unit 1
I get what is expected
X
"hex Data"
58
The problem seems to be with the receiver on the Generator board
note the stream= test is for communicating with a monitor program
and when removed the problem still remains.
I have gone through the forum but have not found any help with this problem.
Code: | // Generator
#include <16F877A.h>
#fuses NOWDT
#fuses HS
#fuses NOPUT
#fuses NOPROTECT
#fuses NOBROWNOUT
#fuses NOLVP
#fuses NOCPD
#fuses NOWRT
#use delay(clock = 10000000)
#use standard_io(all)
//#define rs232 out PIN_B0 // rs232 out
//#define rs232 in PIN_B1 // rs232 in
#define verify_sw PIN_B3 // input
#define LDP PIN_B4 // output
#define RDP PIN_B5 // output
//------------------------------------------------
#define RESET_in PIN_C5 // input
//------------------------------------------------
// when receiving wait 10 MS if no data them an error
#use rs232(baud=9600,FORCE_SW, ERRORS, XMIT = pin_C0, rcv = pin_C3,stream = test)
#use rs232(baud=9600,FORCE_SW, ERRORS, XMIT = pin_B0, rcv = pin_B1,stream = Cont)
int I1,J1,J2,J3;
void SSend_Data(char data); // write a byte of data
char SRead_Data(void); // read a byte of data
void S_RESET(void); // tell all ro erase there stored data
//****************** start of main *******************************************
void main()
{
PORT_B_PULLUPS(true) ;// set app pullups on b high
output_low(LDP);
output_low(RDP);
while(1) // Loop Here for ever
{
if (input(RESET_in) == 0)// check the switch
{
while (!input(RESET_in)); // wait until a one
S_RESET(); //
}
delay_ms(10);
}//end of while(1)
//---------------------------------------------------------------------
}//end of main()
//************************************************************************
void S_RESET()
{
SSend_data(0x52); // send the "R" command
I1 = SRead_Data();// should be an X
fprintf(test,"got a %x\n",I1);
// clear the EEPROM in the chip
}
//-----------------------------------------------------------------------------
void SSend_data(char data) // write a byte of data
{
fputc(data,Cont); // send over rs232
fprintf(test,"sending %x\n",data); // send over rs232
}
//-----------------------------------------------------------------------------
char SRead_Data(void)
{
// kbit has gone low we have seen the start bit
while (!kbhit())//wait for a return
J1 = fgetc(Cont);// get a byte of data
fprintf(test,"return %x\n" J1,);
return J1;
}
|
Code: | // Controller
#include <16F877A.h>
#fuses NOWDT
#fuses HS
#fuses NOPUT
#fuses NOPROTECT
#fuses NOBROWNOUT
#fuses NOLVP
#fuses NOCPD
#fuses NOWRT
#use delay(clock = 10000000)
#use standard_io(all)
//#define rs232 in PIN_B0 // rs232 in
//#define rs232 out PIN_B1 // rs232 out
#define LDP PIN_B4 // output
#define RDP PIN_B5 // output
#use rs232(baud=9600,FORCE_SW ,XMIT = pin_B1,rcv = pin_B0,stream = main)
int input_data;
//-----------------------------------------------------------------------
void SSend_Data(char data); // write a byte of data
int SRead_Data(); // read a byte of data
//-----------------------------------------------------------------------
void S_RESET(void); // tell all to erase the EEPROM Memory
//********************************************************************
void main()
{
PORT_B_PULLUPS(true) ;// set app pullups on b high
//**********************************************************************
output_low(LDP );
output_low(RDP);
//************************************************************
while(1) // Loop Here for ever
{
input_data = SRead_Data();
if (input_data == 0x52) S_RESET();// no return
delay_us(10);
}//end of while(1)
//---------------------------------------------------------------------
}//end of main()
// end of MAIN Program
void S_RESET(void)
{
// on we saw the 0x52 so lets send the conformation
SSend_data(0x58);// send the X for ok
delay_ms(1);
}// end if S_RESET
//************************************************************************
//
void SSend_data(char data) // write a byte of data
{
putc(data);
delay_ms(5);
}
//------------------------------------------------------------------
int SRead_data()// read a byte of data
{
int result;
while (!kbhit());// wait for a bit
result = getc();
return result;
}
|
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Sep 19, 2012 7:25 pm |
|
|
two softies eh ??
Code: |
#use rs232(baud=9600,FORCE_SW, ERRORS, XMIT = pin_C0, rcv = pin_C3,stream = test)
#use rs232(baud=9600,FORCE_SW, ERRORS, XMIT = pin_B0, rcv = pin_B1,stream = Cont)
|
but in
s_readdata ....
you call kbhit () without a stream argument .
so i have to ask"
which stream does kbhit() look for received data in ???
your .LST file may answer that
--------------
i must say respectfully that two soft streams of RS232 in ONE pic is
actually TWO streams more than i would ever use, unless i was eager to sort out the exact kind of trouble you find yourself in.
have you noticed what the 18F46K22 can do for you ??
even at Q=1, they actually cost LESS than the PIC you started with and do so much more, AND with TWO nice hardware uarts ??
( the ONLY kind that is worth using IMHO)[/code] |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Sep 20, 2012 12:10 am |
|
|
I totally agree with asmboy. Because of all the limitations a software UART is a last resort solution and you should be well aware of it's limitations. And then, there is a hardware UART in your chip and you don't even use it? Well, you created your own problem. Fix your hardware design.
Then there is this part of code in the Generator: Code: | char SRead_Data(void)
{
// kbit has gone low we have seen the start bit
while (!kbhit())//wait for a return
J1 = fgetc(Cont);// get a byte of data
| There is no ';' at the end of the while line, so for easier reading you have to format it like: Code: | char SRead_Data(void)
{
// kbit has gone low we have seen the start bit
while (!kbhit())//wait for a return
{
J1 = fgetc(Cont);// get a byte of data
} | And then I have no clue as to what you are trying to do here. As long as there is no kbhit, you are reading data? Makes no sense and I guess that just by coincidence it is doing what you meant it to do: Code: | char SRead_Data(void)
{
J1 = fgetc(Cont);// get a byte of data |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Sep 20, 2012 5:07 am |
|
|
I have to 'second' what asmboy says....upgrade to the 18f46k22s ! I now have a drawer full of 877s and 4550s collecting dust, the newer PIC is the way to go. Having 2 hardare UARTS is a treat getting rid of a lot of timing 'issues', code is smaller, tighter and WORKS. I dumped the 4550s since I get a USB-TTL module for $4(qty 1), again gets rid of a LOT of 'issues'.
SOME newer technology is great, this from a guy with 20 year old 877s.
hth
jay |
|
|
jameszum
Joined: 31 Jan 2012 Posts: 14
|
|
Posted: Thu Sep 20, 2012 10:31 am |
|
|
Good Morning
First, new processor for this project is not going to happen.
Project was given to me on Sept 4 and has to be completed by Sept 27.
The project has 8 boards and I had the micros so I went with them.
However I will keep it in mind for future projects.
Second the missing semicolons,
the code was copied from a larger procedure and it got dropped, sorry about that.
Code: |
char SRead_Data(void)
{
// kbit has gone low we have seen the start bit
while (!kbhit())//wait for a return missing semi here
J1 = fgetc(Cont);// get a byte of data
fprintf(test,"return %x\n" J1,);
return J1;
}
|
Third the soft RS232 I found that putting a delay_ms(20) after each transmit on both units solved the problem.
Code: |
void SSend_data(char data) // write a byte of data
{
//#use rs232(baud=9600,FORCE_SW, ERRORS, XMIT = PIN_B1, RCV = PIN_B0,stream = Cont)
delay_ms(20);
disable_interrupts(INT_TIMER0);
fputc(data,Cont); // send over rs232
fprintf(test,"sending %x \n",data); // send over rs232
enable_interrupts(INT_TIMER0);
// delay_ms(20);
}
|
|
|
|
|
|
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
|