![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
andyfraser
Joined: 04 May 2004 Posts: 47 Location: UK
|
Problem with 9-bit Addressing |
Posted: Tue May 04, 2004 4:32 pm |
|
|
Hi,
I am trying to use 9-bit addressing on my RS485 link using a PIC16F877. I cannot get the receive interrupt service routine to be called when set to interrupt on an address but do when I set it to interrupt on data. An extract of the code I am using follows.
As you can see from the code, I set PIN_B5 low then high in the receive ISR. With the initialisation code shown below, I get no activity on B5 however, if I change the line setup_uart( UART_ADDRESS ) to setup_uart( UART_DATA ), I see a pulse for each character on the bus !
Any help would be much appreciated.
Andy
At top of program:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,enable=RS485_ENABLE,bits=9,long_data,errors,stream=RS485 )
Initialising:
setup_uart( UART_ADDRESS );
setup_uart( TRUE );
output_low( RS485_ENABLE );
//
// Turn on the serial interrupts
//
enable_interrupts( INT_RDA );
enable_interrupts( GLOBAL );
Sending:
int8 i;
int8 cs = 0;
//
// Send address
//
fputc( (int16)0x100 | g_Packet[ 0 ],RS485 );
//
// Send the remaining data with the 9th bit clear
//
for( i = 1 ; i < PACKET_LEN ; i++ )
{
cs += g_Packet[ i ];
fputc( g_Packet[ i ],RS485 );
}
//
// Now send the checksum
//
fputc( cs,RS485 );
Receiving:
#int_rda
void rx_isr()
{
int16 b;
output_low( PIN_B5 );
//
// Get received charcater
//
b = fgetc( RS485 );
output_high( PIN_B5 );
} |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
Re: Problem with 9-bit Addressing |
Posted: Wed May 05, 2004 3:55 am |
|
|
andyfraser wrote: | Hi,
I am trying to use 9-bit addressing on my RS485 link using a PIC16F877. I cannot get the receive interrupt service routine to be called when set to interrupt on an address but do when I set it to interrupt on data. An extract of the code I am using follows.
As you can see from the code, I set PIN_B5 low then high in the receive ISR. With the initialisation code shown below, I get no activity on B5 however, if I change the line setup_uart( UART_ADDRESS ) to setup_uart( UART_DATA ), I see a pulse for each character on the bus !
Any help would be much appreciated.
Andy
At top of program:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,enable=RS485_ENABLE,bits=9,long_data,errors,stream=RS485 )
Initialising:
setup_uart( UART_ADDRESS );
setup_uart( TRUE );
output_low( RS485_ENABLE );
//
// Turn on the serial interrupts
//
enable_interrupts( INT_RDA );
enable_interrupts( GLOBAL );
Sending:
int8 i;
int8 cs = 0;
//
// Send address
//
fputc( (int16)0x100 | g_Packet[ 0 ],RS485 );
//
// Send the remaining data with the 9th bit clear
//
for( i = 1 ; i < PACKET_LEN ; i++ )
{
cs += g_Packet[ i ];
fputc( g_Packet[ i ],RS485 );
}
//
// Now send the checksum
//
fputc( cs,RS485 );
Receiving:
#int_rda
void rx_isr()
{
int16 b;
output_low( PIN_B5 );
//
// Get received charcater
//
b = fgetc( RS485 );
output_high( PIN_B5 );
} |
I haven't looked at the body of your code, but the obvious problem, is that you are misunderstanding how '9bit' works on the PIC with CCS. Basically, when 9bit mode is enabled, the UART, sends/receives 9bit data, _but_ only 8 bits of this, is sendable/receivable through the main receive data /transmit data register. So 'putc', and 'getc', still only handle 8 bit data. You have to seperate off the 9th bit yourself, and write this bit to the RS232_ERRORS register (bit 7). Look at the example file 'ex_pbusm.c', to see how to do this.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
andyfraser
Joined: 04 May 2004 Posts: 47 Location: UK
|
Re: Problem with 9-bit Addressing |
Posted: Wed May 05, 2004 4:49 am |
|
|
Ttelmah,
Thanks for the reply but if you look in the body of the code you will see that I don't use putc and getc, i use fputc and fgetc. According to the example code for multi-drop programming (rs485.c) I can send a 16-bit value through fputc. I think this is a feature added recently to the compiler, so I should have explained that I am using version 3.184. Out of interest, I got the code working by manipulating the UART bits directly as shown below.
Code: |
void SendPacket( void )
{
int16 hdr;
char cs = 0;
char i;
//
// Enable transmitter, disable receiver
//
output_high( RS485_ENABLE );
//
// Enable 9-bit addressing and set the 9th bit
//
TX9 = 1;
TX9D = 1;
//
// Send address byte/digital input bits with the 9th bit set
//
hdr = 0x100 + g_Packet[ 0 ];
fputc( hdr,RS485 );
//
// Disable 9-bit addressing and clear the 9th bit
//
TX9 = 0;
TX9D = 0;
//
// Send the remaining data with the 9th bit clear
//
for( i = 1 ; i < PACKET_LEN ; i++ )
{
cs += g_Packet[ i ];
fputc( g_Packet[ i ],RS485 );
}
//
// Now send the checksum
//
fputc( cs,RS485 );
//
// Enable receiver, disable transmitter
//
output_low( RS485_ENABLE );
}
|
Thanks
Andy |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
Re: Problem with 9-bit Addressing |
Posted: Wed May 05, 2004 8:53 am |
|
|
andyfraser wrote: | Ttelmah,
Thanks for the reply but if you look in the body of the code you will see that I don't use putc and getc, i use fputc and fgetc. According to the example code for multi-drop programming (rs485.c) I can send a 16-bit value through fputc. I think this is a feature added recently to the compiler, so I should have explained that I am using version 3.184. Out of interest, I got the code working by manipulating the UART bits directly as shown below.
Code: |
void SendPacket( void )
{
int16 hdr;
char cs = 0;
char i;
//
// Enable transmitter, disable receiver
//
output_high( RS485_ENABLE );
//
// Enable 9-bit addressing and set the 9th bit
//
TX9 = 1;
TX9D = 1;
//
// Send address byte/digital input bits with the 9th bit set
//
hdr = 0x100 + g_Packet[ 0 ];
fputc( hdr,RS485 );
//
// Disable 9-bit addressing and clear the 9th bit
//
TX9 = 0;
TX9D = 0;
//
// Send the remaining data with the 9th bit clear
//
for( i = 1 ; i < PACKET_LEN ; i++ )
{
cs += g_Packet[ i ];
fputc( g_Packet[ i ],RS485 );
}
//
// Now send the checksum
//
fputc( cs,RS485 );
//
// Enable receiver, disable transmitter
//
output_low( RS485_ENABLE );
}
|
Thanks
Andy |
RS485.C, is not a standard CCS example.
The help file, still says that fputc, only takes an 8bit value.
You can write your own 'encapsulated' function like this:
#bit ninth_bit=RS232_ERRORS.7
void send9(int16 val) {
ninth_bit=make8(val,1);
fputc(make8(val,0),RS485);
}
This will send 9bit data. |
|
![](templates/subSilver/images/spacer.gif) |
andyfraser
Joined: 04 May 2004 Posts: 47 Location: UK
|
Re: Problem with 9-bit Addressing |
Posted: Wed May 05, 2004 9:04 am |
|
|
Ttelmah,
To quote the readme.txt file that came with my version of the compiler :
New options for #UASE RS232:
SAMPLE_EARLY
A getc() normally samples data in the middle of a bit time. This option causes the sample to be at the start of a bit time. May not be used with the UART.
RETURN=pin
For FLOAT_HIGH and MULTI_MASTER this is the pin used to read the signal back. The default for FLOAT_HIGH is the XMIT pin and for MULTI_MASTER the RCV pin.
MULTI_MASTER
Uses the RETURN pin to determine if another master on the bus is transmitting at the same time. If a collision is detected bit 6 is set in RS232_ERRORS and all future PUTC's are ignored until bit 6 is cleared. The signal is checked at the start and end of a bit time. May not be used with the UART.
LONG_DATA
Makes getc() return an int16 and putc accept an int16. This is for 9 bit data formats.
DISABLE_INTS
Will cause interrupts to be disabled when the routines get or put a character. This prevents character distortion for software implemented I/O and prevents interaction between I/O in interrupt handlers and the main program when using the UART.
See RS485.C in the drivers directory for an example RS485 protocol implementation.
However, I could not get this to work correctly and as mentioned in my previous reply, I had to bash the UART registers directly
Andy |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
Re: Problem with 9-bit Addressing |
Posted: Wed May 05, 2004 10:58 am |
|
|
andyfraser wrote: | Ttelmah,
To quote the readme.txt file that came with my version of the compiler :
New options for #UASE RS232:
SAMPLE_EARLY
A getc() normally samples data in the middle of a bit time. This option causes the sample to be at the start of a bit time. May not be used with the UART.
RETURN=pin
For FLOAT_HIGH and MULTI_MASTER this is the pin used to read the signal back. The default for FLOAT_HIGH is the XMIT pin and for MULTI_MASTER the RCV pin.
MULTI_MASTER
Uses the RETURN pin to determine if another master on the bus is transmitting at the same time. If a collision is detected bit 6 is set in RS232_ERRORS and all future PUTC's are ignored until bit 6 is cleared. The signal is checked at the start and end of a bit time. May not be used with the UART.
LONG_DATA
Makes getc() return an int16 and putc accept an int16. This is for 9 bit data formats.
DISABLE_INTS
Will cause interrupts to be disabled when the routines get or put a character. This prevents character distortion for software implemented I/O and prevents interaction between I/O in interrupt handlers and the main program when using the UART.
See RS485.C in the drivers directory for an example RS485 protocol implementation.
However, I could not get this to work correctly and as mentioned in my previous reply, I had to bash the UART registers directly
Andy |
Simple comment. I treat anything that is not at least twenty compiler versions old, as a 'beta'. You now know why. The other comment, is why on earth they will put 'examples', in the 'drivers' directory... :-)
I have the late' compilers, but at present am still treating the 3.148 release as the last eally stable one. The newer version, seem to have introduced a whole 'crop' of bugs at present.
Best Wishes |
|
![](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
|