|
|
View previous topic :: View next topic |
Author |
Message |
jjacob
Joined: 08 Mar 2008 Posts: 54 Location: PORTUGAL (PORTO)
|
RS232 read problems ... |
Posted: Fri Mar 21, 2008 10:22 am |
|
|
I'm trying to read/write from serial port.
My program have to wait for an incoming byte from serial port to the PIC.
If i do like this :
#use rs232(stream=L1, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
char e;
while(!kbhit(L1))
;
e=fgetc(L1);
fputc(e,L1);
the PIC waits for the incoming byte ... for ever ...
But, if i do like this :
#use rs232(stream=L1, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
char e='A';
fputc(e,L1);
while(!kbhit(L1))
;
fgetc(L1);
The program writes on the RS232-L1, but don't wait for the next incoming byte :(
'Ignores' 'fgetc(L1)' and goes all the way down running the program...
I've read the manual ... and read again the manual ... and read ...
but i can't understant why the PIC don't wait for the incoming byte.
This pins are hardware ... i really don't understand the manual explanation about
software RS232 and hardware RS232 in the 'KBHIT()' topic.
Can anybody help me ?
Thank you ...
Jacob |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 21, 2008 11:24 am |
|
|
Get rid of all that code and make a very simple test program.
The following program receives characters that you type into
a terminal window on your PC and it sends them back.
Code: | #include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
char c;
while(1)
{
c = getc(); // Get char from PC
putc(c); // Send it back to PC
}
} |
If you have more questions, post the following:
1. The part number of your PIC.
2. A description of your hardware, especially the RS-232 connections.
Are you using a board that you bought ? If so, post the company
and the name or part number of the board. |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 21, 2008 11:30 am |
|
|
Before going any further, one obvious question. What chip is this?. Not many have the hardware serial on C4/C5.
Best Wishes |
|
|
Matro Guest
|
|
Posted: Fri Mar 21, 2008 11:43 am |
|
|
Please post a more complete program with fuses, preprocessor directives and functions...
The best is a program that reproduces the bug and that can be directly copied-pasted and compiled.
Matro |
|
|
jjacob
Joined: 08 Mar 2008 Posts: 54 Location: PORTUGAL (PORTO)
|
|
Posted: Fri Mar 21, 2008 12:16 pm |
|
|
OK.
I'm using a PIC16F688, as hardware pins for serial communication.
I've already tested the basic 'echo' with my hardware ... it worked.
I'm using an hardware that i've made... but it works ...
So, if the hardware works... the problem is software ...
The project, is a RS485 sensor network using MAX487, this is why i've activated the 'ENABLE' in the definition of '#use rs232'.
I have a MASTER and ... N SLAVES (N<127). The MASTER as two interfaces.
The SLAVE as only one interface.
MASTER is connect to NIVEL 1 and NIVEL3.
The code that i shall show you is for the MASTER.
#use rs232(stream=NIVEL1, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
#use rs232(stream=NIVEL3, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A1, xmit=PIN_C1, rcv=PIN_C2, BRGH1OK, ERRORS, RESTART_WDT)
Each SLAVE as an address and by default they are listening ( fgetc() ).
Step 1. The MASTER, starts sending addresses to the bus start at address 1.
Step 2. The MASTER waits for the SLAVE with the address that it was send to answer.
Step 3. If the SLAVE sends back to the MASTER the right address the PIC light on a Green Led, if the address is not equal than a Red Led is on. It Delays for 1.5s.
My problem is in Step 2, because my PIC don't wait for the SLAVE to answer and goes to Step 3 witout wait for Step 2.
And i can garantee you that the SLAVES don't answer ... because i took them out of the network !!!! So no SLAVES ... and the MASTER still passes Step 2.
Like i've told you, i've already read the manual but can't understand the explanation about KBHIT(), and why if a change my code it works in a way and the other don't.
Code don't work :
char e='A';
fputc(e,L1);
while(!kbhit(L1))
;
e=fgetc(L1);
Code work :
while(!kbhit(L1))
;
e=fgetc(L1);
fputc(e,L1);
Why if i have 'fgetc()' first works and 'fgetc()' after 'fputc()' don't work ?
Is because of the buffer ? How can i clean it ? ??
Master :
Code: |
#include <16F688.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOMCLR,NOWDT,NOPROTECT
#use delay(clock=10000000)
#use rs232(stream=NIVEL1, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
#use rs232(stream=NIVEL3, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A1, xmit=PIN_C1, rcv=PIN_C2, BRGH1OK, ERRORS, RESTART_WDT)
void setup_pic(){
// 0-output 1-input
set_tris_a(0x00);
set_tris_c(0x20);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
}
void envia_21 (char e){
fputc(e,NIVEL1);
}
char recebe_12 (){
while(!kbhit(NIVEL1))
;
return fgetc(NIVEL1);
}
void envia_23 (char e){
fputc(e,NIVEL3);
}
char recebe_32 (){
while(!kbhit(NIVEL3))
;
return fgetc(NIVEL3);
}
void main() {
char c,r;
int f;
setup_pic();
output_high(VERMELHO);
output_high(VERDE);
delay_ms(1500);
output_low(VERMELHO);
output_low(VERDE);
c=65;
r=c;
while(TRUE) {
for(c=65;c<75;c++){
envia_21 (c);
r=recebe_12();
envia_23(r);
if(r==c){
output_high(VERDE);
output_low(VERMELHO);
fprintf(NIVEL3, "\r\n O sensor com ID : %c respondeu ...\r\n",r);
}else {
output_high(VERMELHO);
output_low(VERDE);
}
delay_ms(1000);
}
}
} |
NOTE : PIC address, for the moment is changed in the code ...
Slave :
Code: | #include <16F688.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOMCLR,HS,NOWDT,NOPROTECT
#use delay(clock=10000000)
// O sensor/PIC NIVEL1, responde ao NIVEL2.
// O NIVEL2 gere o troço.
// O NIVEL3 gere o gestor de troço.
#use rs232(stream=NIVEL2, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
void setup_pic(){
// 0-output 1-input
set_tris_a(0x00);
set_tris_c(0x2F);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
}
void envia (char e){
fputc(e,NIVEL2);
}
char recebe (){
while(!kbhit(NIVEL2))
;
return fgetc(NIVEL2);
}
void main() {
unsigned int8 pic_id=72;
char c, f;
setup_pic();
while(TRUE) {
c=recebe();
if(c==pic_id){
output_high(VERDE);
output_low(VERMELHO);
}else {
output_high(VERMELHO);
output_low(VERDE);
}
}
//printf("Estado do LED");
}
|
Thank you in advance.
Jacob |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Mar 21, 2008 12:58 pm |
|
|
Is it possible you are recieving the data that you sent out? |
|
|
jjacob
Joined: 08 Mar 2008 Posts: 54 Location: PORTUGAL (PORTO)
|
|
Posted: Fri Mar 21, 2008 1:10 pm |
|
|
That's a very nice question
But i don't think so ... or perhaps my fgetc() is catching the outgoing fputc()?? Is that what you are asking?
I've put delays between the two ... and then i put kbhit() ...
My sensor network is common RS485 with MAX487... i connect PIN_A0 to the side of the SLAVEs ... and so i read ... the compiler does the rest ...
I've also put LEDs in the SLAVES. If is the SLAVE address then Green else Red. When the SLAVES are there, the right LEDs gets on.
So i think, that only after the char is send, the char is received ...
But i'm quite new with this compiler ... that's why i'm asking for HELP ...
Thank you for your attention
Jacob |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 21, 2008 3:20 pm |
|
|
To me, you've got too much code in there for a test program.
The master and slave should only have a few lines in main().
By a few lines, I mean 2 lines, or 4 lines, maybe 10 max.
If you strip it down, you can probably find the problem. |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 21, 2008 3:26 pm |
|
|
Delays, won't stop the UART from catching the sent data. The _hardware_ stores a byte received.
If you have got RS485 connections, unless you disable the receive on the transmitting device, when you send, you _will_ see the characters you send.
How is the RS485 bus biased?.
Unless it is biased to the off state by the terminating resistors, or you use RS485 receivers that are warranted to see an unconnected bus as 'idle', you _will_ see data on an idle bus...
I suspect you may well have problems like this with the RS485 connections. This would explain fgetc, never waiting.
Separately, you need to make your protocol significantly 'different', if it is to have any chance of working in the real world. There needs to be a way of distinguishing the address bytes from data bytes, or there wll be no way for the bus to recover if the processors get out of sync. Either a time gap before the address, or a 'marker' (SOT/EOT), that is not used in the normal data.
Best Wishes |
|
|
jjacob
Joined: 08 Mar 2008 Posts: 54 Location: PORTUGAL (PORTO)
|
|
Posted: Fri Mar 21, 2008 5:20 pm |
|
|
Hello.
I've made some tests and made my code shorter ...
I have only ONE PIC16F688 with a MAX487. Now i don't have a network.
Pin ~RE of MAX487 is connected to GND and Pin DE is connected to PIN_A0 of the PIC.
Here is the code :
Code: | #include <16F688.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOMCLR,NOWDT,NOPROTECT
#use delay(clock=10000000)
#use rs232(stream=L1, baud=9600, BITS=8, PARITY=N, STOP=1, ENABLE=PIN_A0, xmit=PIN_C4, rcv=PIN_C5, BRGH1OK, ERRORS, RESTART_WDT)
void setup_pic(){
// 0-output 1-input
set_tris_a(0x00);
set_tris_c(0x20);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
}
void main() {
char c;
setup_pic();
c=65;
while(TRUE) {
fputc(c,L1);
while(!kbhit(L1))
;
c=fgetc(L1);
}
} |
I have Hyperterminal connected to the PIC (using MAX232) and result of this code :
Character 'A' appears on Hyperterminal (ascii code is 65)... and it prints 'A'
without stop ... once again it doesn't stop at kbhit().
If i change the code :
Code: | while(TRUE) {
while(!kbhit(L1))
;
c=fgetc(L1);
fputc(c,L1);
}
|
It works... ?????? But i need to send first a byte and then wait for an answer...
My big question is : How do i make my program wait for a character that comes from
a serial port? I've tried to understand the manual about the 'kbhit()' explanation
but i couldn't understand. Can anybody explain ??
Thank for your patient ...
Jacob |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
|
jjacob
Joined: 08 Mar 2008 Posts: 54 Location: PORTUGAL (PORTO)
|
|
|
|
|
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
|