|
|
View previous topic :: View next topic |
Author |
Message |
emil_86 Guest
|
RS485.c - Communication won't work |
Posted: Wed Nov 22, 2006 3:56 am |
|
|
hy,
im a student and actually working on a project where i need rs485,
i've tried to utilize the included rs485.c,
but when monitoring the communication between 2 pic'S i only see a 5V-peak from the sending to the receiving pic.
plz take a look at my source,
thanks in advance,
emil
Code: |
#include <18f2580.h>
#use delay(clock=8000000)
#include "lcd_HD44780_4x16.c"
#fuses INTRC_IO, NOWDT, NOMCLR, NOLVP, NOPROTECT
#define RS485_DRIVER
#define RS485_ID 0x20 // The device's RS485 address or ID
#define RS485_USE_EXT_INT FALSE // Select between external interrupt
#define RS485_RX_PIN PIN_C7 // Data receive pin
#define RS485_TX_PIN PIN_C6 // Data transmit pin
#define RS485_ENABLE_PIN PIN_B4 // Controls DE pin. RX low, TX high.
#define RS485_RX_ENABLE PIN_B5 // Controls RE pin. Should keep low.
#use rs232(baud=9600, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=9, long_data, errors, stream=RS485)
#use rs232(baud=9600, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=9, long_data, force_sw, multi_master, errors, stream=RS485_CD)
#if getenv("AUART")
#define RCV_OFF() {setup_uart(FALSE);}
#else
#define RCV_OFF() {setup_uart(FALSE);}
#endif
#define RS485_wait_time 20 // Wait time in milliseconds
#bit rs485_collision = rs232_errors.6
#define RS485_RX_BUFFER_SIZE 40
int rs485_state, rs485_ni, rs485_no;
int rs485_buffer[RS485_RX_BUFFER_SIZE];
int8 temp_ni;
void RCV_ON(void) {
while(kbhit(RS485)) {getc();} // Clear RX buffer. Clear RDA interrupt flag. Clear overrun error flag.
#if getenv("AUART")
setup_uart(UART_ADDRESS);
setup_uart(TRUE);
#else
setup_uart(TRUE);
#endif
}
void rs485_init() {
RCV_ON();
rs485_state=0;
rs485_ni=0;
rs485_no=0;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
output_low(RS485_RX_ENABLE);
}
void rs485_add_to_temp(int8 b) {
// Store the byte
rs485_buffer[temp_ni] = b;
// Make the index cyclic
if(++temp_ni >= RS485_RX_BUFFER_SIZE)
{
temp_ni = 0;
}
}
#int_rda
void incomming_rs485() {
int16 b;
static int8 cs,state=0,len;
static int16 to,source;
b=fgetc(RS485);
cs^=(int8)b;
switch(state) {
case 0: // Get from address
temp_ni=rs485_ni;
source=b;
cs=b;
rs485_add_to_temp(source);
break;
case 1: // Get to address
to=b;
#if (getenv("AUART")&&(RS485_USE_EXT_INT==FALSE))
setup_uart(UART_DATA);
#endif
break;
case 2: // Get len
len=b;
rs485_add_to_temp(len);
break;
case 255: // Get checksum
if ((!cs)&&(bit_test(to,8))&&(bit_test(source,8))&&((int8)to==RS485_ID)) { // If cs==0, then checksum is good
rs485_ni=temp_ni;
}
#if (getenv("AUART")&&(RS485_USE_EXT_INT==FALSE))
setup_uart(UART_ADDRESS);
#endif
state=0;
return;
default: // Get data
rs485_add_to_temp(b);
--len;
break;
}
if ((state>=3) && (!len)) {
state=255;
}
else {
++state;
}
}
int1 rs485_send_message(int8 to, int8 len, int8* data) {
int8 try, i, cs;
int1 ret = FALSE;
RCV_OFF();
for(try=0; try<5; ++try) {
rs485_collision = 0;
fputc((int16)0x100|rs485_id, RS485_CD);
fputc((int16)0x100|to, RS485_CD);
fputc(len, RS485_CD);
for(i=0, cs=rs485_id^to^len; i<len; ++i) {
cs ^= *data;
fputc(*data, RS485_CD);
++data;
}
fputc(cs, RS485_CD);
if(!rs485_collision) {
ret = TRUE;
break;
}
delay_ms(RS485_ID);
}
RCV_ON();
return(ret);
}
void rs485_wait_for_bus(int1 clrwdt)
{
int16 i;
RCV_OFF();
for(i=0; i <rs485_wait_time>0; --n)
{
*data_ptr = rs485_buffer[rs485_no];
if(++rs485_no >= sizeof(rs485_buffer))
{
rs485_no = 0;
}
++data_ptr;
}
return TRUE;
}
}
/** H A U P T P R O G R A M M *************************************************/
void main(void)
{
int8 *z,lol,lol1,lol2,id_send,data_leng,data_send;
char text[15];
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF); //stellt die Frequ. auf 8MHz
set_tris_a(0x00); OUTPUT_a(0xFF);
delay_ms(500);
OUTPUT_a(0x00);
delay_ms(500);
OUTPUT_a(0xFF);
delay_ms(500);
OUTPUT_a(0x00);
delay_ms(500);
OUTPUT_a(0xFF);
delay_ms(500);
OUTPUT_a(0x00);
delay_ms(500);
lcd_init(); //initialisiert das LCD
rs485_init();
lcd_clearlcd();
printf(lcd_putc,"Warten auf Rx...");
rs485_get_message(*z,TRUE);
lcd_gotoxy(1,3);
id_send=*z;
data_leng=*(z+8);
data_send=*(z+16);
lol=&z;
lol1=&z+8;
lol2=&z+16;
sprintf(text,"%i %i %i %i %i %i",id_send,data_leng,data_send, lol, lol1, lol2);
printf(lcd_putc,text);
} |
|
|
|
emil86
Joined: 14 Nov 2006 Posts: 6 Location: Austria, Vienna
|
Forgotten |
Posted: Wed Nov 22, 2006 3:59 am |
|
|
the source of the sender:
Code: | void main(void)
{
int8 *x,y;
y=130;
*x=y;
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF); //stellt die Frequ. auf 8MHz
set_tris_a(0x00); OUTPUT_a(0xFF);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
lcd_init(); //initialisiert das LCD
lcd_definechar(); //intitialisiert eigenen Zeichen (pfeil rauf, pfeil runter)
lcd_gotoxy(11,1);
printf(lcd_putc,"SEAS");
delay_ms(300);
rs485_init();
delay_ms(300);
while (rs485_send_message(0x20, 1 ,*x)==FALSE)
{
rs485_send_message(20, 1 ,*x);
}
lcd_clearlcd();
printf(lcd_putc,"Paket gesendet");
lcd_gotoxy(1,2);
printf(lcd_putc,"0x20,5"); |
thx |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 22, 2006 4:18 am |
|
|
RS485, _is_ a 5v signalling standard. It uses a pair of differential 5v lines. You have got the hardware drivers for these differential signals?.
Best Wishes |
|
|
emil86
Joined: 14 Nov 2006 Posts: 6 Location: Austria, Vienna
|
|
Posted: Wed Nov 22, 2006 4:26 am |
|
|
i have them lying around,...but i think i dont need them now, because im transmitting on one Board (3cm)
i think it also should work if im only using 2 pic's and connecting rx-->tx and tx<--rx.
Do you can find any errors in the source ??
thanks in advance,
emil |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 22, 2006 5:27 am |
|
|
The point is that RS485, is a 5v standard. It is also half duplex. The original code as writen, requires the drivers, to allow the bus turnround, and the presence of multiple receivers. If you only want to talk between two chips, then you don't need the RS485 stuff at all. Just connect RX on one chip to TX on the other, then the same the other way, and send the data.
Best Wishes |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Wed Nov 22, 2006 6:20 am |
|
|
As Ttelmah
You dont need to use the RS485 chips if you just want pic to pic communication except if it is one of the specification for your project.
if can find some info here for Rs485
www.basicstampiii.com/dl/docs/prod/appkit/rs485Communication.pdf
Good luck _________________ BOB_Santana |
|
|
|
|
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
|