(114 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
[[category: LPC1768 Tutorials]]
 
[[category: LPC1768 Tutorials]]
 
 
 
 
 
=Objective=
 
=Objective=
In this tutorial we are going to discuss the serial communication using UART. For more info on UART/RS232 check the below 8051 tutorial.<br>
+
In this tutorial we are going to discuss the serial communication using UART.<br>
 +
For more info on UART/RS232 check [[A4.8051 Communication Protocols:UART, RS232|8051 tutorial]].<br>
 
LPC1768 has four inbuilt USARTs. We are going to discuss only UART0. After this tutorial you should be able to extend it to remaining three UARTS.<br>
 
LPC1768 has four inbuilt USARTs. We are going to discuss only UART0. After this tutorial you should be able to extend it to remaining three UARTS.<br>
After understating the basics of LPC1768 UART module, We will discuss how to use the %%%%% libraries to communicate with any of the UART devices.<br>
+
After understating the basics of LPC1768 UART module, We will discuss how to use the ExploreEmbedded libraries to communicate with any of the UART devices.<br><br><br><br>
  
=LPC1768 ADC Block=
+
=UART module=
LPC1768 has an inbuilt 12 bit Successive Approximation ADC which is multiplexed among 8 input pins.<br>
+
UART module and registers.
The ADC reference voltage is measured across  VREFN to VREFP, meaning it can do the conversion within this range. Usually the VREFP is connected to VDD and VREFN is connected to GND.<br>
+
LPC1768 has 4-UARTs numbering 0-3, similarly the pins are also named as RXD0-RXD3 and TXD0-TXD3.As the LPC1768 pins are multiplexed for multiple functionalities, first they have to be configured as UART pins.<br>
As LPC1768 works on 3.3 volts, this will be the ADC reference voltage.<br>
+
Below table shows the multiplexed UARTs pins.<br>
Now the resolution of ADC = 3.3/(2^12) = 3.3/4096 =0.000805 = 0.8mV<br>
+
  
The below block diagram shows the ADC input pins multiplexed with other GPIO pins.<br>
+
{| class="table table-striped table-hover table-condensed table-bordered"
The ADC pin can be enabled by configuring the corresponding PINSEL register to select ADC function.<br>
+
|-class="info"
When the ADC function is selected for that pin in the Pin Select register, other Digital signals are disconnected from the ADC input pins.
+
!Port Pin|| Pin Number || PINSEL_FUNC_0 || PINSEL_FUNC_1 ||PINSEL_FUNC_2 ||PINSEL_FUNC_3
{| class="wikitable" style="text-align:left; background-color:#ABCDEF;"
+
!Adc Channel || Port Pin || Pin Functions || Associated PINSEL Register
+
 
|-
 
|-
|AD0|| P0.23  || 0-GPIO, 1-<b>AD0[0]</b>, 2-I2SRX_CLK, 3-CAP3[0] ||14,15 bits of PINSEL1
+
|P0.02 || 98 || GPIO || <b>TXD0</b> || ADC0[7] ||  
|-                                                                 
+
|AD1|| P0.24  || 0-GPIO, 1-<b>AD0[1]</b>, 2-I2SRX_WS,  3-CAP3[1] ||16,17 bits of PINSEL1
+
|-                                                                 
+
|AD2|| P0.25  || 0-GPIO, 1-<b>AD0[2]</b>, 2-I2SRX_SDA, 3-TXD3        ||18,19 bits of PINSEL1
+
|-                                                                 
+
|AD3|| P0.26  || 0-GPIO, 1-<b>AD0[3]</b>, 2-AOUT,        3-RXD3    ||20,21 bits of PINSEL1
+
|-                                                                 
+
|AD4|| P1.30  || 0-GPIO, 1-VBUS,  2-  ,      3-<b>AD0[4]</b>        ||28,29 bits of PINSEL3
+
|-                                                                 
+
|AD5|| P1.31  || 0-GPIO, 1-SCK1,  2-  ,        3-<b>AD0[5]</b>        ||30,31 bits of PINSEL3
+
|-                                                                 
+
|AD6|| P0.3  ||    0-GPIO, 1-RXD0,        2-<b>AD0[6]</b>,      3-  ||6,7 bits of PINSEL0 
+
|-                                                                 
+
|AD7|| P0.2  ||    0-GPIO, 1-TXD0,        2-<b>AD0[7]</b>,      3-  ||4,5 bits of PINSEL0 
+
|}
+
 
+
 
+
 
+
 
+
 
+
 
+
=ADC Registers  =
+
The below table shows the registers associated with LPC1768 ADC.<br>
+
We are going to focus only on ADCR and ADGDR as these are sufficient for simple A/D conversion.<br>
+
However once you are familer with LPC1768 ADC, you can explore the other features and the associated registers.
+
{| class="wikitable" style="text-align:left; background-color:#ABCDEF;"
+
!Register || Description
+
 
|-
 
|-
|ADCR|| A/D COntrol Register: Used for Configuring the ADC
+
|P0.03 || 99 || GPIO || <b>RXD0</b> || ADC0[6] ||
 
|-
 
|-
|ADGDR|| A/D Global Data Register: This register contains the ADC’s DONE bit and the result of the most recent A/D conversion
+
|P2_0 || 48 || GPIO || PWM1[1] || <b>TXD1</b>  ||
 
|-
 
|-
|ADINTEN|| A/D Interrupt Enable Register
+
|P2.1 || 49 || GPIO || PWM1[2] || <b>RXD1</b> ||
 
|-
 
|-
|ADDR0 - ADDR7|| A/D Channel Data Register: Contains the recent ADC value for respective channel
+
|P0.10 || 62 || GPIO || <b>TXD2</b> || SDA2|| MAT3[0]
 
|-
 
|-
|ADSTAT|| A/D Status Register: Contains DONE & OVERRUN flag for all the ADC channels
+
|P0.11 || 63 || GPIO || <b>RXD2</b> || SCL2|| MAT3[1]
|}
+
 
+
 
+
 
+
 
+
 
+
 
+
=ADC Register Configuration=
+
Now lets see how to configure the individual registers for ADC conversion.
+
=====ADCR ( ADC Control Register )=====
+
This registers contains the bits for channel selection, ADC conversion clock speed and Starting the conversion.
+
{| class="wikitable" style="text-align:center; background-color:#ABCDEF;margin: 1em auto 1em auto"
+
!colspan = '9'|ADCR
+
 
|-
 
|-
|31:28|| 27 || 26:24|| 23:22 ||   21  || 20:17 || 16|| 15:8 || 7:0 
+
|P0.0 || 82 || GPIO || CAN1_Rx|| <b>TXD3 </b>|| SDA1
 
|-
 
|-
|Reserved||EDGE||START||Reserved||   PDN || Reserved || BURST || CLCKDIV || SEL
+
|P0.1 || 85 || GPIO || CAN1_Tx|| <b>RXD3</b> || SCL1
 
|}
 
|}
 +
<br><br><br><br>
  
'''Bit 7:0 – SEL : Channel Select'''<br>
+
=UART Registers  =
These bits are used to select a particular channel for ADC conversion. One bit is allotted for each channel. Setting the Bit-0 will make the ADC to sample AD0[0] for conversion. Similary setting bit-7 will do the conversion for AD0[7].
+
The below table shows the registers associated with LPC1768 UART.<br>
 
+
{| class="table table-striped table-hover table-condensed table-bordered"
 
+
|-class="info"
'''Bit 15:8 – CLCKDIV : Clock Divisor'''<br>
+
!Register || Description
The APB clock (PCLK_ADC0) is divided by (this value plus one) to produce the clock for the A/D converter, which should be less than or equal to 13 MHz.
+
 
+
 
+
'''Bit 16 – BURST'''<br>
+
This bit is used for BURST conversion. If this bit is set the ADC module will do the conversion for all the channels that are selected(SET) in SEL bits. <br>
+
CLearing this bit will disable the BURST conversion.
+
 
+
 
+
'''Bit 21 – PDN : Power Down Mode'''<br>
+
Setting this bit brings ADC out of power down mode and makes it operational.<br>
+
Clearing this bit will power down the ADC.
+
 
+
 
+
'''Bit 24:26 – START'''<br>
+
When the BURST bit is 0, these bits control whether and when an A/D conversion is started:
+
{| class="wikitable" style="text-align:center; background-color:#C0C0C0;"
+
!Bit Value || FIFO Status
+
 
|-
 
|-
|000|| Conversion Stopped
+
|RBR|| Contains the recently received Data
 
|-
 
|-
|001|| Start Conversion Now
+
|THR|| Contains the data to be transmitted
|}
+
|-
The remaining cases (010 to 111) are about starting conversion on occurrence of  edge on a particular CAP or MAT pin.
+
|FCR|| FIFO Control Register
 
+
 
+
'''Bit 27 - EDGE'''<br>
+
This bit is significant only when the START field contains 010-111.
+
It starts conversion on selected CAP or MAT input.
+
{| class="wikitable" style="text-align:center; background-color:#C0C0C0;"
+
!Bit Value || Start Conversion
+
 
|-
 
|-
|0|| On Falling Edge
+
|LCR|| Controls the UART frame formatting(Number of Data Bits, Stop bits)
 
|-
 
|-
|1||On Rising Edge
+
|DLL|| Least Significant Byte of the UART baud rate generator value.
 
|-
 
|-
 +
|DLM|| Most Significant Byte of the UART baud rate generator value.
 
|}
 
|}
 +
<br><br>
  
 
+
=UART Register Configuration=
 
+
Now lets see how to configure the individual registers for UART communication.
=====ADGDR ( ADC Global Data Register )=====
+
==FCR ( FIFO Control Register )==
{| class="wikitable" style="text-align:center; background-color:#ABCDEF;margin: 1em auto 1em auto"
+
LPC1768 has inbuilt 16byte FIFO for Receiver/Transmitter. Thus it can store 16-bytes of data received on UART without overwriting. If the data is not read before the Queue(FIFO) is filled then the new data will be lost and the OVERRUN error bit will be set.
!colspan = '9'|ADCR
+
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
|FCR
 
|-
 
|-
|31|| 27 || 26:24|| 23:16|| 15:4 || 3:0   
+
|31:8|| 7:6 ||   5:4 || 3 || 2 || 1 || 0   
 
|-
 
|-
|DONE||OVERRUN||CHN || Reserved || RESULT|| Reserved
+
|RESERVED|| RX TRIGGER||   RESERVED  || DMA MODE || TX FIFO RESET  || RX FIFO RESET || FIFO ENABLE
 
|}
 
|}
  
'''Bit 15:4 - RESULT'''
+
'''Bit 0 – FIFO:'''<br>
This field contains the 12bit A/D conversion value for the selected channel in <b>ADCR.SEL</b><br>
+
This bit is used to enable/disable the FIFO for the data received/transmitted.<br>
The vale for this register should be read oncve the conversion is completed ie DONE bit is set.
+
0--FIFO is Disabled.<br>
 +
1--FIFO is Enabled for both Rx and Tx.<br>
 +
     
 +
'''Bit 1 – RX_FIFO:'''<br>
 +
This is used to clear the 16-byte Rx FIFO.<br>
 +
0--No impact.<br>
 +
1--CLears the 16-byte Rx FIFO and the resets the FIFO pointer.<br>
  
 +
'''Bit 2 – Tx_FIFO:'''<br>
 +
This is used to clear the 16-byte Tx FIFO.<br>
 +
0--No impact.<br>
 +
1--Clears the 16-byte Tx FIFO and the resets the FIFO pointer.<br>
  
'''Bit 26:24 - CHN : Channel'''<br>
+
'''Bit 3 – DMA_MODE:'''<br>
These bits contain the channel number for which the A/D conversion is done and the converted value is available in RESULT bits(e.g. 000 identifies channel 0, 011 channel 3...).
+
This is used for Enabling/Disabling DMA mode.<br>
 +
0--Disables the DMA.<br>
 +
1--Enables DMA only when the FIFO(bit-0) bit is SET.<br>
 +
 
 +
'''Bit 7:6 – Rx_TRIGGER:'''<br>
 +
This bit is used to select the number of bytes of the receiver data to be written so as to enable the interrupt/DMA.<br>
 +
00-- Trigger level 0 (1 character or 0x01)<br>
 +
01-- Trigger level 1 (4 characters or 0x04)<br>
 +
10-- Trigger level 2 (8 characters or 0x08)<br>
 +
11-- Trigger level 3 (14 characters or 0x0E)
 +
<br><br><br><br><br>
  
 +
==LCR ( Line Control Register )==
 +
This register is used for defining the UART frame format ie. Number of Data bits, STOP bits etc.
 +
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
|LCR
 +
|-
 +
|31:8|| 7 || 6 || 5:4 || 3 || 2 || 1:0 
 +
|-
 +
|Reserved|| DLAB ||  Break COntrol  || Parity Select || Parity Enable || Stop Bit Select || Word Length Select
 +
|}
 +
 +
'''Bit 1:0 – WLS : WordLenghtSelect'''<br>
 +
These two bits are used to select the character length<br>
 +
00-- 5-bit character length<br>
 +
01-- 6-bit character length<br>
 +
10-- 7-bit character length<br>
 +
11-- 8-bit character length<br>       
 +
 
 +
'''Bit 2 – Stop Bit Selection:'''<br>
 +
This bit is used to select the number(1/2) of stop bits <br>
 +
0-- 1 Stop bit<br>
 +
1-- 2 Stop Bits<br>
  
'''Bit 27 - OVERRUN'''<br>
+
'''Bit 3 – Parity Enable:'''<br>
This bit is set during the BURST mode where the previous conversion data is overwritten by the new A/D conversion value.
+
This bit is used to Enable or Disable the Parity generation and checking.<br>
 +
0-- Disable parity generation and checking.<br>
 +
1-- Enable parity generation and checking.<br>
 +
           
 +
'''Bit 5:4 – Parity Selection:'''<br>
 +
These two bits will be used to select the type of parity.<br>
 +
00-- Odd parity. Number of 1s in the transmitted character and the attached parity bit will be odd.<br>
 +
01-- Even Parity. Number of 1s in the transmitted character and the attached parity bit will be even.<br>
 +
10-- Forced "1" stick parity.<br>
 +
11-- Forced "0" stick parity <br>
 +
           
 +
'''Bit 6 – Break Control'''<br>     
 +
0-- Disable break transmission.<br>
 +
1-- Enable break transmission. Output pin UARTn TXD is forced to logic 0<br>
  
  
'''Bit 31 - DONE'''<br>
+
'''Bit 8 – DLAB: Divisor Latch Access Bit'''<br>
This bit is set to 1 when an A/D conversion completes. It is cleared when this register is read and when the ADCR is written. If the ADCR is written while a conversion is still in progress, this bit is set and a new conversion is started.
+
This bit is used to enable the access to divisor latch.<br>
 +
0-- Disable access to divisor latch<br>
 +
0-- Enable access to divisor latch
 +
<br><br><br><br><br>
  
====Some other registers====
+
==LSR (Line Status Register)==
Though there are some more registers, we are restricting ourselves to use these registers only as this will be more convenient.
+
The is a read-only register that provides status information of the UART TX and RX blocks.
 +
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
|LSR
 +
|-
 +
|31:8 || 7 || 6 || 5 || 4 || 3 || 2 || 1|| 0 
 +
|-
 +
|Reserved || RXFE || TEMT || THRE || BI  || FE || PE || OE || RDR
 +
|}
  
Apart from ADC Global Data register there are more 8 ADC Data registers (one Data register per ADC channel). DONE and OVERRUN bits for each channel can be monitored separately from the bits present in ADC Status register.
+
'''Bit 0 – RDR: Receive Data Ready'''<br>
 +
This bit will be set when there is a received data in RBR register. This bit will be automatically cleared when RBR is empty.<br>
 +
0-- The UARTn receiver FIFO is empty.<br>
 +
1-- The UARTn receiver FIFO is not empty.<br>
 +
   
 +
'''Bit 1 – OE: Overrun Error'''<br>
 +
The overrun error condition is set when the UART Rx FIFO is full and a new character is received.
 +
In this case, the UARTn RBR FIFO will not be overwritten and the character in the UARTn RSR will be lost.<br>
 +
0-- No overrun<br>
 +
1-- Buffer over run<br>
  
One can use the A/D Global Data Register to read all data from the ADC else use the A/D Channel Data
+
'''Bit 2 – PE: Parity Error'''<br>
Registers. It is important to use one method consistently because the DONE and OVERRUN flags can otherwise get out of synch between the AD0GDR and the A/D Channel Data Registers, potentially causing erroneous interrupts or DMA activity.
+
This bit is set when the receiver detects a error in the Parity.<br>   
 +
0-- No Parity Error<br>
 +
1-- Parity Error<br>
 +
   
 +
'''Bit 3 – FE: Framing Error'''<br>
 +
This bit is set when there is error in the STOP bit(LOGIC 0)<br>
 +
0-- No Framing Error<br>
 +
1-- Framing Error<br>
  
 +
'''Bit 4 – BI: Break Interrupt'''<br>
 +
This bit is set when the RXDn is held in the spacing state (all zeroes) for one full character transmission<br>
 +
0-- No Break interrupt<br>
 +
1-- Break Interrupt detected.<br>
  
 +
'''Bit 5 – THRE: Transmitter Holding Register Empty'''<br>
 +
THRE is set immediately upon detection of an empty THR. It is automatically cleared when the THR is written.<br>
 +
0-- THR register is Empty<br>
 +
1-- THR has valid data to be transmitted<br>
  
 +
'''Bit 6 – TEMT: Transmitter Empty'''<br>
 +
TEMT is set when both UnTHR and UnTSR are empty; TEMT is cleared when any of them contain valid data.<br>
 +
0-- THR and/or the TSR contains valid data.<br>
 +
1-- THR and the TSR are empty.<br> 
  
  
 +
'''Bit 7 – RXFE: Error in Rx FIFO'''<br>
 +
This bit is set when the received data is affected by Framing Error/Parity Error/Break Error.<br>
 +
0-- RBR contains no UARTn RX errors.<br> 
 +
1-- RBR contains at least one RX error.<br><br><br>
  
=Schematic=
+
==TER (Transmitter Enable register)==
[[File:Schematic LPC1768 ADC.svg|x500px|center|Schematic]]<br>
+
This register is used to Enable/Disable the transmission
 +
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
|TER
 +
|-
 +
|31:8|| 7 || 6-0 
 +
|-
 +
|Reserved|| TXEN || Reserved
 +
|}     
 +
     
 +
     
 +
'''Bit 7 – TXEN: Trsnamitter Enable<br>
 +
When this bit is 1, the data written to the THR is output on the TXD pin.<br>
 +
If this bit is cleared to 0 while a character is being sent, the transmission of that character is completed, but no further characters are sent until this bit is set again.<br> 
 +
In other words, a 0 in this bit blocks the transfer of characters.
 +
*Note: By default this bit will be set after Reset.<br><br><br>
  
 +
==Baudrate Calculation==
 +
LPC1768 generates the baud rate depending on the values of DLM,DLL.<br>
 +
<b>Baudrate = PCLK/ (16 * ( 256 * DLM + DLL) * (1+ DivAddVal/MulVal))</b><br>
  
 +
<b>Getting the PCLK value.</b><br>
 +
PCLKSELx registers contains the PCLK info for all the clock dependent peripherals in which Bit6,Bit7 contains the Uart Clock(ie.UART_PCLK) information.<br>
 +
The UART_PCLK and the actual Peripheral Clock(PCLK) is calculated as below.<br>
 +
(Refer data sheet for more info)
  
 +
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
|UART_PCLK  || PCLK
 +
|-
 +
|0|| SystemFreq/4
 +
|-
 +
|1|| SystemFreq
 +
|-
 +
|2|| SystemFreq/2
 +
|-
 +
|3|| SystemFreq/8
 +
|}
 +
 
 +
 +
DivAddVal/MulVal == 0
 +
       
 +
Using the above parameters , DLL/DLM is calculated as below.<br>
 +
<b>(256 * DLL + DLM) = PCLK / (16* Baudrate).</b><br><br><br>
  
 
=Steps for Configuring and Using the Adc=
 
Below are the steps for configuring the LPC1768 ADC.
 
#Step1: Configure the GPIO pin for ADC function using PINSEL register.
 
#Step2: Enable the CLock to ADC module.
 
#Step3: Deselect all the channels and Power on the internal ADC module by setting ADCR.PDN bit.
 
#Step4: Select the Particular channel for A/D conversion by setting the corresponding bits in ADCR.SEL
 
#Step5: Set the ADCR.START bit for starting the A/D conversion for selected channel.
 
#Step6: Wait for the conversion to complete, ADGR.DONE bit will be set once conversion is over.
 
#Step7: Read the 12-bit A/D value from ADGR.RESULT.
 
#Step8: Use it for further processing or just display on LCD.
 
  
  
 +
=Steps for Configuring UART0=
 +
Below are the steps for configuring the UART0.
 +
#Step1: Configure the GPIO pin for UART0 function using PINSEL register.
 +
#Step2: Configure the FCR for enabling the FIXO and Reste both the Rx/Tx FIFO.
 +
#Step3: Configure LCR for 8-data bits, 1 Stop bit, Disable Parity and Enable DLAB.
 +
#Step4: Get the PCLK from PCLKSELx register 7-6 bits.
 +
#Step5: Calculate the DLM,DLL vaues for required baudrate from PCLK.
 +
#Step6: Updtae the DLM,DLL with the calculated values.
 +
#Step6: Finally clear DLAB to disable the access to DLM,DLL.
 +
After this the UART will be ready to Transmit/Receive Data at the specified baudrate.<br>
  
 +
<b>Code sniffet:</b>
 +
<html>
 +
<script src="https://gist.github.com/Amritach/35437ef514c0ad0f9089.js"></script>
 +
</html>
 +
<br><br>
  
 +
=Steps for transmitting a char=
 +
#Step1: Wait till the previous char is transmitted ie. till THRE becomes high.
 +
#Step2: Load the new char to be transmitted into THR.<br>
 +
<b>Code snippet</b>
 +
<html>
 +
<script src="https://gist.github.com/Amritach/50b91b48e5722b03ad4c.js"></script>
 +
</html>
 +
<br><br>
  
 +
=Steps for Receiving a char=
 +
#Step1: Wait till the a char is received ie. till RDR becomes high.
 +
#Step2: Copy the received data from receive buffer(RBR).<br>
 +
<b>Code snippet</b>
 +
<html>
 +
<script src="https://gist.github.com/Amritach/c6b329d11c5406347279.js"></script>
 +
</html>
  
 
=Code=
 
=Code=
Here we are going to do the A/D conversion for only ADC[0]. The result of the A/D conversion will be displayed on the LCD.<br>
 
  
<syntaxhighlight>
 
#include<lpc17xx.h>
 
#include "lcd.h"        //ExploreEmbedded LCD library which contains the lcd routines
 
#include "delay.h"      //ExploreEmbedded delay library which contains the delay routines
 
       
 
/* Bit positions of ADCR and ADGR registers */
 
#define SBIT_BURST  16u
 
#define SBIT_START 24u
 
#define SBIT_PDN 21u
 
#define SBIT_EDGE 27u
 
#define SBIT_DONE 31u
 
#define SBIT_RESULT   4u
 
#define SBIT_CLCKDIV  8u
 
  
 +
===Example 1===
 +
Below is the code for transmitting and receiving chars at 9600 baud<br>
 +
<html>
 +
<script src="https://gist.github.com/SaheblalBagwan/dfa8847f40f1cf14f20fae2bb2a6d83c.js"></script>
 +
</html><br><br><br>
  
void main()
+
===Using Explore Embedded Libraries===
{
+
In the above tutorial we discussed how to configure and use the inbuilt LPC1768 UART.<br>
    uint16_t adc_result;
+
Now we will see how to use the ExploreEmbededd UART libraries to communicate on all the four UART channels.<br>
    SystemInit();                              //Clock and PLL configuration
+
For this you have to include the uart.c/uart.h files and associated gpio/stdutils files.<br>
  
  /* Setup/Map the controller pins for LCD operation
+
As LPC1768 has four inbuilt UART channels, the interfaces are suffixed with channel number as shown below.<br>
                            RS  RW  EN    D0    D1    D2      D3      D4    D5      D6    D7*/
+
UART0_Printf()<br>
    LCD_SetUp(P2_0,P2_1,P2_2,P1_20,P1_21,P1_22,P1_23,P1_24,P1_25,P1_26,P1_27);
+
UART1_Printf()<br>
 +
UART2_Printf()<br>
 +
UART3_Printf()<br>
  
  /* Specify the LCD type(2x16) for initialization*/
+
#Note:Refer the uart.h file for more info.
    LCD_Init(2,16);   
+
   
+
     
+
    LPC_SC->PCONP |= (1 << 12);      /* Enable CLOCK for internal ADC controller */
+
  
    LPC_ADC->ADCR = ((1<<SBIT_PDN) | (10<<SBIT_CLCKDIV));  //Set the clock and Power ON ADC module
+
<html>  
 +
<script src="https://gist.github.com/SaheblalBagwan/7db91d1895e3bfe9534c8f657af89a79.js"></script>
 +
</html>
  
    LPC_PINCON->PINSEL1|= 0x01<<14;      /* Select the P0_23 AD0[0] for ADC function */
+
=Testing=
  
   
+
==Using the Terminal Software==
 +
After generating the hex/bin file, flash it to the controller. Now connect the LPC1768 to your system using a Usb to Serial converter.
  
    while(1)
+
[[File:Lpc1768SerialConnection.JPG|x400px]]<br><br>
    {
+
       
+
        LPC_ADC->ADCR  |= 0x01;        /* Select Channel 0 by setting 0th bit of ADCR */
+
        DELAY_us(10);                  /* allow the channel voltage to stabilize*/
+
       
+
        util_BitSet(LPC_ADC->ADCR,SBIT_START);            /*Start ADC conversion*/
+
       
+
        while(util_GetBitStatus(LPC_ADC->ADGDR,SBIT_DONE)==0);  /* wait till conversion completes */
+
       
+
        adc_result = (LPC_ADC->ADGDR >> SBIT_RESULT) & 0xfff;  /*Read the 12bit adc result*/
+
       
+
        LCD_GoToLine(0);                      /* Go to First line of 2x16 LCD */
+
        LCD_Printf("Adc0: %4d",adc_result);  /* Display 4-digit adc result */ 
+
    }
+
}
+
</syntaxhighlight>  
+
  
 +
Open the terminal software , select the COM port, set baud rate and hit the connect button.
  
 +
<html>
 +
<img src=https://www.exploreembedded.com/wiki/images/8/8f/TerminalSetUp.png class="img-responsive">
 +
</html><br><br>
  
 +
==Using The Keil Simulator==
 +
Code can be tested on the Keil simulator as well. For this the target memory options needs to be set to default as shown below.
 +
<html>
 +
<img src=https://www.exploreembedded.com/wiki/images/d/d5/UartConfigOtpions.png class="img-responsive">
 +
</html>
  
  
  
=Using Explore Embedded Libraries=
 
In the above tutorial we discussed how to configure and use the inbuilt LPC1768 ADC.<br>
 
Now we will see how to use the exploreEmbededd ADC libraries and interface POT,LDR and Temperature Sensor(LM35).<br>
 
For this you have to include the adc.c/adc.h files. As the result will be displayed on the LCD, lcd.c/lcd.h also needs to be included.<br>
 
Refer the LCD tutorial for interfacing the 2x16 lcd.
 
<syntaxhighlight> 
 
#include<lpc17xx.h>
 
#include "lcd.h"    //User defined LCD library which contains the lcd routines
 
#include "delay.h"  //User defined library which contains the delay routines
 
#include "adc.h"
 
       
 
  
void main()
+
Now Rebuild the project and Run the code using the Keil simulator as shown below.
{
+
<html>
  uint16_t pot_value,ldr_value, temp_raw, temp_final;
+
<img src=https://www.exploreembedded.com/wiki/images/0/00/Lpc1768_Uart_Simulator.png class="img-responsive">
  float voltage;
+
</html>
    SystemInit();                              //Clock and PLL configuration
+
<br><br>
 
+
  /* Setup/Map the controller pins for LCD operation
+
              RS  RW  EN    D0    D1    D2  D3    D4  D5    D6    D7*/
+
    LCD_SetUp(P2_0,P2_1,P2_2,P1_20,P1_21,P1_22,P1_23,P1_24,P1_25,P1_26,P1_27);
+
  
 +
= Downloads=
 +
Download the complete project folder from the below link:
 +
https://codeload.github.com/ExploreEmbedded/Explore-Cortex-M3-LPC1768-Stick-DVB-14001/zip/master<br><br><br><br>
 
    
 
    
    LCD_Init(2,16);      /* Specify the LCD type(2x16) for initialization*/
+
Have a opinion, suggestion , question or feedback about the article let it out here!
    ADC_Init();          /* Initialize the ADC */
+
    while(1)
+
    {
+
        pot_value  = ADC_GetAdcValue(0); /* Read pot value connect to AD0(P0_23) */
+
        ldr_value  = ADC_GetAdcValue(1); /* Read LDR value connect to AD1(P0_24) */
+
        temp_raw  = ADC_GetAdcValue(2); /* Read Temp value connect to AD2(P0_25) */
+
 
+
    /*Converting the raw adc value to equivalent temperature with 3.3v as ADC reference using 12bit resolution.
+
            Step size of ADC= (3.3v/2^12)= 3.3/4096 = 0.0008056640625 = 0.0806mv
+
            For every degree celcius the Lm35 provides 10mv voltage change.
+
            1 degree celcius = 10mv = 10mv/0.0806mv = 12.41 uinits           
+
            Hence the Raw ADC value can be divided by 12.41 to get equivalent temp*/       
+
     
+
        temp_final = temp_raw/12.41;
+
 
+
        /* Vin = (Adc_value * REF)/ 2^12 */
+
        voltage = (pot_value * 3.3)/ 4096.0;
+
 
+
        LCD_GoToLine(0);
+
        LCD_Printf("P:%4d %f",pot_value,voltage);
+
        LCD_Printf("\nL:%4d T:%4d",ldr_value,temp_final);     
+
    }
+
}
+
 
+
</syntaxhighlight>
+
 
{{DISQUS}}
 
{{DISQUS}}

Latest revision as of 11:59, 27 July 2016

Objective

In this tutorial we are going to discuss the serial communication using UART.
For more info on UART/RS232 check 8051 tutorial.
LPC1768 has four inbuilt USARTs. We are going to discuss only UART0. After this tutorial you should be able to extend it to remaining three UARTS.
After understating the basics of LPC1768 UART module, We will discuss how to use the ExploreEmbedded libraries to communicate with any of the UART devices.



UART module

UART module and registers. LPC1768 has 4-UARTs numbering 0-3, similarly the pins are also named as RXD0-RXD3 and TXD0-TXD3.As the LPC1768 pins are multiplexed for multiple functionalities, first they have to be configured as UART pins.
Below table shows the multiplexed UARTs pins.

Port Pin Pin Number PINSEL_FUNC_0 PINSEL_FUNC_1 PINSEL_FUNC_2 PINSEL_FUNC_3
P0.02 98 GPIO TXD0 ADC0[7]
P0.03 99 GPIO RXD0 ADC0[6]
P2_0 48 GPIO PWM1[1] TXD1
P2.1 49 GPIO PWM1[2] RXD1
P0.10 62 GPIO TXD2 SDA2 MAT3[0]
P0.11 63 GPIO RXD2 SCL2 MAT3[1]
P0.0 82 GPIO CAN1_Rx TXD3 SDA1
P0.1 85 GPIO CAN1_Tx RXD3 SCL1





UART Registers

The below table shows the registers associated with LPC1768 UART.

Register Description
RBR Contains the recently received Data
THR Contains the data to be transmitted
FCR FIFO Control Register
LCR Controls the UART frame formatting(Number of Data Bits, Stop bits)
DLL Least Significant Byte of the UART baud rate generator value.
DLM Most Significant Byte of the UART baud rate generator value.



UART Register Configuration

Now lets see how to configure the individual registers for UART communication.

FCR ( FIFO Control Register )

LPC1768 has inbuilt 16byte FIFO for Receiver/Transmitter. Thus it can store 16-bytes of data received on UART without overwriting. If the data is not read before the Queue(FIFO) is filled then the new data will be lost and the OVERRUN error bit will be set.

FCR
31:8 7:6 5:4 3 2 1 0
RESERVED RX TRIGGER RESERVED DMA MODE TX FIFO RESET RX FIFO RESET FIFO ENABLE

Bit 0 – FIFO:
This bit is used to enable/disable the FIFO for the data received/transmitted.
0--FIFO is Disabled.
1--FIFO is Enabled for both Rx and Tx.

Bit 1 – RX_FIFO:
This is used to clear the 16-byte Rx FIFO.
0--No impact.
1--CLears the 16-byte Rx FIFO and the resets the FIFO pointer.

Bit 2 – Tx_FIFO:
This is used to clear the 16-byte Tx FIFO.
0--No impact.
1--Clears the 16-byte Tx FIFO and the resets the FIFO pointer.

Bit 3 – DMA_MODE:
This is used for Enabling/Disabling DMA mode.
0--Disables the DMA.
1--Enables DMA only when the FIFO(bit-0) bit is SET.

Bit 7:6 – Rx_TRIGGER:
This bit is used to select the number of bytes of the receiver data to be written so as to enable the interrupt/DMA.
00-- Trigger level 0 (1 character or 0x01)
01-- Trigger level 1 (4 characters or 0x04)
10-- Trigger level 2 (8 characters or 0x08)
11-- Trigger level 3 (14 characters or 0x0E)




LCR ( Line Control Register )

This register is used for defining the UART frame format ie. Number of Data bits, STOP bits etc.

LCR
31:8 7 6 5:4 3 2 1:0
Reserved DLAB Break COntrol Parity Select Parity Enable Stop Bit Select Word Length Select

Bit 1:0 – WLS : WordLenghtSelect
These two bits are used to select the character length
00-- 5-bit character length
01-- 6-bit character length
10-- 7-bit character length
11-- 8-bit character length

Bit 2 – Stop Bit Selection:
This bit is used to select the number(1/2) of stop bits
0-- 1 Stop bit
1-- 2 Stop Bits

Bit 3 – Parity Enable:
This bit is used to Enable or Disable the Parity generation and checking.
0-- Disable parity generation and checking.
1-- Enable parity generation and checking.

Bit 5:4 – Parity Selection:
These two bits will be used to select the type of parity.
00-- Odd parity. Number of 1s in the transmitted character and the attached parity bit will be odd.
01-- Even Parity. Number of 1s in the transmitted character and the attached parity bit will be even.
10-- Forced "1" stick parity.
11-- Forced "0" stick parity

Bit 6 – Break Control
0-- Disable break transmission.
1-- Enable break transmission. Output pin UARTn TXD is forced to logic 0


Bit 8 – DLAB: Divisor Latch Access Bit
This bit is used to enable the access to divisor latch.
0-- Disable access to divisor latch
0-- Enable access to divisor latch




LSR (Line Status Register)

The is a read-only register that provides status information of the UART TX and RX blocks.

LSR
31:8 7 6 5 4 3 2 1 0
Reserved RXFE TEMT THRE BI FE PE OE RDR

Bit 0 – RDR: Receive Data Ready
This bit will be set when there is a received data in RBR register. This bit will be automatically cleared when RBR is empty.
0-- The UARTn receiver FIFO is empty.
1-- The UARTn receiver FIFO is not empty.

Bit 1 – OE: Overrun Error
The overrun error condition is set when the UART Rx FIFO is full and a new character is received. In this case, the UARTn RBR FIFO will not be overwritten and the character in the UARTn RSR will be lost.
0-- No overrun
1-- Buffer over run

Bit 2 – PE: Parity Error
This bit is set when the receiver detects a error in the Parity.
0-- No Parity Error
1-- Parity Error

Bit 3 – FE: Framing Error
This bit is set when there is error in the STOP bit(LOGIC 0)
0-- No Framing Error
1-- Framing Error

Bit 4 – BI: Break Interrupt
This bit is set when the RXDn is held in the spacing state (all zeroes) for one full character transmission
0-- No Break interrupt
1-- Break Interrupt detected.

Bit 5 – THRE: Transmitter Holding Register Empty
THRE is set immediately upon detection of an empty THR. It is automatically cleared when the THR is written.
0-- THR register is Empty
1-- THR has valid data to be transmitted

Bit 6 – TEMT: Transmitter Empty
TEMT is set when both UnTHR and UnTSR are empty; TEMT is cleared when any of them contain valid data.
0-- THR and/or the TSR contains valid data.
1-- THR and the TSR are empty.


Bit 7 – RXFE: Error in Rx FIFO
This bit is set when the received data is affected by Framing Error/Parity Error/Break Error.
0-- RBR contains no UARTn RX errors.
1-- RBR contains at least one RX error.


TER (Transmitter Enable register)

This register is used to Enable/Disable the transmission

TER
31:8 7 6-0
Reserved TXEN Reserved


Bit 7 – TXEN: Trsnamitter Enable
When this bit is 1, the data written to the THR is output on the TXD pin.
If this bit is cleared to 0 while a character is being sent, the transmission of that character is completed, but no further characters are sent until this bit is set again.
In other words, a 0 in this bit blocks the transfer of characters.

  • Note: By default this bit will be set after Reset.


Baudrate Calculation

LPC1768 generates the baud rate depending on the values of DLM,DLL.
Baudrate = PCLK/ (16 * ( 256 * DLM + DLL) * (1+ DivAddVal/MulVal))

Getting the PCLK value.
PCLKSELx registers contains the PCLK info for all the clock dependent peripherals in which Bit6,Bit7 contains the Uart Clock(ie.UART_PCLK) information.
The UART_PCLK and the actual Peripheral Clock(PCLK) is calculated as below.
(Refer data sheet for more info)

UART_PCLK PCLK
0 SystemFreq/4
1 SystemFreq
2 SystemFreq/2
3 SystemFreq/8


DivAddVal/MulVal == 0

Using the above parameters , DLL/DLM is calculated as below.
(256 * DLL + DLM) = PCLK / (16* Baudrate).



Steps for Configuring UART0

Below are the steps for configuring the UART0.

  1. Step1: Configure the GPIO pin for UART0 function using PINSEL register.
  2. Step2: Configure the FCR for enabling the FIXO and Reste both the Rx/Tx FIFO.
  3. Step3: Configure LCR for 8-data bits, 1 Stop bit, Disable Parity and Enable DLAB.
  4. Step4: Get the PCLK from PCLKSELx register 7-6 bits.
  5. Step5: Calculate the DLM,DLL vaues for required baudrate from PCLK.
  6. Step6: Updtae the DLM,DLL with the calculated values.
  7. Step6: Finally clear DLAB to disable the access to DLM,DLL.

After this the UART will be ready to Transmit/Receive Data at the specified baudrate.

Code sniffet:

Steps for transmitting a char

  1. Step1: Wait till the previous char is transmitted ie. till THRE becomes high.
  2. Step2: Load the new char to be transmitted into THR.

Code snippet

Steps for Receiving a char

  1. Step1: Wait till the a char is received ie. till RDR becomes high.
  2. Step2: Copy the received data from receive buffer(RBR).

Code snippet

Code

Example 1

Below is the code for transmitting and receiving chars at 9600 baud



Using Explore Embedded Libraries

In the above tutorial we discussed how to configure and use the inbuilt LPC1768 UART.
Now we will see how to use the ExploreEmbededd UART libraries to communicate on all the four UART channels.
For this you have to include the uart.c/uart.h files and associated gpio/stdutils files.

As LPC1768 has four inbuilt UART channels, the interfaces are suffixed with channel number as shown below.
UART0_Printf()
UART1_Printf()
UART2_Printf()
UART3_Printf()

  1. Note:Refer the uart.h file for more info.

Testing

Using the Terminal Software

After generating the hex/bin file, flash it to the controller. Now connect the LPC1768 to your system using a Usb to Serial converter.

Lpc1768SerialConnection.JPG

Open the terminal software , select the COM port, set baud rate and hit the connect button.



Using The Keil Simulator

Code can be tested on the Keil simulator as well. For this the target memory options needs to be set to default as shown below.



Now Rebuild the project and Run the code using the Keil simulator as shown below.

Downloads

Download the complete project folder from the below link: https://codeload.github.com/ExploreEmbedded/Explore-Cortex-M3-LPC1768-Stick-DVB-14001/zip/master



Have a opinion, suggestion , question or feedback about the article let it out here!