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.
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 };
Generated on Wed Jul 20 2022 02:17:21 by 1.7.2