![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
ivrj
Joined: 17 Mar 2009 Posts: 7
|
CCS RS485.c Lib Doesn't work. Proteus + source. |
Posted: Fri Nov 20, 2009 1:16 pm |
|
|
Hello! I tried to use the library of ccs to make communication between two PICs, but did not work.
I need the message to go in both directions, to do a sensor network.
I am enclosing the file used in this test, including the proteus circuit.
appreciate any help!
http://www.mediafire.com/file/zdnozazmmnh/485.rar |
|
![](templates/subSilver/images/spacer.gif) |
ivrj
Joined: 17 Mar 2009 Posts: 7
|
|
Posted: Wed Nov 25, 2009 8:41 am |
|
|
Anybody know what I did wrong? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 25, 2009 1:53 pm |
|
|
There are probably several reasons why no one is helping you.
1. You didn't give a direct download link for your file. It goes to an
HTML page. Who knows what is on that page ? It could be
something bad.
2. Most people don't want to look at a large amount of code.
3. Most people don't have Proteus. They can't view a Proteus schematic file. |
|
![](templates/subSilver/images/spacer.gif) |
ivrj
Joined: 17 Mar 2009 Posts: 7
|
|
Posted: Thu Nov 26, 2009 5:10 am |
|
|
PCM programmer wrote: | There are probably several reasons why no one is helping you.
1. You didn't give a direct download link for your file. It goes to an
HTML page. Who knows what is on that page ? It could be
something bad.
2. Most people don't want to look at a large amount of code.
3. Most people don't have Proteus. They can't view a Proteus schematic file. |
Sorry, but my intention was to make it easy to debug my code!
There is the code, and the schematic:
[img=http://img20.imageshack.us/img20/2093/rs485.jpg]
Code: |
/////////////////////////////////////////////////////////////////////////
//// EX_RS485_CHAT.C ////
//// ////
//// Converts RS485 data and puts it onto RS232 data line. ////
//// ////
//// Jumpers: ////
//// PCM,PCH pin B2 to RS232 RX, pin B1 to RS232 TX ////
//// ////
//// ////
//// The following conditional compilation lines are used to ////
//// include a valid device for each compiler. Change the device, ////
//// clock and RS232 pins for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2005 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#include <18f4550.h>
#device *=16
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, ENABLE=PIN_B0)
#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT TRUE
int8 OUR_RS485_ID = 0;
#define RS485_ID OUR_RS485_ID
#include <rs485.c>
#include <stdlib.h>
#define RS485_RX_PIN PIN_C6 // Data receive pin
#define RS485_TX_PIN PIN_C7 // Data transmit pin
#define RS485_ENABLE_PIN PIN_B0 // Controls DE pin. RX low, TX high.
#define RS485_RX_ENABLE PIN_B1 // Controls RE pin. Should keep low.
int8 in_char = 0;
int8 next_in = 0;
int8 next_out = 0;
int8 msg[64];
#INT_TIMER1
void timer1_isr()
{
int8 i;
printf("timer");
if(rs485_get_message(msg, FALSE))
{
printf("\n\r mensagem recebida %d: ", msg[0]);
for(i=0; i < msg[1]; ++i)
putc(msg[i+2]);
printf("\n\r");
}
}
void RS485send(char* s, int8 id)
{
int8 size;
for(size=0; s[size]!='\0'; ++size);
printf("Wait for bus");
rs485_wait_for_bus(FALSE);
printf("bus released, sending message...");
while(!rs485_send_message(id, size, s))
delay_ms(OUR_RS485_ID);
printf("msg sent!");
}
char PCgetc()
{
in_char = 0;
while(!kbhit());
in_char = getc();
return in_char;
}
int8 PCgetInt()
{
int8 i, s[3];
for(i=0; (s[i]=PCgetc()) != '\r' && i<3; ++i);
return atoi(s);
}
char* PCgetMsg()
{
int8 i;
for(i=0; (msg[i] = PCgetc()) != '\r' && i<64; ++i);
msg[i] = '\0';
return &(msg[0]);
}
void get_string(char* s, unsigned int8 max) {
unsigned int8 len;
char c;
--max;
len=0;
do {
c=getc();
if(c==8) { // Backspace
if(len>0) {
len--;
putc(c);
putc(' ');
putc(c);
}
} else if ((c>=' ')&&(c<='~'))
if(len<=max) {
s[len++]=c;
putc(c);
}
} while(c!=13);
s[len]=0;
}
signed int8 get_int() {
char s[5];
signed int8 i;
get_string(s, 5);
i=atoi(s);
//printf("get int %d", i);
return(i);
}
#INT_RDA
void serial_isr()
{
//printf("INT RDA");
if(kbhit())
in_char = get_int;
//in_char = fgetc(PC);
}
void main()
{
int8 i, send_addr = 0;
char command;
int8 inteiro;
char *teste; //just a test variable
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
//enable_interrupts(INT_TIMER1);
rs485_init();
while(OUR_RS485_ID == 0 || OUR_RS485_ID >= 255)
{
printf("Please choose a network ID (1-255): ");
//inteiro = get_int();
//printf("%s",inteiro);
OUR_RS485_ID = PCgetInt();
//OUR_RS485_ID = inteiro;
}
printf("\n\rYour ID is: %d\n\r\n\rIf you require assistance, press h.\n\r", OUR_RS485_ID);
while(command != 'Q')
{
enable_interrupts(INT_TIMER1);
command = toupper(PCgetc());
//disable_interrupts(INT_TIMER1);
switch(command)
{
case 'S':
if(send_addr == 0 || send_addr > 255)
{
printf("\n\r\n\rEnter send address (1-255): ");
send_addr =get_int();
}
printf("\n\r%d:>", send_addr);
RS485send(PCgetint(), send_addr);
printf("Msg sent \n\r");
break;
case 'C':
send_addr = 0;
while(send_addr == 0 || send_addr > 255)
{
printf("\n\r\n\rEnter send address (1-255): ");
send_addr = PCgetint();
printf("\n\r");
}
break;
case 'I':
OUR_RS485_ID = 0;
while(OUR_RS485_ID == 0 || OUR_RS485_ID >= 255)
{
printf("\n\rPlease choose a network ID (1-255): ");
OUR_RS485_ID = PCgetint();
}
printf("\n\rYour ID is: %d\n\r\n\r", OUR_RS485_ID);
break;
case 'H':
printf("\n\rCommands: (S)end message, (C)hange Send Address, ");
printf("Change (I)D, (H)elp, (Q)uit.\n\r");
break;
default:
if(command != 'Q')
printf("\n\rInvalid command!\n\r");
}
}
}
|
Just pointing out that the code used in master and slave is the same!
Watching the oscilloscope, I noticed that there is sign on the 485´wires
just before setting the destination ID and type a message.
Ater typing the target ID and type the message, the code stops on the
line Code: | rs485_wait_for_bus(FALSE) | of RS485send() function.
Thank you for your time! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 26, 2009 11:11 am |
|
|
You have changed the CCS example in many ways.
Quote: | c:\program files\picc\examples\ex_rs485.c |
Try the CCS example with as few changes as possible. Make that code
work. Then try adding changes to it. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 26, 2009 4:54 pm |
|
|
I do agree with PCM Programmer. Start with a working program and then make small changes so you know the latest change is the one to break things.
Just a few remarks on your code: Code: | RS485send(PCgetint(), send_addr); | RS485send expects a string as input, you give it an integer.
Code: | int8 PCgetInt()
{
int8 i, s[3];
for(i=0; (s[i]=PCgetc()) != '\r' && i<3; ++i);
return atoi(s);
} | It is a very ugly coding style to have an assignment in the compare statement of the for-loop.
Bug: there is no terminating zero in s[] before your call to atoi().
Bug: You do have the terminating zero in PCgetMsg, but here it is possible a large message will write to msg[64]. A buffer overflow.
This line in get_string() can cause a buffer overflow. Change '<=' to '<'.
Also see my post in http://www.ccsinfo.com/forum/viewtopic.php?t=40633
Code: | #INT_RDA
void serial_isr()
{
//printf("INT RDA");
if(kbhit())
in_char = get_int;
//in_char = fgetc(PC);
} | Your program will only enter the interrupt when a character has been received. Hence testing kbhit will always be true and can be removed.
Calling get_int() from within the interrupt handler is bad practice. Get_int() will wait for a complete integer to be received. This is taking a long time for the processor and you are wasting a lot of processor resources. The same code can be written without interrupt handler and will be easier to understand. |
|
![](templates/subSilver/images/spacer.gif) |
ivrj
Joined: 17 Mar 2009 Posts: 7
|
|
Posted: Sat Nov 28, 2009 2:57 pm |
|
|
ckielstra wrote: | I do agree with PCM Programmer. Start with a working program and then make small changes so you know the latest change is the one to break things.
Just a few remarks on your code: Code: | RS485send(PCgetint(), send_addr); | RS485send expects a string as input, you give it an integer.
Code: | int8 PCgetInt()
{
int8 i, s[3];
for(i=0; (s[i]=PCgetc()) != '\r' && i<3; ++i);
return atoi(s);
} | It is a very ugly coding style to have an assignment in the compare statement of the for-loop.
Bug: there is no terminating zero in s[] before your call to atoi().
Bug: You do have the terminating zero in PCgetMsg, but here it is possible a large message will write to msg[64]. A buffer overflow.
|
this is the original rs485.c code! :(
ckielstra wrote: |
This line in get_string() can cause a buffer overflow. Change '<=' to '<'.
Also see my post in http://www.ccsinfo.com/forum/viewtopic.php?t=40633
Code: | #INT_RDA
void serial_isr()
{
//printf("INT RDA");
if(kbhit())
in_char = get_int;
//in_char = fgetc(PC);
} | Your program will only enter the interrupt when a character has been received. Hence testing kbhit will always be true and can be removed.
Calling get_int() from within the interrupt handler is bad practice. Get_int() will wait for a complete integer to be received. This is taking a long time for the processor and you are wasting a lot of processor resources. The same code can be written without interrupt handler and will be easier to understand. |
I really appreciate the time and attention of you, but after reading a lot about rs485 and ask some questions for a friend I finally understood a little more how an exchange of messages in 485. So , I will abandon the use of this library to do my own protocol.
I just wanted to take one more doubt: the rs485 is identical to RS232 for messaging, differing only in the use of "pin" activation mode for writing and reading? This is without considering the need to develop the communication protocol, treatment of collision, and everything else!
Again, thank you! |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Fri Mar 26, 2010 10:30 am |
|
|
ckielstra wrote: |
Code: | int8 PCgetInt()
{
int8 i, s[3];
for(i=0; (s[i]=PCgetc()) != '\r' && i<3; ++i);
return atoi(s);
} | It is a very ugly coding style to have an assignment in the compare statement of the for-loop.
|
Heh! you know how much of that's in the older Microchip TCPIP stack? Hahah..
I looked at it the same way too. "eeehhhh!!"
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|