Line 77: Line 77:
 
'''Bit 0 – FIFO:'''<br>  
 
'''Bit 0 – FIFO:'''<br>  
 
This bit is used to enable/disable the FIFO for the data received/transmitted.<br>
 
This bit is used to enable/disable the FIFO for the data received/transmitted.<br>
0-- FIFO is Disabled.<br>
+
0--FIFO is Disabled.<br>
1-- FIFO is Enabled for both Rx and Tx.<br>
+
1--FIFO is Enabled for both Rx and Tx.<br>
 
        
 
        
 
        
 
        
 
'''Bit 1 – RX_FIFO:'''<br>  
 
'''Bit 1 – RX_FIFO:'''<br>  
 
This is used to clear the 16-byte Rx FIFO.<br>
 
This is used to clear the 16-byte Rx FIFO.<br>
0- No impact.<br>
+
0--No impact.<br>
1- CLears the 16-byte Rx FIFO and the resets the FIFO pointer.<br>
+
1--CLears the 16-byte Rx FIFO and the resets the FIFO pointer.<br>
  
 
'''Bit 2 – Tx_FIFO:'''<br>
 
'''Bit 2 – Tx_FIFO:'''<br>
 
This is used to clear the 16-byte Tx FIFO.<br>
 
This is used to clear the 16-byte Tx FIFO.<br>
0- No impact.<br>
+
0--No impact.<br>
1- Clears the 16-byte Tx FIFO and the resets the FIFO pointer.<br>
+
1--Clears the 16-byte Tx FIFO and the resets the FIFO pointer.<br>
  
 
'''Bit 3 – DMA_MODE:'''<br>
 
'''Bit 3 – DMA_MODE:'''<br>
 
This is used for Enabling/Disabling DMA mode.<br>
 
This is used for Enabling/Disabling DMA mode.<br>
0- Disables the DMA.<br>
+
0--Disables the DMA.<br>
1-Enables DMA only when the FIFO(bit-0) bit is SET.<br>
+
1--Enables DMA only when the FIFO(bit-0) bit is SET.<br>
  
 
            
 
            
 
'''Bit 7:6 – Rx_TRIGGER:'''<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>
 
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>
+
00-- Trigger level 0 (1 character or 0x01)<br>
01 Trigger level 1 (4 characters or 0x04)<br>
+
01-- Trigger level 1 (4 characters or 0x04)<br>
10 Trigger level 2 (8 characters or 0x08)<br>
+
10-- Trigger level 2 (8 characters or 0x08)<br>
11 Trigger level 3 (14 characters or 0x0E)<br>
+
11-- Trigger level 3 (14 characters or 0x0E)<br>
  
 
=====ADGDR ( ADC Global Data Register )=====
 
=====ADGDR ( ADC Global Data Register )=====

Revision as of 13:04, 31 May 2015



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.00 75 GPIO PWM1[1] TXD1
P2.01 74 GPIO PWM1[2] RXD1
P0.10 48 GPIO TXD2 SDA2 MAT3[0]
P0.11 49 GPIO RXD2 SCL2 MAT3[1]
P4.28 82 GPIO RX_MCLK MAT2[0] TXD3
P4.29 85 GPIO TX_MCLK MAT2[1] RXD3



UART Registers

The below table shows the registers associated with LPC1768 ADC.
We are going to focus only on ADCR and ADGDR as these are sufficient for simple A/D conversion.
However once you are familer with LPC1768 ADC, you can explore the other features and the associated registers.

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 set.

ADCR
31:8 7:6 5:4 3 2 1 0
RESERVED RX TRIGGER RESERVED DMA MODE TX RIFO RESET RX RIFO 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)

ADGDR ( ADC Global Data Register )
ADCR
31 27 26:24 23:16 15:4 3:0
DONE OVERRUN CHN Reserved RESULT Reserved

Bit 15:4 - RESULT This field contains the 12bit A/D conversion value for the selected channel in ADCR.SEL
The vale for this register should be read oncve the conversion is completed ie DONE bit is set.


Bit 26:24 - CHN : Channel
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...).


Bit 27 - OVERRUN
This bit is set during the BURST mode where the previous conversion data is overwritten by the new A/D conversion value.


Bit 31 - DONE
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.

Some other registers

Though there are some more registers, we are restricting ourselves to use these registers only as this will be more convenient.

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.

One can use the A/D Global Data Register to read all data from the ADC else use the A/D Channel Data 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.

Schematic

Schematic



Steps for Configuring and Using the Adc

Below are the steps for configuring the LPC1768 ADC.

  1. Step1: Configure the GPIO pin for ADC function using PINSEL register.
  2. Step2: Enable the CLock to ADC module.
  3. Step3: Deselect all the channels and Power on the internal ADC module by setting ADCR.PDN bit.
  4. Step4: Select the Particular channel for A/D conversion by setting the corresponding bits in ADCR.SEL
  5. Step5: Set the ADCR.START bit for starting the A/D conversion for selected channel.
  6. Step6: Wait for the conversion to complete, ADGR.DONE bit will be set once conversion is over.
  7. Step7: Read the 12-bit A/D value from ADGR.RESULT.
  8. Step8: Use it for further processing or just display on LCD.




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.

#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
 
 
void main()
{
    uint16_t adc_result;
    SystemInit();                              //Clock and PLL configuration
 
   /* 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);
 
  /* Specify the LCD type(2x16) for initialization*/
    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
 
    LPC_PINCON->PINSEL1|= 0x01<<14;      	/* Select the P0_23 AD0[0] for ADC function */
 
 
 
    while(1)
    {
 
        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 */  
    }
}




Using Explore Embedded Libraries

In the above tutorial we discussed how to configure and use the inbuilt LPC1768 ADC.
Now we will see how to use the exploreEmbededd ADC libraries and interface POT,LDR and Temperature Sensor(LM35).
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.
Refer the LCD tutorial for interfacing the 2x16 lcd.

 
#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()
{
   uint16_t pot_value,ldr_value, temp_raw, temp_final;
   float voltage;
    SystemInit();                              //Clock and PLL configuration
 
   /* 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);
 
 
    LCD_Init(2,16);      /* Specify the LCD type(2x16) for initialization*/
    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);       
    }
}