CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RS232 read problems ...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 11:24 am     Reply with quote

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







PostPosted: Fri Mar 21, 2008 11:30 am     Reply with quote

Before going any further, one obvious question. What chip is this?. Not many have the hardware serial on C4/C5.

Best Wishes
Matro
Guest







PostPosted: Fri Mar 21, 2008 11:43 am     Reply with quote

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)

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 12:16 pm     Reply with quote

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 ... Smile

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

View user's profile Send private message Visit poster's website

PostPosted: Fri Mar 21, 2008 12:58 pm     Reply with quote

Is it possible you are recieving the data that you sent out?
jjacob



Joined: 08 Mar 2008
Posts: 54
Location: PORTUGAL (PORTO)

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 1:10 pm     Reply with quote

That's a very nice question Smile

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

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 3:20 pm     Reply with quote

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







PostPosted: Fri Mar 21, 2008 3:26 pm     Reply with quote

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)

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 5:20 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 9:59 pm     Reply with quote

Quote:

This pins are hardware ... i really don't understand the manual explanation about
software RS232 and hardware RS232 in the 'KBHIT()' topic.


http://www.ccsinfo.com/forum/viewtopic.php?t=23440&highlight=kbhit
http://www.ccsinfo.com/forum/viewtopic.php?t=27156&highlight=kbhit
http://www.ccsinfo.com/forum/viewtopic.php?t=27826&highlight=kbhit

Humberto
jjacob



Joined: 08 Mar 2008
Posts: 54
Location: PORTUGAL (PORTO)

View user's profile Send private message

PostPosted: Sat Mar 22, 2008 8:58 am     Reply with quote

Thank you ...

Is working now Smile Smile
It was little detail in the understanding of KBHIT()!!!
After read http://www.ccsinfo.com/forum/viewtopic.php?t=23440&highlight=kbhit
(Posted: Thu Jun 30, 2005 6:27 pm)

i change my code and is working !!

Best regards
Jacob
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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