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@0:fe18ab08e05d, 2011-11-21 (annotated)
- Committer:
- elmicro
- Date:
- Mon Nov 21 10:29:41 2011 +0000
- Revision:
- 0:fe18ab08e05d
Initial Revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elmicro | 0:fe18ab08e05d | 1 | #include "mbed.h" |
elmicro | 0:fe18ab08e05d | 2 | |
elmicro | 0:fe18ab08e05d | 3 | DigitalOut myled(LED1); |
elmicro | 0:fe18ab08e05d | 4 | Serial pc(USBTX, USBRX); |
elmicro | 0:fe18ab08e05d | 5 | |
elmicro | 0:fe18ab08e05d | 6 | void RS485_Init(void); |
elmicro | 0:fe18ab08e05d | 7 | void RS485_SendChar(unsigned char data); |
elmicro | 0:fe18ab08e05d | 8 | void RS485_SendText(char *pString); |
elmicro | 0:fe18ab08e05d | 9 | |
elmicro | 0:fe18ab08e05d | 10 | extern const unsigned int BRLookUp[][3]; |
elmicro | 0:fe18ab08e05d | 11 | |
elmicro | 0:fe18ab08e05d | 12 | |
elmicro | 0:fe18ab08e05d | 13 | void RS485_Init(unsigned int iBR, unsigned int iPCLK) |
elmicro | 0:fe18ab08e05d | 14 | { |
elmicro | 0:fe18ab08e05d | 15 | /* =================================================================== |
elmicro | 0:fe18ab08e05d | 16 | routine: RS485_Init |
elmicro | 0:fe18ab08e05d | 17 | purpose: Sets all required parameters for UART1 as RS485 |
elmicro | 0:fe18ab08e05d | 18 | using following signals: |
elmicro | 0:fe18ab08e05d | 19 | |
elmicro | 0:fe18ab08e05d | 20 | mbed | LPC1768 | function |
elmicro | 0:fe18ab08e05d | 21 | -----+---------+--------- |
elmicro | 0:fe18ab08e05d | 22 | P21 | P2[5] | DTR - '1' for TX |
elmicro | 0:fe18ab08e05d | 23 | P25 | P2[1] | RX |
elmicro | 0:fe18ab08e05d | 24 | P26 | P2[0] | TX |
elmicro | 0:fe18ab08e05d | 25 | |
elmicro | 0:fe18ab08e05d | 26 | parameters: <iBR> Desired baudrate |
elmicro | 0:fe18ab08e05d | 27 | <iPCLK> Current peripheral clock in Hz |
elmicro | 0:fe18ab08e05d | 28 | (mbed standard is 24000000) |
elmicro | 0:fe18ab08e05d | 29 | date: 2011-11-21 |
elmicro | 0:fe18ab08e05d | 30 | author: Stefan Guenther | Elektronikladen |
elmicro | 0:fe18ab08e05d | 31 | co-author: |
elmicro | 0:fe18ab08e05d | 32 | notes: Calculation of baudrate based on NXP's algorithm in |
elmicro | 0:fe18ab08e05d | 33 | the LPC17xx manual, Fig. 50 on page 334. |
elmicro | 0:fe18ab08e05d | 34 | |
elmicro | 0:fe18ab08e05d | 35 | PCLK |
elmicro | 0:fe18ab08e05d | 36 | baud = --------------------------------------- |
elmicro | 0:fe18ab08e05d | 37 | 16*(256*DLM+DLL)*(1+(DivAddVal/MulVal)) |
elmicro | 0:fe18ab08e05d | 38 | -------------------------------------------------------------------*/ |
elmicro | 0:fe18ab08e05d | 39 | |
elmicro | 0:fe18ab08e05d | 40 | unsigned int iDL, iFR, iOffset, x; |
elmicro | 0:fe18ab08e05d | 41 | unsigned char cDLM, cDLL, cMULVAL, cDIVADDVAL; |
elmicro | 0:fe18ab08e05d | 42 | |
elmicro | 0:fe18ab08e05d | 43 | iDL = iPCLK/(16*iBR); |
elmicro | 0:fe18ab08e05d | 44 | |
elmicro | 0:fe18ab08e05d | 45 | if(iDL*16*iBR==iPCLK) //iDL is an even number |
elmicro | 0:fe18ab08e05d | 46 | { |
elmicro | 0:fe18ab08e05d | 47 | cDIVADDVAL = 0; |
elmicro | 0:fe18ab08e05d | 48 | cMULVAL = 1; |
elmicro | 0:fe18ab08e05d | 49 | cDLM = 0; |
elmicro | 0:fe18ab08e05d | 50 | cDLL = 0; |
elmicro | 0:fe18ab08e05d | 51 | } else //iDL is an odd number |
elmicro | 0:fe18ab08e05d | 52 | { |
elmicro | 0:fe18ab08e05d | 53 | iOffset=0; |
elmicro | 0:fe18ab08e05d | 54 | do //change iFR until it's value is within 1.1 .. 1.9 range |
elmicro | 0:fe18ab08e05d | 55 | { |
elmicro | 0:fe18ab08e05d | 56 | iOffset+=100; |
elmicro | 0:fe18ab08e05d | 57 | iFR = 1005+iOffset; |
elmicro | 0:fe18ab08e05d | 58 | iDL=iPCLK/(0.016*iBR*iFR); |
elmicro | 0:fe18ab08e05d | 59 | iFR=iPCLK/(0.016*iBR*iDL); |
elmicro | 0:fe18ab08e05d | 60 | } while((iFR>1900) || (iFR<1100)); |
elmicro | 0:fe18ab08e05d | 61 | |
elmicro | 0:fe18ab08e05d | 62 | //iFR is now correctly calculated! |
elmicro | 0:fe18ab08e05d | 63 | |
elmicro | 0:fe18ab08e05d | 64 | cDLM = (iDL>>8); |
elmicro | 0:fe18ab08e05d | 65 | cDLL = iDL; |
elmicro | 0:fe18ab08e05d | 66 | x = 0; |
elmicro | 0:fe18ab08e05d | 67 | |
elmicro | 0:fe18ab08e05d | 68 | do //use lookup table to find values for DIVADDVAL and MULVAL |
elmicro | 0:fe18ab08e05d | 69 | { |
elmicro | 0:fe18ab08e05d | 70 | x++; |
elmicro | 0:fe18ab08e05d | 71 | } while(BRLookUp[x][0]<iFR); |
elmicro | 0:fe18ab08e05d | 72 | |
elmicro | 0:fe18ab08e05d | 73 | cDIVADDVAL = BRLookUp[x][1]; |
elmicro | 0:fe18ab08e05d | 74 | cMULVAL = BRLookUp[x][2]; |
elmicro | 0:fe18ab08e05d | 75 | } |
elmicro | 0:fe18ab08e05d | 76 | //Now, all necessary values are calculated for the desired baudrate according to |
elmicro | 0:fe18ab08e05d | 77 | //the current PCLK frequency. These values (cDLM, cDLL, cDIVADDVAL and cMULVAL) |
elmicro | 0:fe18ab08e05d | 78 | //now are used to configure UART1 for RS485 communication. |
elmicro | 0:fe18ab08e05d | 79 | |
elmicro | 0:fe18ab08e05d | 80 | LPC_PINCON->PINSEL4 |= 0x80A; //RXD1, TXD1, DTR1 |
elmicro | 0:fe18ab08e05d | 81 | LPC_SC->PCONP |= (1<<4); //Power on UART1 |
elmicro | 0:fe18ab08e05d | 82 | //LPC_SC->PCLKSEL //clock default is /4, we keep this |
elmicro | 0:fe18ab08e05d | 83 | LPC_UART1->LCR = 0x83; //sets DLAB; 8bit,1stopbit |
elmicro | 0:fe18ab08e05d | 84 | LPC_UART1->DLL = cDLL; //UART Divisor Latch LSB |
elmicro | 0:fe18ab08e05d | 85 | LPC_UART1->FDR = cDIVADDVAL; //DivAddVal |
elmicro | 0:fe18ab08e05d | 86 | LPC_UART1->FDR |= (cMULVAL<<4); //MulVal |
elmicro | 0:fe18ab08e05d | 87 | LPC_UART1->DLM = cDLM; //UART Divisor Latch MSB |
elmicro | 0:fe18ab08e05d | 88 | LPC_UART1->LCR &=~(1<<7); //clears DLAB |
elmicro | 0:fe18ab08e05d | 89 | LPC_UART1->RS485CTRL &=~(1<<1); //Receiver enabled |
elmicro | 0:fe18ab08e05d | 90 | LPC_UART1->RS485CTRL &=~(1<<2); //AAD disabled |
elmicro | 0:fe18ab08e05d | 91 | LPC_UART1->RS485CTRL |= (1<<3); //DTR used for direction control |
elmicro | 0:fe18ab08e05d | 92 | LPC_UART1->RS485CTRL |= (1<<4); //direction control enabled |
elmicro | 0:fe18ab08e05d | 93 | LPC_UART1->RS485CTRL |= (1<<5); //DTR=1 when transmitting |
elmicro | 0:fe18ab08e05d | 94 | //LPC_UART1->IER |= 1; //RBR IRQ enable |
elmicro | 0:fe18ab08e05d | 95 | //LPC_UART1->TER &= ~0x80; //!TXEN - disable transmitter, enable receiver |
elmicro | 0:fe18ab08e05d | 96 | //NVIC_EnableIRQ(UART1_IRQn); //set up CM3 NVIC to process UART1 IRQs |
elmicro | 0:fe18ab08e05d | 97 | RS485_SendText("\nRS485 communication port setup succesful!\n\n"); |
elmicro | 0:fe18ab08e05d | 98 | } |
elmicro | 0:fe18ab08e05d | 99 | |
elmicro | 0:fe18ab08e05d | 100 | void RS485_SendChar(unsigned char data) |
elmicro | 0:fe18ab08e05d | 101 | { |
elmicro | 0:fe18ab08e05d | 102 | LPC_UART1->TER |= 0x80; //enable transmitter |
elmicro | 0:fe18ab08e05d | 103 | while (!(LPC_UART1->LSR & 0x20)); //wait for UART1 to be ready - !!could lock up system!! |
elmicro | 0:fe18ab08e05d | 104 | LPC_UART1->THR=data; //write to THR register triggers transmission |
elmicro | 0:fe18ab08e05d | 105 | } |
elmicro | 0:fe18ab08e05d | 106 | |
elmicro | 0:fe18ab08e05d | 107 | void RS485_SendText(char *pString) |
elmicro | 0:fe18ab08e05d | 108 | { |
elmicro | 0:fe18ab08e05d | 109 | char *pText; //initialize pointer |
elmicro | 0:fe18ab08e05d | 110 | pText=(char *)pString; //set pointer to first character |
elmicro | 0:fe18ab08e05d | 111 | while(*pText!=0x00) { //0x00 marks end of text string |
elmicro | 0:fe18ab08e05d | 112 | RS485_SendChar(*pText); //send each character seperately |
elmicro | 0:fe18ab08e05d | 113 | *pText++; //move pointer to next character |
elmicro | 0:fe18ab08e05d | 114 | } |
elmicro | 0:fe18ab08e05d | 115 | } |
elmicro | 0:fe18ab08e05d | 116 | |
elmicro | 0:fe18ab08e05d | 117 | int main() { |
elmicro | 0:fe18ab08e05d | 118 | RS485_Init(115200, 24000000); //setup RS485 communication with 115200baud |
elmicro | 0:fe18ab08e05d | 119 | |
elmicro | 0:fe18ab08e05d | 120 | while(1) { |
elmicro | 0:fe18ab08e05d | 121 | myled = 1; |
elmicro | 0:fe18ab08e05d | 122 | wait(0.2); |
elmicro | 0:fe18ab08e05d | 123 | myled = 0; |
elmicro | 0:fe18ab08e05d | 124 | wait(0.2); |
elmicro | 0:fe18ab08e05d | 125 | } |
elmicro | 0:fe18ab08e05d | 126 | } |
elmicro | 0:fe18ab08e05d | 127 | |
elmicro | 0:fe18ab08e05d | 128 | |
elmicro | 0:fe18ab08e05d | 129 | /* =================================================================== |
elmicro | 0:fe18ab08e05d | 130 | table: BRLookUp |
elmicro | 0:fe18ab08e05d | 131 | purpose: provides settings for UART configuration (baudrate) |
elmicro | 0:fe18ab08e05d | 132 | date: 2011-02-04 |
elmicro | 0:fe18ab08e05d | 133 | author: Stefan Guenther | Elektronikladen |
elmicro | 0:fe18ab08e05d | 134 | source: NXP's user manual for the LPC17xx (UM10360), Page 335 |
elmicro | 0:fe18ab08e05d | 135 | -------------------------------------------------------------------*/ |
elmicro | 0:fe18ab08e05d | 136 | |
elmicro | 0:fe18ab08e05d | 137 | const unsigned int BRLookUp[72][3] = |
elmicro | 0:fe18ab08e05d | 138 | { |
elmicro | 0:fe18ab08e05d | 139 | 1000, 0, 1, |
elmicro | 0:fe18ab08e05d | 140 | 1067, 1, 15, |
elmicro | 0:fe18ab08e05d | 141 | 1071, 1, 14, |
elmicro | 0:fe18ab08e05d | 142 | 1077, 1, 13, |
elmicro | 0:fe18ab08e05d | 143 | 1083, 1, 12, |
elmicro | 0:fe18ab08e05d | 144 | 1091, 1, 11, |
elmicro | 0:fe18ab08e05d | 145 | 1100, 1, 9, |
elmicro | 0:fe18ab08e05d | 146 | 1125, 1, 8, |
elmicro | 0:fe18ab08e05d | 147 | 1133, 2, 15, |
elmicro | 0:fe18ab08e05d | 148 | 1143, 1, 7, |
elmicro | 0:fe18ab08e05d | 149 | 1154, 2, 13, |
elmicro | 0:fe18ab08e05d | 150 | 1167, 1, 6, |
elmicro | 0:fe18ab08e05d | 151 | 1182, 2, 11, |
elmicro | 0:fe18ab08e05d | 152 | 1200, 1, 5, |
elmicro | 0:fe18ab08e05d | 153 | 1214, 3, 14, |
elmicro | 0:fe18ab08e05d | 154 | 1222, 2, 9, |
elmicro | 0:fe18ab08e05d | 155 | 1231, 3, 13, |
elmicro | 0:fe18ab08e05d | 156 | 1250, 1, 4, |
elmicro | 0:fe18ab08e05d | 157 | 1267, 4, 15, |
elmicro | 0:fe18ab08e05d | 158 | 1273, 3, 11, |
elmicro | 0:fe18ab08e05d | 159 | 1286, 2, 7, |
elmicro | 0:fe18ab08e05d | 160 | 1300, 3, 10, |
elmicro | 0:fe18ab08e05d | 161 | 1308, 4, 13, |
elmicro | 0:fe18ab08e05d | 162 | 1333, 1, 3, |
elmicro | 0:fe18ab08e05d | 163 | 1357, 5, 14, |
elmicro | 0:fe18ab08e05d | 164 | 1364, 4, 11, |
elmicro | 0:fe18ab08e05d | 165 | 1375, 3, 8, |
elmicro | 0:fe18ab08e05d | 166 | 1385, 5, 13, |
elmicro | 0:fe18ab08e05d | 167 | 1400, 2, 5, |
elmicro | 0:fe18ab08e05d | 168 | 1417, 5, 12, |
elmicro | 0:fe18ab08e05d | 169 | 1429, 3, 7, |
elmicro | 0:fe18ab08e05d | 170 | 1444, 4, 9, |
elmicro | 0:fe18ab08e05d | 171 | 1455, 5, 11, |
elmicro | 0:fe18ab08e05d | 172 | 1462, 6, 13, |
elmicro | 0:fe18ab08e05d | 173 | 1467, 7, 15, |
elmicro | 0:fe18ab08e05d | 174 | 1500, 1, 2, |
elmicro | 0:fe18ab08e05d | 175 | 1533, 8, 15, |
elmicro | 0:fe18ab08e05d | 176 | 1538, 7, 13, |
elmicro | 0:fe18ab08e05d | 177 | 1545, 6, 11, |
elmicro | 0:fe18ab08e05d | 178 | 1556, 5, 9, |
elmicro | 0:fe18ab08e05d | 179 | 1571, 4, 7, |
elmicro | 0:fe18ab08e05d | 180 | 1583, 7, 12, |
elmicro | 0:fe18ab08e05d | 181 | 1600, 3, 5, |
elmicro | 0:fe18ab08e05d | 182 | 1615, 8, 13, |
elmicro | 0:fe18ab08e05d | 183 | 1625, 5, 8, |
elmicro | 0:fe18ab08e05d | 184 | 1636, 7, 11, |
elmicro | 0:fe18ab08e05d | 185 | 1643, 9, 14, |
elmicro | 0:fe18ab08e05d | 186 | 1667, 2, 3, |
elmicro | 0:fe18ab08e05d | 187 | 1692, 9, 13, |
elmicro | 0:fe18ab08e05d | 188 | 1700, 7, 10, |
elmicro | 0:fe18ab08e05d | 189 | 1714, 5, 7, |
elmicro | 0:fe18ab08e05d | 190 | 1727, 8, 11, |
elmicro | 0:fe18ab08e05d | 191 | 1733, 11, 15, |
elmicro | 0:fe18ab08e05d | 192 | 1750, 3, 4, |
elmicro | 0:fe18ab08e05d | 193 | 1769, 10, 13, |
elmicro | 0:fe18ab08e05d | 194 | 1778, 7, 9, |
elmicro | 0:fe18ab08e05d | 195 | 1786, 11, 14, |
elmicro | 0:fe18ab08e05d | 196 | 1800, 4, 5, |
elmicro | 0:fe18ab08e05d | 197 | 1818, 9, 11, |
elmicro | 0:fe18ab08e05d | 198 | 1833, 5, 6, |
elmicro | 0:fe18ab08e05d | 199 | 1846, 11, 13, |
elmicro | 0:fe18ab08e05d | 200 | 1857, 6, 7, |
elmicro | 0:fe18ab08e05d | 201 | 1867, 13, 15, |
elmicro | 0:fe18ab08e05d | 202 | 1875, 7, 8, |
elmicro | 0:fe18ab08e05d | 203 | 1889, 8, 9, |
elmicro | 0:fe18ab08e05d | 204 | 1900, 9, 10, |
elmicro | 0:fe18ab08e05d | 205 | 1909, 10, 11, |
elmicro | 0:fe18ab08e05d | 206 | 1917, 11, 12, |
elmicro | 0:fe18ab08e05d | 207 | 1923, 12, 13, |
elmicro | 0:fe18ab08e05d | 208 | 1929, 13, 14, |
elmicro | 0:fe18ab08e05d | 209 | 1933, 14, 15 |
elmicro | 0:fe18ab08e05d | 210 | }; |