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 CCS Technical Support

USART multiprocessors

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



Joined: 08 Oct 2010
Posts: 10

View user's profile Send private message

USART multiprocessors
PostPosted: Sat Mar 12, 2011 1:43 am     Reply with quote

Hi! I'm going to setup a small network with 1 master and 2 slave .
I use 9th bit mode with address detect.
In slave chip, data will be received when interrupt be called by 9th bit =1 , RCIF bit=1 and interrupt be enabled.
Here is my code for master and slave:
Master
Code:

#include <16F877A.h>

#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                      //Program memory not write protected

#use delay(clock=20000000)


#byte  SPBRG =0x99  // baudrate  reg

#byte  TXREG =0x19  // trans data  reg

#byte  RCSTA =0x18  // recieve data reg
#define SPEN 7
#define RX9 6
#define SREN 5
#define CREN 4
#define ADDEN 3
#define FERR 2
#define OERR 1
#define RX9D 0

#byte  TXSTA =0x98  // trans data control reg
#define CSRC 7
#define TX9 6
#define TXEN 5
#define SYNC 4
#define BRGH 2
#define TRMT 1
#define TX9D 0
int i;

void Init_UART(void)
   {
   
 TXSTA|=(1<<TX9); //select 9-bit transmissio
   SPBRG= 31;         // set baudrate 9600
   SET_TRIS_B( 0xFF);    // set  TX, RX 
     TXSTA&=~(1<< BRGH );     //Low speed
     TXSTA&=~(1<<SYNC);     //Asynchronous mode
     TXSTA|=(1<<TXEN);     //Transmit enable
     RCSTA|=(1<<SPEN);     //Serial port enable
     RCSTA|=(1<<CREN );     // eneble reception.

   }
// trans address
void tx_add(unsigned int chr)
{
    while(!(TXSTA&(1<<TRMT)));
   for(  i=0; i<30;i++);
      TXSTA|= (1<<TX9D);         // set bit 9th
   TXREG= chr;

}

       
// trans data
void tx_data(unsigned int chr)
{
    while(!(TXSTA&(1<<TRMT)));
    for(  i=0; i<30;i++);
    TXSTA&= ~(1<<TX9D);        // clear bit 9th
    TXREG= chr;
   
}
       
       
       
void main()
{
  Init_UART();
    while(1){ 
 
        tx_add(1);
        tx_data(66);
 
    }
}


Code for slave:
Code:


#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)


#byte  SPBRG =0x99  // baudrate reg

#byte  TXREG =0x19  // trans data reg

#byte  RCSTA =0x18  // rev data reg
#define SPEN 7
#define RX9 6
#define SREN 5
#define CREN 4
#define ADDEN 3
#define FERR 2
#define OERR 1
#define RX9D 0

#byte  TXSTA =0x98  // trans data control reg
#define CSRC 7
#define TX9 6
#define TXEN 5
#define SYNC 4
#define BRGH 2
#define TRMT 1
#define TX9D 0

#byte  PIE1 =0x8C  //

#define PSPIE  7
#define ADIE   6
#define RCIE   5
#define TXIE   4
#define SSPIE  3
#define CCP1IE 2
#define TMR2IE 1
#define TMR1IE 0
#byte RCREG = 0x1A
// ngat
//#byte INTCON = 0x0b
#define GIE 7
#define PEIE 6

#byte PIR1 = 0x0C
#define PSPIF  7
#define ADIF 6
#define RCIF 5
#define TXIF   4
#define SSPIF  3
#define CCP1IF 2
#define TMR2IF 1
#define TMR1IF 0



unsigned char ind;
unsigned char data;
unsigned char all_data[2];



unsigned char addr= 1;
#INT_RDA
RDA_ISR(unsigned char data, unsigned char all_data[2] )
{

  while (!(PIR1&(1<<RCIF)));
   data= RCREG;
   if ( ind == 0)
      {
         if ( addr ==  data)
            {
               RCSTA&= ~(1<<ADDEN);  // clear bit 9th
               ind ++;
            }
      }
   else{
         all_data[ind]= data;
         ind ++;
     //     TXREG=  all_data[ind];
    while(!(TXSTA&(1<<TRMT)));
    TXREG=  all_data[ind];
         if( ind ==2)
         {
            RCSTA|= (1<<ADDEN);  // set bit 9th
            ind =0;
         }
      }       
}


void Init_UART(void)
{
   TXSTA|=(1<<TX9); //select 9-bit transmission.
TXSTA&=~(1<<SYNC);
   
  RCSTA|=(ADDEN<<1); //enable address detection.
   PIE1|=(RCIE << 1); //enable interrupt.
  RCSTA|=(RX9 << 1); //select 9-bit reception.
   INTCON|=(GIE << 1); // for interrupt
   INTCON|=(PEIE << 1);
   
  SPBRG= 31;         // set baudrate
   SET_TRIS_B( 0xFF);    // set TX, RX 
     TXSTA&=~(1<< BRGH );     //Low speed
     TXSTA&=~(1<<SYNC);     //Asynchronous mode
     TXSTA|=(1<<TXEN);     //Transmit enable
     RCSTA|=(1<<SPEN);     //Serial port enable
     RCSTA|=(1<<CREN );     // eneble reception.

}
void tx_data(unsigned char chr)
{
   while(!(TXSTA&(1<<TRMT)));
   TXREG= chr;
}

char temp;
void main()
{

 //  long int i,j;
   // TODO: USER CODE!!
   Init_UART();
     set_tris_a(0xFF);
     
  enable_interrupts(GLOBAL);
    while(1)
    {
    }
}

I use Proteus to debug it and see RCIF doesn't change its value although RCREG have received data. So it can't go to the interupt service. Can you help me plzzz?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 4:16 pm     Reply with quote

I strongly suggest that you use CCS functions. Example of why:

Here, you have defined GIE and PEIE as their bit numbers instead of
their bitmasks.
Code:

#define GIE 7
#define PEIE 6

INTCON|=(GIE << 1); // for interrupt
 INTCON|=(PEIE << 1);

So then you shift the bit numbers left by 1. So you are shifting 0x07
and 0x06 left by 1 bit position. Considering that the true bitmask for
GIE is 0x80 and PEIE is 0x40, your code will not work. Here is the .LST
file for your code. Notice that it's putting 0x0E and 0x0C into INTCON.
This is incorrect.
Code:

....... INTCON|=(GIE << 1); // for interrupt 
000F:  MOVLW  0E
0010:  BCF    STATUS.RP0
0011:  IORWF  INTCON,F
.................... INTCON|=(PEIE << 1); 
0012:  MOVLW  0C
0013:  IORWF  INTCON,F


Now let's look at the CCS function, which you did not want to use.
It does it correctly. It turns on GIE and PEIE correctly in INTCON:
Code:

.................... enable_interrupts(GLOBAL);
0014:  MOVLW  C0
0015:  IORWF  INTCON,F

Use the CCS functions. They will prevent errors like this.
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 4:34 pm     Reply with quote

Also put a delay in your xmt forever loop to give your rcv units time to process what's being sent.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 4:35 pm     Reply with quote

Hi,

I agree with PCM, there is no need to "roll your own" serial functions, just use the built-in functions provided by the compiler. I also don't know why you want to mess around with the '9th bit' for addressing? Just define a simple protocol that includes a slave address. Each slave will receive all broadcast messages, but only the 'addressed' slave will respond. I just finished a multi-node sensor network using the canned CCS serial routines, and my own data protocol, and it works like a charm!

John
agreement



Joined: 08 Oct 2010
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 7:03 pm     Reply with quote

Quote:
I strongly suggest that you use CCS functions. Example of why:

Here, you have defined GIE and PEIE as their bit numbers instead of
their bitmasks.
Code:

#define GIE 7
#define PEIE 6

INTCON|=(GIE << 1); // for interrupt
 INTCON|=(PEIE << 1);


that's a fool mistake. It must be:
INTCON|=( 1<<GIE); // for interrupt
INTCON|=( 1<<PEIE);
Anyway, use the built in func will be better.
I have corrected that mistake but the program still not work properly, bit RCIF not be set although RCREG have receive data.


Last edited by agreement on Sat Mar 12, 2011 7:06 pm; edited 2 times in total
agreement



Joined: 08 Oct 2010
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 7:05 pm     Reply with quote

temtronic wrote:
Also put a delay in your xmt forever loop to give your rcv units time to process what's being sent.

Thanks! That's good idea! but slave still not go to interrupt service to receive data. :(
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 7:44 pm     Reply with quote

It'd be a whole lot easier to figure out if you'ld used the built in functions that CCS supplies !

However you seem to be missing the following line from the rcv main ..

enable_interrupts(int_rda);

This line should be before

enable_interrupts(GLOBAL);

Look at the CCS supplied ex_sisr.c example program as well as the help files( F11) in PCM.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 12, 2011 8:45 pm     Reply with quote

Quote:

void Init_UART(void)
{
TXSTA|=(1<<TX9); //select 9-bit transmission.
TXSTA&=~(1<<SYNC);

RCSTA|=(ADDEN<<1); //enable address detection.
PIE1|=(RCIE << 1); //enable interrupt.
RCSTA|=(RX9 << 1); //select 9-bit reception.
INTCON|=(GIE << 1); // for interrupt
INTCON|=(PEIE << 1);

SPBRG= 31; // set baudrate
SET_TRIS_B( 0xFF); // set TX, RX
TXSTA&=~(1<< BRGH ); //Low speed
TXSTA&=~(1<<SYNC); //Asynchronous mode
TXSTA|=(1<<TXEN); //Transmit enable
RCSTA|=(1<<SPEN); //Serial port enable
RCSTA|=(1<<CREN ); // eneble reception.

}

The hardware UART is on pins C6 and C7. It's on Port C, not Port B.
Use 100% CCS library code and functions. Then this won't happen.
agreement



Joined: 08 Oct 2010
Posts: 10

View user's profile Send private message

PostPosted: Sun Mar 13, 2011 12:31 pm     Reply with quote

PCM programmer wrote:
Quote:

void Init_UART(void)
{
TXSTA|=(1<<TX9); //select 9-bit transmission.
TXSTA&=~(1<<SYNC);

RCSTA|=(ADDEN<<1); //enable address detection.
PIE1|=(RCIE << 1); //enable interrupt.
RCSTA|=(RX9 << 1); //select 9-bit reception.
INTCON|=(GIE << 1); // for interrupt
INTCON|=(PEIE << 1);

SPBRG= 31; // set baudrate
SET_TRIS_B( 0xFF); // set TX, RX
TXSTA&=~(1<< BRGH ); //Low speed
TXSTA&=~(1<<SYNC); //Asynchronous mode
TXSTA|=(1<<TXEN); //Transmit enable
RCSTA|=(1<<SPEN); //Serial port enable
RCSTA|=(1<<CREN ); // eneble reception.

}

The hardware UART is on pins C6 and C7. It's on Port C, not Port B.
Use 100% CCS library code and functions. Then this won't happen.

It's realy a fool mistake. Im sorry about that.
But after I changed it to TRISC or use:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
there is no change in RCIF bit Sad .
temtronic



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

View user's profile Send private message

PostPosted: Sun Mar 13, 2011 2:12 pm     Reply with quote

Since you've made a few changes, repost the program, it'll be easier to follow....
agreement



Joined: 08 Oct 2010
Posts: 10

View user's profile Send private message

PostPosted: Mon Mar 14, 2011 1:16 am     Reply with quote

temtronic wrote:
Since you've made a few changes, repost the program, it'll be easier to follow....

Yes, this is my code:
For master:
Code:

#include <16F877A.h>

#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                      //Program memory not write protected

#use delay(clock=20000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)



#byte  TXREG =0x19  // trans data  reg

#byte  RCSTA =0x18  // recieve data control reg
#define SPEN 7
#define RX9 6
#define SREN 5
#define CREN 4
#define ADDEN 3
#define FERR 2
#define OERR 1
#define RX9D 0

#byte  TXSTA =0x98  // trans data control reg
#define CSRC 7
#define TX9 6
#define TXEN 5
#define SYNC 4
#define BRGH 2
#define TRMT 1
#define TX9D 0
int i;

// trans address
void tx_add(unsigned int chr)
{
   while(!(TXSTA&(1<<TRMT)));
   TXSTA|= (1<<TX9D);         // set bit 9th
   TXREG= chr;
}

       
// trans data
void tx_data(unsigned int chr)
{
   while(!(TXSTA&(1<<TRMT)));
   TXSTA&= ~(1<<TX9D);        // clear bit 9th
   TXREG= chr;
   
}
       
       
       
void main()
{
 
    while(1){ 
   delay_ms(500);    // wait for slave setup
   tx_add(1);
   delay_ms(500);     // wait for slave go to ISR to receive data
   tx_data(66);
    }
}

For slave
Code:

#include <16F877A.h>
#device adc=8
#use delay(clock=20000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected




#byte  TXREG =0x19  // trans data reg

#byte  RCSTA =0x18  // receive data reg
#define SPEN 7
#define RX9 6
#define SREN 5
#define CREN 4
#define ADDEN 3
#define FERR 2
#define OERR 1
#define RX9D 0

#byte  TXSTA =0x98  // trans data control reg
#define CSRC 7
#define TX9 6
#define TXEN 5
#define SYNC 4
#define BRGH 2
#define TRMT 1
#define TX9D 0


#byte RCREG = 0x1A



#byte PIR1 = 0x0C
#define PSPIF  7
#define ADIF 6
#define RCIF 5
#define TXIF   4
#define SSPIF  3
#define CCP1IF 2
#define TMR2IF 1
#define TMR1IF 0



unsigned char ind;
unsigned char data;
unsigned char all_data[2];



unsigned char addr= 1;
#INT_RDA
RDA_ISR(unsigned char data, unsigned char all_data[2] )
{
   data= RCREG;
   if ( ind == 0)
      {
         if ( addr ==  data)
            {
               RCSTA&= ~(1<<ADDEN);  // clear bit 9th
               ind ++;
            }
      }
   else{
         all_data[ind]= data;
         ind ++;
          TXREG=  all_data[ind];
         if( ind ==2)
         {
            RCSTA|= (1<<ADDEN);  // set bit 9th
            ind =0;
         }
      }       
}



void main()
{

   RCSTA|= (1<<ADDEN);  // set bit 9th for slave
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
 
    while(1)
    {
    while(!(TXSTA&(1<<TRMT)));   // Transmit data which have just reveived
    TXREG= all_data[1];
    }
}
temtronic



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

View user's profile Send private message

PostPosted: Mon Mar 14, 2011 6:41 am     Reply with quote

one item...
You need to add 'errors' to the RS232(....) function.
If you receive more than 2 characters and haven't cleared the buffer , it overruns and stops !
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