How do I open multiple serial ports at different baud rates in Dynamic C?

You can open multiple serial ports with the Dynamic C serXopen() function(X = A, B, C, D, E or F).  This function may or may not use the Timer A prescaler to create the desired baud rate.  A problem occurs when opening more than one serial port at a time with lower baud rates.  For the lower baud rates, Timer A1 is needed as a  prescale.  The problem is that if the baud rate is low and both serial ports need to use the A1 prescaler, the second one overwrites the divisor that is loaded into A1, which can affect the baud rate for the first.
 
To take care of this, you can reload Timer A1 with a different divisor.  Please see the sample program below which shows how to recalculate the baud rates
 
The formula used is: An = (peripheral clock freq/2*16*(A1+1)*baud rate) - 1
==============================================================
//This sample shows how to reload Timer A1 so that all three serial ports can use it at the same time
//Commented below is formula for determining divisor

/********************************************************
1200_1200_300.C  BL2600 used w/ 44.2MHz xtal.
**********************************************************/

#define CINBUFSIZE 255
#define COUTBUFSIZE 255

#define EINBUFSIZE 255
#define EOUTBUFSIZE 255

#define FINBUFSIZE 255
#define FOUTBUFSIZE 255

main()
{
      brdInit();
   serCwrFlush();
     serCrdFlush();
   serEwrFlush();
     serErdFlush();
   serFwrFlush();
     serFrdFlush();

    serCopen(1200);
   printf("TAT6RShadow = %d\n", TAT6RShadow);
   printf("TAT1RShadow = %d\n", TAT1RShadow);
   if(TACRShadow & 1<<6)
       printf("Timer A6 gets input from A1\n");
   else
       printf("Timer A6 gets input from pclk/2\n");
    printf("\n");

   serEopen(1200);
   printf("TAT2RShadow = %d\n", TAT2RShadow);
   printf("TAT1RShadow = %d\n", TAT1RShadow);
   if(TACRShadow & 1<<2)
       printf("Timer A2 gets input from A1\n");
   else
       printf("Timer A2 gets input from pclk/2\n");
    printf("\n");

    serFopen(300);
   printf("TAT3RShadow = %d\n", TAT3RShadow);
   printf("TAT1RShadow = %d\n", TAT1RShadow);
   if(TACRShadow & 1<<3)
       printf("Timer A3 gets input from A1\n");
   else
       printf("Timer A3 gets input from pclk/2\n");
    printf("\n");

   //Since TimerA3 has maxed out divisor of 255, use that A1 divisor
   //which is 17.
   //Using following calculations we can change TimerA2 and TimerA6 divisors
   //to 63:
   //An = (peripheral clock freq/2*16*(A1+1)*baud rate) - 1
   //A2 or A6 = (44.2Mhz/2*16*(17+1)*1200) - 1
   //A2 or A6 = 63
   //Since serFopen(300) is the last port opened and A1 is already set with 17
   //we don't need to load A1 unless we change the order of the serXopen's

   //WrPortI(TAT1R,&TAT1RShadow, 17);
   WrPortI(TAT2R, &TAT2RShadow,63);
   WrPortI(TAT6R, &TAT6RShadow,63);

    ser485Tx();                            //    enable transmitter

   while(1)
   {
       costate
      {
          serCputc(0xAA);
         waitfor(DelayMs(100));
      }
       costate
      {
          serEputc(0xAA);
         waitfor(DelayMs(100));
      }
       costate
      {
          serFputc(0xAA);
         waitfor(DelayMs(100));
      }
    }
}
Last updated: Apr 12, 2019

Filed Under

Embedded

Recently Viewed

No recently viewed articles

Did you find this article helpful?