Example software showing how to use TestBed\'s RS485 feature with mbed\'s hardware UART1. Currently only the setup routine and a \"SendText\" routine are implemented. Can easily be used to develop receiving messages and invoking IRQ handling.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 DigitalOut myled(LED1);
00004 Serial pc(USBTX, USBRX);
00005 
00006 void RS485_Init(void);
00007 void RS485_SendChar(unsigned char data);
00008 void RS485_SendText(char *pString);
00009 
00010 extern const unsigned int BRLookUp[][3];
00011 
00012 
00013 void RS485_Init(unsigned int iBR, unsigned int iPCLK)
00014 {
00015 /* ===================================================================
00016     routine:    RS485_Init
00017     purpose:    Sets all required parameters for UART1 as RS485
00018                 using following signals:
00019              
00020                 mbed | LPC1768 | function
00021                 -----+---------+---------
00022                 P21  | P2[5]   | DTR - '1' for TX
00023                 P25  | P2[1]   | RX
00024                 P26  | P2[0]   | TX
00025     
00026     parameters: <iBR>        Desired baudrate
00027                 <iPCLK>      Current peripheral clock in Hz
00028                              (mbed standard is 24000000)
00029     date:       2011-11-21
00030     author:     Stefan Guenther | Elektronikladen
00031     co-author:    
00032     notes:      Calculation of baudrate based on NXP's algorithm in 
00033                 the LPC17xx manual, Fig. 50 on page 334.
00034 
00035                                         PCLK
00036                 baud = ---------------------------------------
00037                        16*(256*DLM+DLL)*(1+(DivAddVal/MulVal))
00038   -------------------------------------------------------------------*/
00039 
00040     unsigned int iDL, iFR, iOffset, x;
00041     unsigned char cDLM, cDLL, cMULVAL, cDIVADDVAL;    
00042     
00043     iDL = iPCLK/(16*iBR);    
00044     
00045     if(iDL*16*iBR==iPCLK)           //iDL is an even number    
00046     {        
00047         cDIVADDVAL = 0;
00048         cMULVAL    = 1;
00049         cDLM       = 0;
00050         cDLL       = 0;
00051     } else                          //iDL is an odd number
00052     {
00053         iOffset=0;
00054         do                          //change iFR until it's value is within 1.1 .. 1.9 range
00055         {
00056             iOffset+=100;      
00057             iFR = 1005+iOffset;
00058             iDL=iPCLK/(0.016*iBR*iFR);
00059             iFR=iPCLK/(0.016*iBR*iDL);            
00060         } while((iFR>1900) || (iFR<1100));        
00061         
00062         //iFR is now correctly calculated!
00063         
00064         cDLM        = (iDL>>8);
00065         cDLL        = iDL;              
00066         x = 0;            
00067         
00068         do                          //use lookup table to find values for DIVADDVAL and MULVAL
00069         {
00070             x++;
00071         } while(BRLookUp[x][0]<iFR);
00072             
00073         cDIVADDVAL = BRLookUp[x][1];
00074         cMULVAL    = BRLookUp[x][2];            
00075     }
00076     //Now, all necessary values are calculated for the desired baudrate according to
00077     //the current PCLK frequency. These values (cDLM, cDLL, cDIVADDVAL and cMULVAL)
00078     //now are used to configure UART1 for RS485 communication.
00079     
00080     LPC_PINCON->PINSEL4    |= 0x80A;        //RXD1, TXD1, DTR1    
00081     LPC_SC->PCONP          |= (1<<4);       //Power on UART1    
00082     //LPC_SC->PCLKSEL                       //clock default is /4, we keep this
00083     LPC_UART1->LCR          = 0x83;         //sets DLAB; 8bit,1stopbit                
00084     LPC_UART1->DLL          = cDLL;         //UART Divisor Latch LSB
00085     LPC_UART1->FDR          = cDIVADDVAL;   //DivAddVal
00086     LPC_UART1->FDR         |= (cMULVAL<<4); //MulVal     
00087     LPC_UART1->DLM          = cDLM;         //UART Divisor Latch MSB 
00088     LPC_UART1->LCR         &=~(1<<7);       //clears DLAB                 
00089     LPC_UART1->RS485CTRL   &=~(1<<1);       //Receiver enabled 
00090     LPC_UART1->RS485CTRL   &=~(1<<2);       //AAD disabled 
00091     LPC_UART1->RS485CTRL   |= (1<<3);       //DTR used for direction control 
00092     LPC_UART1->RS485CTRL   |= (1<<4);       //direction control enabled 
00093     LPC_UART1->RS485CTRL   |= (1<<5);       //DTR=1 when transmitting
00094     //LPC_UART1->IER |= 1;                  //RBR IRQ enable 
00095     //LPC_UART1->TER &= ~0x80;              //!TXEN - disable transmitter, enable receiver
00096     //NVIC_EnableIRQ(UART1_IRQn);           //set up CM3 NVIC to process UART1 IRQs
00097     RS485_SendText("\nRS485 communication port setup succesful!\n\n");
00098 }
00099 
00100 void RS485_SendChar(unsigned char data)
00101 {
00102     LPC_UART1->TER |= 0x80;                 //enable transmitter
00103     while (!(LPC_UART1->LSR & 0x20));       //wait for UART1 to be ready - !!could lock up system!!
00104     LPC_UART1->THR=data;                    //write to THR register triggers transmission
00105 }
00106 
00107 void RS485_SendText(char *pString) 
00108 {
00109     char *pText;                            //initialize pointer
00110     pText=(char *)pString;                  //set pointer to first character
00111     while(*pText!=0x00) {                   //0x00 marks end of text string
00112         RS485_SendChar(*pText);             //send each character seperately
00113         *pText++;                           //move pointer to next character
00114     }     
00115 }
00116 
00117 int main() {
00118     RS485_Init(115200, 24000000);           //setup RS485 communication with 115200baud
00119     
00120     while(1) {
00121         myled = 1;
00122         wait(0.2);
00123         myled = 0;
00124         wait(0.2);
00125     }
00126 }
00127 
00128 
00129 /* ===================================================================    
00130     table:      BRLookUp
00131     purpose:    provides settings for UART configuration (baudrate)    
00132     date:       2011-02-04
00133     author:     Stefan Guenther | Elektronikladen    
00134     source:     NXP's user manual for the LPC17xx (UM10360), Page 335
00135   -------------------------------------------------------------------*/
00136 
00137 const unsigned int BRLookUp[72][3]    =
00138 {
00139     1000,     0,  1,
00140     1067,    1,    15,
00141     1071,    1,    14,
00142     1077,    1,    13,
00143     1083,    1,    12,
00144     1091,    1,    11,
00145     1100,    1,    9,
00146     1125,    1,    8,
00147     1133,    2,    15,
00148     1143,    1,    7,
00149     1154,    2,    13,
00150     1167,    1,    6,
00151     1182,    2,    11,
00152     1200,    1,    5,
00153     1214,    3,    14,
00154     1222,    2,    9,
00155     1231,    3,    13,
00156     1250,    1,    4,
00157     1267,    4,    15,
00158     1273,    3,    11,
00159     1286,    2,    7,
00160     1300,    3,    10,
00161     1308,    4,    13,
00162     1333,    1,    3,
00163     1357,    5,    14,
00164     1364,    4,    11,
00165     1375,    3,    8,
00166     1385,    5,    13,
00167     1400,    2,    5,
00168     1417,    5,    12,
00169     1429,    3,    7,
00170     1444,    4,    9,    
00171     1455,    5,    11,
00172     1462,    6,    13,
00173     1467,    7,    15,
00174     1500,    1,    2,    
00175     1533,    8,    15,
00176     1538,    7,    13,
00177     1545,    6,    11,
00178     1556,    5,    9,
00179     1571,    4,    7,
00180     1583,    7,    12,
00181     1600,    3,    5,
00182     1615,    8,    13,
00183     1625,    5,    8,
00184     1636,    7,    11,
00185     1643,    9,    14,
00186     1667,    2,    3,
00187     1692,    9,    13,
00188     1700,    7,    10,
00189     1714,    5,    7,
00190     1727,    8,    11,
00191     1733,    11,    15,
00192     1750,    3,    4,
00193     1769,    10,    13,
00194     1778,    7,    9,
00195     1786,    11,    14,
00196     1800,    4,    5,
00197     1818,    9,    11,
00198     1833,    5,    6,
00199     1846,    11,    13,
00200     1857,    6,    7,
00201     1867,    13,    15,
00202     1875,    7,    8,
00203     1889,    8,    9,
00204     1900,    9,  10,
00205     1909,    10,    11,
00206     1917,    11,    12,
00207     1923,    12,    13,
00208     1929,    13,    14,
00209     1933,    14,    15
00210 };