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 support@ccsinfo.com

Help with PIC to PIC RS232 communication-Problem Solved!

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



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

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

Help with PIC to PIC RS232 communication-Problem Solved!
PostPosted: Sat Feb 14, 2015 6:08 pm     Reply with quote

Hello All,

This has been a most frustrating adventure so far, so maybe you can suggest a solution! I have two PICs, one an old 16F877a, and another 12F629 as the receive unit. I am simply trying to send one 8 bit integer from the 877 to the 629 at various speeds such as 1200baud. Now for over a decade we have done this at work with Pic basic pro with two simple commands - that always worked: serout(x) and serin(x) and never had any problems. I can even send tons of serial consecutively separated by a coma.

Now in CCS C, I've been beating my head against the wall all day trying to get this to work to no avail. This should be easy I think, and I feel I am very close!

I know I'm sending the data in some format - I can easily see the number I'm sending on my external LCD connected to the very same pin. SO I KNOW its getting out and is there. But I always get nothing.

On the 877a chip this is the serial related code I have right now:

Code:

#use rs232(baud=1200, xmit=Pin_B4, bits=8, parity=N,stream=SERIAL2)

while (true)  {

s=3;

fprintf(SERIAL,"%u"s);

}



This is of course cut out, the while loop is in main() and the use directive is at the top below the defines for osc, and others.

NOW on the receive end I have this on the 629 chip:

Code:
#use rs232(baud=1200, rcv=Pin_A3, bits=8, parity=N,stream=SERIAL2)

main()   {

while (true) {

speed = fgetc(SERIAL2);

//(Then I light an lamp if the received number is right.)

}
}



Now here is the deal - I normally do NOT use the uart for sending or receiving for robotics because i usually have half a dozen outputs driving different chips, and use normal non uart pins. I DID try the uart pin C6 on the 877a but it did the same thing, only puts out zero at the other end.

OK, so I know this is dumb, but If I'm sending an INT8 variable, how hard can this be?

Appreciate your help guys, your the best...

Chris


Last edited by Arizona Chris on Sun Feb 15, 2015 6:33 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 15, 2015 12:21 am     Reply with quote

You're sending ASCII. Do you know this ? You're sending 0x33 (not 0x03).
diode_blade



Joined: 18 Aug 2014
Posts: 52
Location: Sheffield, South Yorkshire

View user's profile Send private message Send e-mail

Re: Help requested with PIC to PIC RS232 communication.
PostPosted: Sun Feb 15, 2015 2:02 am     Reply with quote

Chris just a point in your rs232 declare you name the stream as "serial2", then when you transmit the data you use the name serial.
Ttelmah



Joined: 11 Mar 2010
Posts: 19244

View user's profile Send private message

PostPosted: Sun Feb 15, 2015 2:37 am     Reply with quote

and then of course, you don't show the device headers (processor, clock etc.), so these could be completely wrong.

I think PCM_programmers comment is the likely main problem. Use putc/getc, not printf to send the raw character.

This is made even more likely, since this is what the serin/serout routines you are used to do.

You've picked up and used the C 'output formatting' routine, which does all the work for you of turning a 'raw' value, into a sequence of ASCII text characters, then missed that if you send ASCII text, you have to write the receiver code to receive ASCII text.....
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

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

chip to chip
PostPosted: Sun Feb 15, 2015 5:45 am     Reply with quote

Yes, that is exactly what it looks like, ASCII. Im sending 33 which is 3 in ascii. When I have to use acsii at work with PBP I have a conversion routine on the the recive end which converts it back to standard decimal numbers. but I should be able to just send plain integers too by formatting the data before it leaves? I tried getc and putc and was not able to get it to work either.

Let me do this, after I get home from work today, let me take a look on the scope at what it sends using putc and see if its still ascii. If I can still not get it to work Ill post the whole code - which is not a very big program since ll Im trying to do is proof of concept.

Chris
Ttelmah



Joined: 11 Mar 2010
Posts: 19244

View user's profile Send private message

PostPosted: Sun Feb 15, 2015 8:57 am     Reply with quote

As already said, post your clock and fuse settings.

If you putc(3), then at the other end getc, you will receive 3. Nothing else needed. However the thing that would stop it being received correctly, would be the clock not being set right on the 629, which will then see the start bit, and receive the wrong pattern, as it clocks the data in at the wrong rate....
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

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

232 Connection made!
PostPosted: Sun Feb 15, 2015 6:32 pm     Reply with quote

I got it all working fine guys. Ttelmah you hit it on the head once again by using putc and getc. I was able to transmitt at various baud rates any byte and from PIC to Pic with no problem.

Going back to what caused my confusion in the first place, the reference Im using as a guide (Embedded C programmin - Seigesmund) specifically indicated NOT to use put and get for serial, but use streams. But all the examples in his book for streams are with ascii text. OH well. LEarn and live.

The data on the Oscope now looks great - when I send a 3, 128 or 255 for example - I can see the actual number on the bits themselves. The other commands would of course add 30 to convert to ascii and send that instead. Ttelmah and all you folks on this forum are my heros again today. ;)

I did actually try to send a word using put and get, but like most serial commands Ive seen it would only send a byte and you would have to break the word into Highbyte and Lowbyte I suppose to send it serially. This is the way I have done it for years at work, so nothing new here!

Chris in Sunny Arizona.

Example code for communication testing from Pic to Pic:

Send side - 16F877a chip:


Code:
//****************************************************************************
//Chris Schur
//(Serial output tests 16F877A)
//Date:  2/14/15
//****************************************************************************

/*Description of this Program:

This version 0 -  will attempt to send a serial output for a speed control for
the motor PWM chip.  It WORKED.  this sends a byte (0-255) from this pic to
another using the putc(x) and x = getc() commands.*/


//I/O Designations ---------------------------------------------------
// RA0: 
// RA1: 
// RA2: 
// RA3: 
// RA4:  (Open Collector output)
// RA5: 

// RB0:  Status LED output
// RB1:  LCD output
// RB2:  Piezzo Speaker
// RB3: 
// RB4:  serial output to M1
// RB5: 
// RB6: 
// RB7: 

// RC0: 
// RC1: 
// RC2: 
// RC3: 
// RC4: 
// RC5: 
// RC6:  UART TX serial output
// RC7:


//--------------------------------------------------------------------

//Include Files:
#include <16F877A.h>  //Normally chip, math, etc.  used is here.

//Directives and Defines:

#fuses NOPROTECT,HS,NOWDT   //xtal is used
#use delay(crystal=10MHz)   //xtal speed
#use fast_io(ALL)          //must define tris below in main when using this

#use rs232(baud=9600, xmit=Pin_B4, bits=8, parity=N)

*********************************************************
//Global Variables:
int8 s;


//****************************************************************************
//-- Main Program
//****************************************************************************

void main(void) {

   // Set TRIS I/O directions, define analog inputs, compartors:
      set_tris_A(0b11111);
      set_tris_B(0b11101000);   //m1 tx is pin 4
      set_tris_C(0b10111111);   //Set Pin_C6 to output for TX
      set_tris_D(0b11111111);
      set_tris_E(111);
     
     
   //Initialize variables and Outputs:  --------------------------------------
   
   output_low(Pin_B0);  //status off
   
   
   //----------------------------------------------------------------

//MAIN LOOP:

while (true)   {

s = 128;

putc(s);

delay_ms(100);

    } 
 
}



And on the Recieve side with a 12f629 chip:


Code:
//****************************************************************************
//Chris Schur
//(Program Name):  12F629 - Serial Reciever
//Date:  2/7/15
//****************************************************************************

/*This version works - can recive a byte (0-255) from another PIC */


//I/O Designations ---------------------------------------------------
// A0 (GPIO0):  OUTPUT MOT-
// A1 (GPIO1):  OUTPUT MOT+
// A2 (GPIO2):  OUTPUT STATUS LED
// A3 (GPIO3):  SERIAL DATA INPUT (can ONLY be input)
// A4 (GPIO4):  XTAL OUTPUT
// A5 (GPIO5):  XTAL INPUT


//--------------------------------------------------------------------

//Include Files:
#include <12F629.h>  //Normally chip, math, etc.  used is here.

//Directives and Defines:
#fuses NOPROTECT,NOMCLR
#use delay(crystal=10MHz)
#use fast_io(A)

#use rs232(baud=9600, rcv=Pin_A3, bits=8, parity=N)


#define LED Pin_A2  //status LED


//*******Global Variables (put before main and Interrupts to make ***********
//available everywhere):*****

int8 speed = 0;      //External number to set speeds
     

//*********** ----- Main Program     ****************************************

void main(void) {

   // Set TRIS I/O directions, define analog inputs, compartors:
        //(analog inputs digital by default) 
     
      set_tris_A(0b101000);

   //Initialize variables and Outputs:  --------------------------------------
      //variables used ONLY within main (local):
     
//---Initial Values---------------------------------------------------
   
speed = 0;
output_low(LED);

//MAIN LOOP: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

while (true)   {


speed = getc();

if (speed == 128)
      output_high(LED);

else
   output_low(LED);


   }  //elihw

} //niam


Ttelmah



Joined: 11 Mar 2010
Posts: 19244

View user's profile Send private message

PostPosted: Mon Feb 16, 2015 1:52 am     Reply with quote

There is no reason you can't use streams.

fputc, and fgetc, are the routines to talk to named streams and send a character.

However, I think the book you are using is orientated to an enhanced C on the PC. Here you would always use 'text streams', or 'binary streams' for such I/O. This type of 'stream' is a 'smart object', allowing you to put a variable in at one end, and have the OS behind the scenes, do all the conversions necessary to transmit this over the transfer medium, and reconstruct it at the other end.
Standard C does not have this type of stream.

For the sending a word, look at a union:
Code:

union {
   int8 bytes[2];
   int16 word;
} val;

val.word is a 16bit variable that can be used wherever you want, while val,bytes[0] and val.bytes[1] are the two separate bytes. Transmit these separately, and write these into an identical union at the other end, and val.word at the receive end, will be the same as val.word at the transmit end.
Efficient code, and likely to be reliable.
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

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

streams
PostPosted: Mon Feb 16, 2015 6:31 am     Reply with quote

Very informative! Yes, the next step now to be able to drive two separate devices (pwm motor controllers for robots) will be to use streams to be able to have two separate outputs or more with different speeds and pin outs. fput, fget are the way to go here for sure. The directive I discovered last night I really love is the "disable_Ints" command, allowing me to send serial to a chip at high speed while its doing timer0 PWM generation and not have the constant barrage of 100uS interrupts distort the data input as to be unreadable. what a great idea!

Chris
Ttelmah



Joined: 11 Mar 2010
Posts: 19244

View user's profile Send private message

PostPosted: Mon Feb 16, 2015 11:54 am     Reply with quote

I have to ask why you are using the Timer interrupt?.
PWM, does not need it. Use the hardware PWM, and let it generate the pulses for you....
temtronic



Joined: 01 Jul 2010
Posts: 9124
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Feb 16, 2015 5:32 pm     Reply with quote

You should look into using 'buffered' serial functions( see ex_sisr.c) also be sure to add 'errors' to the use rs232(...options...) when using the hardware UART. That will keep it from 'hanging'.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19244

View user's profile Send private message

PostPosted: Tue Feb 17, 2015 12:54 am     Reply with quote

Unfortunately, he is using software UARTs... :(
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

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

Pic to Pic
PostPosted: Tue Feb 17, 2015 9:20 am     Reply with quote

Yes, I'm using a 12F629 chip - the ultimate cheapie PIC. No PWM inside, but I'm trying to milk every drop of functionality out of this device. Its been great fun, and I've learned more on how to use all the timers than any time in my career! Ill be posting the final project files soon, a 10 speed robot motor driver chip with serial input. Not bad for an 80 cent chip. ;) You've got to love this stuff, ay?

Chris
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