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

Problem with 9-bit Addressing

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



Joined: 04 May 2004
Posts: 47
Location: UK

View user's profile Send private message

Problem with 9-bit Addressing
PostPosted: Tue May 04, 2004 4:32 pm     Reply with quote

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 );
}
Ttelmah
Guest







Re: Problem with 9-bit Addressing
PostPosted: Wed May 05, 2004 3:55 am     Reply with quote

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
andyfraser



Joined: 04 May 2004
Posts: 47
Location: UK

View user's profile Send private message

Re: Problem with 9-bit Addressing
PostPosted: Wed May 05, 2004 4:49 am     Reply with quote

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
Ttelmah
Guest







Re: Problem with 9-bit Addressing
PostPosted: Wed May 05, 2004 8:53 am     Reply with quote

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



Joined: 04 May 2004
Posts: 47
Location: UK

View user's profile Send private message

Re: Problem with 9-bit Addressing
PostPosted: Wed May 05, 2004 9:04 am     Reply with quote

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 Sad

Andy
Ttelmah
Guest







Re: Problem with 9-bit Addressing
PostPosted: Wed May 05, 2004 10:58 am     Reply with quote

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 Sad

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