You are on page 1of 48

Embedded Systems Lab Manual 18ECL66

ACHARYA INSTITUTE OF TECHNOLOGY


Department of Electronics & Communication Engineering

Embedded Systems Lab Manual


[18ECL66]
VI- SEMESTER ECE VTU 2018 CBCS Scheme

By
RAGHUNATH .B.H

Name of Student: _______________________________


USN: ____________________________________
SEC : ______________ Batch : _______________

Page 1
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Course Title Course Code Core/Elective Semester Year


Credits
Embedded Controller 18ECL66 CORE 2 6 2021-22
Lab Even

Contact Hours/ week Lecture Tutorials Practical


3 1 0 2

Name of the faculty RAGHUNATH.B.H


Designation and mail ID Assistant Professor
raghunath@acharya.ac.in
Department ECE

B) Course Related Specifics

Prerequisites for the Course Knowledge of Digital electronics,


(exemption from the prerequisites is Microprocessor Architecture and
provided only in exceptional Basics of ‘ C ’ Programming
circumstances)

1. Understand the architecture of ARM Cortex M3- LPC1768


Course Objectives microcontroller and assembly programming of ARM.
2. Learn to design, construct, Program, verify, analyze and troubleshoot
ARM assembly and C language programs and supporting hardware.

Syllabus :

PART-A: Conduct the following Study experiments to learn ALP using ARM Cortex M3
Registers using an Evaluation board and the required software tool.
1. ALP to multiply two 16 bit binary numbers.
2. ALP to find the sum of first 10 integer numbers.
3. ALP to find the number of 0’s and 1’s in 32 bit data.
4. ALP to determine whether the given 32 bit number is EVEN or ODD.
5. ALP to write data to RAM

PART-B: Conduct the following experiments on an ARM CORTEX M3 evaluation board


using evaluation version of Embedded 'C' & Keil Uvision-4 tool/compiler.

1. Display “Hello World” message using Internal UART.

2. Interface and Control a DC Motor.

3. Interface a Stepper motor and rotate it in clockwise and anti-clockwise direction.

4. Interface a DAC and generate Triangular and Square waveforms.

Page 2
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

5. Interface a 4x4 keyboard and display the key code on an LCD.

6. Demonstrate the use of an external interrupt to toggle an LED On/Off.

7. Display the Hex digits 0 to F on a 7-segment LED interface, with an appropriate delay in
between.

8. Measure Ambient temperature using a sensor and SPI ADC IC.

Cycle 1: PART-A Assembly Language Programming

1. ALP to multiply two 16 bit binary numbers.


2. ALP to find the sum of first 10 integer numbers.
3. ALP to find the number of 0’s and 1’s in 32 bit data.
4. ALP to determine whether the given 32 bit number is EVEN or ODD.
5. ALP to write data to RAM

Cycle 2: PART B- Interfacing Embedded C Programs

Embedded C Codes

1. Display “Hello world” message using internal UART


2. Interface and Control the speed of a DC Motor.
3. Interface a Stepper motor and rotate it in clockwise and anti-clockwise direction.
4. Interface a DAC and generate Triangular and Square waveforms.

Cycle : 3

5. Interface a 4x4 keyboard and display the key code on an LCD.


6.Demonstrate the use of an external interrupt to toggle an LED On/Off.
7.. Display the Hex digits 0 to F on a 7-segment LED interface, with an appropriate delay.
8. Measure Ambient temperature using a sensor and SPI ADC IC

Page 3
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

STEPS: FOR COMPLETE TUTORIAL CLICK AND WATCH https://youtu.be/wmWExarqfhA OR scan QR


Create new project in a new folder .
1. Open startup_LPC17xx.s file_in the project window
2. Comment 5 lines of it. i.e line # 127, 129, 130, 272 and 273 by putting ;
[semicolon] in the beginning of each line.
3. Right click on source group and select add new item to the source group
4. Select ASM file (.s) .

Program -1
AIM: Write an ALP to multiply two 16-bit numbers
Algorithm:

Step1: Load the first number into a register.

Step2: Load the second number into a register.

Step3: Multiply the numbers and store the result in a register.

Program:

;//Program to multiply two 16-bit data

AREA MULTIPLICATION, CODE, READONLY


EXPORT main

NUM1 DCD 0x5000


NUM2 DCD 0x4000
main

LDR R0, NUM1 ;Load Reg R0 with NUM1

LDR R1, NUM2 ;Load Reg R1 with NUM2

MUL R2, R1, R0 ;R2 = R1 x R0

LDR R3,= product ;Read the address of Product into R3

STR R2, [R3] ;Store the contents of R2 into Product location

AREA RESULT,DATA,READWRITE
product DCD 0

END
Expected Output:
Product = 1400 0000 H
Exercise: ALP to multiply two 32 bit numbers : https://youtu.be/7Xl_jRFiM5E

Page 4
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Program -2: ALP to find the sum of first 10 integer numbers.

AIM:Write an Assembly language program to calculate the sum and display the result for the
addition of first ten numbers. SUM = 10+9+8+.........+1

https://youtu.be/Cb5QPwSmUHI OR SCAN QR code

Algorithm:

Step1:Initialize the number of elements as count in an array.

Step2:Add the elements of the array and store carry if generated until count becomes 0.

Step3:Stop

Program:

;//Program for array addition

AREA SUMOFINT, CODE, READONLY

EXPORT __main

__main
MOV R0, #10 ;number of elements in an array

MOV R1, #00 ;Reg R1 is used to store sum. Initialise to 0


BACK ADD R1, R0 ;R1=R1+R0

SUBS R0, #1 ;Decrement R0 by 1

BNE BACK ;Branch to back if R0 is not equal to 0


LDR R2, = SUM ; load R2 with address of sum
STR R1, [R2] ;store R1 content into SUM location
STOP B STOP ; branch to label STOP
AREA RESULT, DATA, READWRITE

SUM DCD 0
END
Expected Output:
sum= 37H

Page 5
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Program -3

AIM: Write an ALP to find number of 0’s and 1’s in a given 16 bit number
AREA count01s, CODE, READONLY
EXPORT __main
NUM DCD 0x0099 ; NUM = 0000 0000 1001 1001 in binary
__main
MOV R0, #0 ; R0 is counter of 0s
MOV R1, #0 ; R1 is counter of 1s
MOV R3, #16 ; R3 is initialised to 16 . as num is 16 bit number
LDR R2, NUM ; Load reg R2 with original num 0099h
BACK LSRS R2, #1 ; logically shift Right side by 1 time to check C bit
BCS NEXT ; Branch to label NEXT if carry flag C is set[ i.e 1]
ADD R0, R0, #1 ; If not set increment zero counter by 1
B Skip ; branch to label skip
NEXT ADD R1, R1, #1 ; if C flag is set, increment 1s counter by 1
Skip SUB R3, R3, #1 ; decrement no of bits counter by 1
CMP R3, #0 ; compare reg R3 with 0
BNE BACK ; if R3 not equal to 0, branch to label BACk
END

Expected output: Given 16 bit number is 0099h = 0000 0000 1001 1001 b
No of zeros in Register R0 = 0C H = 12 in Decimal
No of Ones in Register R1 = 04
To check number of 0s and 1s in a given 32bit number check this video

https://youtu.be/kA6LsVF5zOU

Page 6
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Program-4

AIM: Write an Assembly language program to check if the given 32 bit number is odd or even. If
Even, store 0xEEEE in Reg R1, else store 0x1111 in Reg R1

Algorithm:

Step1: Initialize the number.

Step2: Logical Shift right by one bit. (moves LSB into carry).
Step3: Read the carry bit

Step4: If carry is set, the number is odd


Step5: If carry is zero, the number is even
Step6: Stop

Program:

;//Program for even or odd

AREA CODE1, CODE, READONLY


EXPORT main

NUM DCD 0x90 ;Initialize the number 1001 0000


main

LDR R0, NUM ; Load reg R0 with NUM


LSRS R0, #1 ; Logically shift Rightside by 1 time (checking LSB)
BCS NEXT ; branch to label NEXT if Carry flag C is set[ means 1]
MOV R1, #0xEEEE ; if C flag is 0 then store R1 with 0xEEEE to indicate as EVEN num
B STOP ; Branch to label STOP
NEXT MOV R1, #0x1111 ; if C = 1, store num 1111 in R1 to indicate num is ODD
STOP B STOP ; branch to label STOP
END

Output

R1 = 0xEEEE [even number]

https://youtu.be/Ppqesw7FmEg

Page 7
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Program #5: ALP to write data into RAM

AREA DATAWRITE, CODE, READONLY

EXPORT __main

DATA DCB 0x12345678

__main

LDR R0,DATA ; load R0 with DATA

LDR R1,=RAMLOC ; load R1 with address of RAMLOC

STR R0, [R1] ; write DATA into RAM location

AREA RAM, DATA, READWRITE

RAMLOC DCB 0x0

END

https://youtu.be/L4OwbI0xqxU

Output: RAMLOC = 12345678h

Augmented Syllabus
1 write an ALP to perform division operation

https://youtu.be/rvPslDqZLaA

2. write an ALP to transfer a block of DATA from one location to other location

https://youtu.be/NmkuXm0KEcw

3.Write an ALP to perform Addition/ 4. ALP to subtraction of two 32 bit numbers

https://youtu.be/7Xl_jRFiM5E https://youtu.be/C1Tebq5AXg4

Page 8
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

PART - B : Hardware Interfacing using


Embedded C Programs

Page 9
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Keil Micro Vision® 5 IDE Tool : Step by step Tutorial


Open Keil 5 IDE tool

Step 1. Open the Keil IDE, under main menu goto “Project -> New uVision Project…” and a window prompt
will open asking a name to save the new project. Type your desired project name and save.

Step 2. After that, a new window will appear as shown below. Make sure “Software Packs” is selected for the
1st drop down. In the search box below it, type “lpc1768” and then select the device from list below. Finally
click “OK”.

Page 10
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Step 3. Now, inside the “Manage Run-Time Environment Window” select the check boxes for “CORE” under
“CMSIS” and “Startup” under “Device”. If you want to select any other libraries you can do so by selecting
the respective checkboxes. Selecting “Startup” will automatically added all the necessary startup/boot files
required for LPC17xx device, so we don’t have to import them from external sources. The selection of
libraries can be changed any time later.

Step 4. Now click on “Options for Target” button as shown below:

Page 11
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Step 5. Now, click on the “Output” tab. If you want to generate hex file then you can check “Create HEX
File”.

Step 6. Then click on the “Linker” tab and Under that tab check the checkbox option which says “Use
Memory Layout from Target Dialog”.

Step 7.Now, under the “Debug” tab, change the values for “Dialog DLL” and “Parameter” under both
simulation and hardware debugger settings group. You can select “Use Simulator” to debug your code using

Page 12
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
simulator itself. If you are using JTAG programmer or any other hardware debugger supported by KEIL
then you can select it from top-right drop down box. We will see flashing and debugger options in detail in an
upcoming post. Finally to click “OK” to apply settings and close window.

Step 8. Now, in the source navigation pane on the left area, right click on “Source Group 1” and select
“Add New Item to Group ‘Source Group 1′”.

Page 13
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Step 10. Now you can write your code in the editor. To compile your program Press “F7” key or in the main
menu goto “Project->Build Target”. To check for any compilation errors you can have a look at the build
output at the bottom of main window. A screenshot of the Keil MDK uVision 5 is given below. The top red
box shows the Source Tree Navigation and the bottom red box shows the build output.

Step 11. To initiate a debug session using simulator or debug hardware/probe click “Debug->Start/Stop Debug
Session” or you can hit “Ctrl+F5” as shown below:

Now open the flash magic software and follow the below steps.

1. Select the Device as LPC1768 from Select Menu.


2. Select the COM Port. Check the device manager for detected COM port.

3. Select the Baud rate from 9600-115200. Ex: Set as 115200


4. Select None ISP Option.
5. Oscillator Freq in Mhz . Type 12 . i.e 12Mhz
6. Check the Erase all Flash + Code Rd Prot
7. Browse and Select the desired hex file. [project.hex file]
8. Press the Start Button to flash the hex file.

Page 14
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Register Configuration

LPC1768 has its GPIOs divided into five ports PORT0 - PORT4, although many of them are not physically
32bit wide. Refer the data sheet for more info. The Below registers will be used for Configuring and using the
GPIOs registers for sending and receiving the Digital signals. A structure LPC_GPIOn (where n= 0,1,2,3)
contains all the registers for required for GPIO operation. Refer lpc17xx.h file for more info on the registers.

LPC1768 GPIO
FIOSET, FIOCLR,
PINSEL FIODIR
FIOPIN
Selects Pin Function Configure Pin Direction Access the Port Pin

PINSEL: GPIO Pins Select Register Almost all the LPC1768 pins are multiplexed to support
more than 1 function. Every GPIO pin has a minimum of one function and max of four functions. The required
function can be selected by configuring the PINSEL register. As there can be up to 4 functions associated with
a GPIO pin, two bits for each pin are available to select the function. This implies that we need two PINSEL
registers to configure a PORT pins. By this the first 16(P0.0-P0.16) pin functions of PORT0 can be selected by
32 bits of PINSELO register. The remaining 16 bits(P0.16-P0.32) are configured using 32bits of PINSEL1
register. As mentioned earlier every pin has max of four functions. Below table shows how to select the function
for a particular pin using two bits of the PINSEL register.

Value Function Enumeration


Primary (default) function, typically GPIO
00 PINSEL_FUNC_0
port
01 First alternate function PINSEL_FUNC_1
10 Second alternate function PINSEL_FUNC_2
11 Third alternate function PINSEL_FUNC_3

FIODIR: Fast GPIO Direction Control Register.

This register individually controls the direction of each port pin.

Values Direction
0 Input
1 Output

FIOSET: Fast Port Output Set Register.

This register controls the state of output pins. Writing 1s produces highs at the corresponding port pins.
Writing 0s has no effect. Reading this register returns the current contents of the port output register not the
physical port value.

Values FIOSET
0 No Effect
1 Sets High on Pin

Page 15
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
FIOCLR: Fast Port Output Clear Register.

This register controls the state of output pins. Writing 1s produces lows at the corresponding port pins.
Writing 0s has no effect.

Values FIOCLR
0 No Effect
1 Sets Low on Pin

FIOPIN: Fast Port Pin Value Register .

Have a look at the diagram given below.

PINSEL0 Register

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

P0.15 P0.14 P0.13 P0.12 P0.11 P0.10 P0.9 P0.8 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0

PINSEL1
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
P0.31 P0.30 P0.29 P0.28 P0.27 P0.26 P0.25 P0.24 P0.23 P0.22 P0.21 P0.20 P0.19 P0.18 P0.17 P0.16

Example : Port 0.0 pin’s function is decided by contents of PINSEL0 register bit 0 and bit 1

P0.0 function decided by P0.0 Function as


PINSEL0.1 PINSEL0.0
0 0 when PINSEL0.1= 0 , PINSEL0.0= 0 Then P0.0 Function as General Purpose
I/O
0 1 when PINSEL0.1= 0, PINSEL0.0= 1 Then P0.0 Function as RD1
1 0 when PINSEL0.1= 1, PINSEL0.0= 0 Then P0.0 function as TXD3
1 1 when PINSEL0.1= 1, PINSEL0.0= 1 Then P0.0 function as SDA1

Since by default all pins are configured as GPIOs we don’t need to explicitly assign a ‘0’ value to PINSEL
register in Programming examples.

Page 16
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Example #1)

Configure Pin 4 of Port 0 i.e P0.4 as Output and SET it High (Logic 1)

LPC_GPIO0->FIODIR = 0x0000 0010; // in 32 bit form 0000 0000 0000 0000 0000 0000 0001 0000; 4th bit is 1

Port Number Pin number


Alternate way is
LPC_GPIO0->FIODIR = (1<< 4); // 1 in 32 bit binary form left shift by 4 times.
0000 0000 0000 0000 0000 0000 0000 0001 left shit by 4 times results as
0000 0000 0000 0000 0000 0000 0001 0000. which Configures P0.4 as Ouput
LPC_GPIO0->FIOSET = (1<< 4); // SET High for P0.4 pin

LPC_GPIO0->FIODIR = 0x0000 0010; // omitting left side zeros ; we can write as 0x10 ; x stands for Hexadecimal number

LPC_GPIO->FIODIR = 0x10; // Configure pin 4 of port 0 as Output


LPC_GPIO->FIOSET=0x10; //pin 4 of port 0 is made HIGH

Example #2

Configure Pin 17 of Port 1 [ P1.17] as output and then SET that Pin and CLEAR it:

LPC_GPIO1->FIODIR = (1<<17); // configuring 17th pin of port 1 [P1.17] as Output pin


LPC_GPIO1->FIOSET = (1<<17); // Output for P1.17 becomes High
LPC_GPIO1->FIOCLR = (1<<17); // Output for P1.17 becomes Low

Example #3) Configure Pin 3 and 5 of port 0 as output and SET them Logic High.

i.e Configuring P0.3 and P0.5 as Output and Setting them High:

LPC_GPIO0->FIODIR = (1<<3) | (1<<5) // 1 left shift 3 logically ORed with 1 left shift by 5
0000 0000 0000 0000 0000 0000 0000 1000 [ 1 << 3 ]
LOGIC OR with 0000 0000 0000 0000 0000 0000 0010 0000 [ 1 << 5 ]
0000 0000 0000 0000 0000 0000 0010 1000 3rd and 5th bits are 1. So P0.3 and P0.5 configures
as output
Alternate way is
LPC_GPIO0->FIODIR =0x0000 0028; // grouping above terms or we can also write as 0x28
LPC_GPIO0->FIOSET = (1<<3) | (1<<5) // Make ouput High for P0.3 and P0.5

Example #4)

Configuring 1st 8 Pins of Port 0 (P0.0 to P0.7) as Ouput and Setting them High:

LPC_GPIO0->FIODIR = 0x000000FF; // Config P0.0 to P0.7 as Ouput. 0000 0000 0000 0000 0000 1111 1111
LPC_GPIO0->FIOSET = 0x000000FF; // Make output High for P0.0 to P0.7

Example #5)

Configuring Pins of Port 0 (P0.4 to P0.11) as Output and Setting them High: and Low

LPC_GPIO0->FIODIR = 0xFF0; // Config P0.4 to P0.11 as Ouput. 0000 0000 0000 0000 0000 1111 1111 0000
LPC_GPIO0->FIOSET = 0xFF0; // 1111 1111 0000 Make output High for P0.4 to P0.11
LPC_GPIO0->FIOCLR = 0xFF0; // Make output LOW for P0.4 to P0.11

Example #6) Configuring Pins of Port 1 (P1.14 to P0.21) as Input :

LPC_GPIO1->FIODIR &= ~(0xFF0); // Config P1.14 to P1.21 as Input. ~ means complement


LPC_GPIO1->FIODIR &=~(1<<14); // only Pin p1.14 is configured as input

Note: On reset by default all registers are zero. So all port’s all the pins acts as input. We can skip setting i/p lines

Page 17
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

LPC1768: External Interrupts


EINTx Pins

LPC1768 has four external interrupts EINT0, EINT1, EINT2, EINT3.


As LPC1768 pins are multi functional, these four interrupts are available on multiple pins.
Below table shows mapping of EINTx pins.

EINT Registers

The registers associated with LPC1768 external interrupts.

Register Description

PINSELx To configure the pins as External Interrupts

Page 18
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

External Interrupt Flag Register contains interrupt flags for EINT0,EINT1, EINT2 &
EXTINT
EINT3.

EXTMODE External Interrupt Mode register(Level/Edge Triggered)

EXTPOLAR External Interrupt Polarity(Falling/Rising Edge, Active Low/High)

EXTINT

31:4 3 2 1 0

RESERVED EINT3 EINT2 EINT1 EINT0

EINTx: Bits will be set whenever the interrupt is detected on the particular interrupt pin.
If the interrupts are enabled then the control goes to ISR.
Writing one to specific bit will clear the corresponding interrupt.

EXTMODE

31:4 3 2 1 0

RESERVED EXTMODE3 EXTMODE2 EXTMODE1 EXTMODE0

EXTMODEx: This bits is used to select whether the EINTx pin is level or edge Triggered
0: EINTx is Level Triggered.
1: EINTx is Edge Triggered.

EXTPOLAR

31:4 3 2 1 0

RESERVED EXTPOLAR3 EXTPOLAR2 EXTPOLAR1 EXTPOLAR0

EXTPOLARx: This bits is used to select polarity(LOW/HIGH, FALLING/RISING) of the EINTx interrupt
depending on the EXTMODE register.

0: EINTx is Active Low or Falling Edge (depending on EXTMODEx).


1: EINTx is Active High or Rising Edge (depending on EXTMODEx).

Steps to Configure Interrupts

1. Configure the pins as external interrupts in PINSELx register.


2. Clear any pending interrupts in EXTINT.
3. Configure the EINTx as Edge/Level triggered in EXTMODE register.
4. Select the polarity(Falling/Rising Edge, Active Low/High) of the interrupt in EXTPOLAR register.
5. Finally enable the interrputs by calling NVIC_EnableIRQ() with IRQ number.

Page 19
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Expt No 1 . a. Demonstrate the use of an external interrupt EINT0 to toggle an LED -ON/OFF.

#include <lpc17xx.h>
void EINT0_IRQHandler(void)
{
LPC_SC->EXTINT = 1; //0000 0000 0000 0001, EXTINT pin0 is One. Clearing EXTINT0
LPC_GPIO0->FIOPIN ^ = (1<<4); /* Toggle the LED1 everytime INTR0 is generated */
}
int main( )
{
LPC_SC->EXTINT = 1; // 0000 0000 0000 0000 0000 0000 0000 0001 Clear EXTINT0
LPC_PINCON->PINSEL4 = (1<< 20); // PINSEL4 BIT NO 20 = 1 makes P2.10 function as EINT0
LPC_GPIO0->FIODIR = (1<<4); /* PORT 0 PIN 4 is configured as OUTPUT */
NVIC_EnableIRQ(EINT0_IRQn); /* Enable the EINT0 interrupts */
while(1)
{ // any main program running
}
}

Page 20
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
UART module : Universal Asynchronous Receiver and Transmitter

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.

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.
Page 21
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
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
Break Parity Stop Bit Word Length
Reserved DLAB Parity Select
Control Enable Select Select
Set as-> 1 0 00 0 0 11

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
1-- Enable access to divisor latch

Page 22
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

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

Page 23
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

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.

Page 24
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
After this the UART will be ready to Transmit/Receive Data at the specified baudrate.

Expt No 3 . Write embedded C program to display “Hello World” message using Internal UART.

#include "LPC17xx.h"

void UART0_Init (void)


{
//Make PINSEL 0.4 and PINSEL0.6 pins High
LPC_PINCON->PINSEL0 |= (1 << 4)| (1 << 6); // so Pin P0.2 used as TXD0 & Pin P0.3 used as RXD0 /
LPC_UART0->LCR = 0x83; /* 8 bits, no polarity, 1stop bit */
LPC_UART0->DLM = 0;
LPC_UART0->DLL = 9; // 115200 baus rate @25MHz clk
LPC_UART0->LCR = 0x03; /* Lock the baud rate */
LPC_UART0->FDR = 0x21; //MULVAL=2,DIVADDval=1
}

int UART0_SendChar (int Data)


{
while (!(LPC_UART0->LSR & 0x20)); //if LSR.5th bit =0 wait for valid data.
return (LPC_UART0->THR = Data); // LSR.5th bit =1 ,THR has valid data to be transmitted

void UART0_SendString (unsigned char *s)


{
while (*s != 0) // if content of string is not 0
UART0_SendChar(*s++); //send char and auto increment i.e s=s+1
}

int main(void)
{
char ch;
SystemInit( );
UART0_Init( ); //initialize UART0
UART0_SendString("hello world! "); //string=hello world!
}

Page 25
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

LPC1768 DAC

LPC1768/LPC1769 DAC Block

ARM Cortex-M3 LPC176x MCUs incorporate a 10 bit DAC and provide buffered analog output. As per the datasheet, it is
implemented as a string DAC which is the most simplest form of DAC consisting of 2 N resistors in series where N = no. of bits which
simply forms a Kelvin-Varley Divider. LPC176x DAC has only 1 output pin, referred to as AOUT. The Analog voltage at the output
of this pin is given as:

VAOUT = VALUE * (VREFP-VREFN)/ 1024

When we have VREFN = 0, the equation boils down to:

VAOUT = ( VALUE * VREFP)/1024

Where VALUE is the 10-bit digital value which is to be converted into its Analog counterpart and V REF is the input reference voltage.

Pins relating to LPC1768 DAC block:


Pin Description

AOUT Analog Output pin. Provides the converted Analog signal which is referenced to V SSA i.e.
(P0.26) the Analog GND. Set Bits[21:20] in PINSEL1 register to [10] to enable this function.

These are reference voltage input pins used for both ADC and DAC. V REFP is positive
VREFP, VREFN reference voltage and VREFN is negative reference voltage pin. In example shown below
we will use VREFN=0V(GND).

Page 26
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

VDDA is Analog Power pin and VSSA is Ground pin used to power the ADC module.
VDDA, VSSA
These are generally same as VCC and GND but with additional filtering to reduce noise.

DAC Registers in ARM Cortex-M3 LPC176x

The DAC module in ARM LPC1768/LPC1769 has 3 registers viz. DACR, DACCTRL, DACCNTVAL. In this
tutorial we will only go through to DACR register since the other two are related with DMA operation, explaining
which is not in the scope of this tutorial. Just note that DMA is used to update new values to DACR from memory
without the intervention of CPU. This is particularly useful when generation different types of waveforms using
DAC. We will cover this in another tutorial.

Also note that the DAC doesn’t have a power control it in PCONP register. Simply select the AOUT alternate function
for pin P0.26 using PINSEL1 register to enable DAC ouput.

The DACR register in LPC1768

The field containing bits [15:6] is used to feed a digital value which needs to be converted and bit 16 is used to
select settling time. The bit significance is as shown below:

1. Bit[5:0]: Reserved.
2. Bit[15:6] – VALUE starts from bit 6 [ In programming we use Value <<6; ]
3. Bit[16] – BIAS: Setting this bit to 0 selects settling time of 1us max with max current consumption of
700uA at max 1Mhz update rate. Setting it to 1 will select settling time of 2.5us but with reduce max
current consumption of 300uA at max 400Khz update rate.
4. Bits[31:17]: Reserved

LPC1768

Analog out
to CRO
DAC out

The total voltage provided by the DACOUT pin is function of binary number written on to bits 6 (D0) to bit 15(D9) of
DAC Register(DACR) and the reference voltage Vref(3.3V),it is as follows

𝑫𝟗 𝑫𝟖 𝑫𝟕 𝑫𝟔 𝑫𝟓 𝑫𝟒 𝑫𝟑 𝑫𝟐 𝑫𝟏 𝑫𝟎
Vout =Vref [
𝟐
+
𝟒
+
𝟖
+
𝟏𝟔
+
𝟑𝟐
+
𝟔𝟒
+
𝟏𝟐𝟖
+
𝟐𝟓𝟔
+
𝟓𝟏𝟐
+
𝟏𝟎𝟐𝟒
]
Where D0 is the LSB and D9 is MSB

Expt No 4 a .Interface a DAC and generate Triangular waveform.

Page 27
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
#include <LPC17xx.H
int main (void)
{
int i, m;

LPC_PINCON->PINSEL1 = (1<< 21); // make PINSEL1.21 pin high to Select AOUT function for P0.26

while(1)
{
for (i = 0; i <= 1023; i++) //send value start from 0 to 1023 insteps of 1
{
LPC_DAC->DACR = (i << 6) ; // DACR register value should placed in 15:6
for(m = 10; m > 1; m--) ; //delay to vary freq
}
for (i = 1023 ; i > 0; i - -) //once reaches max of 3.3v starts decreasing
{
LPC_DAC->DACR = (i << 6);
for(m = 10; m > 1; m--);
}
}

4.b. Interface a DAC and generate Square waveforms.


#include <LPC17xx.H>

int main (void)


{
int i;

LPC_PINCON->PINSEL1 = (1<<21) ; //Select AOUT function for P0.26

while (1)
{
LPC_DAC -> DACR = (1024 << 6); // 10bit = 1024 Vmax = 3.3 V
for (i = 120000; i > 1; i--); // maintain this value for some delay

LPC_DAC -> DACR = (512 << 6); // for Vmax/2 = 1.74V


for (i = 120000; i > 1; i--) ; // delay
}
}

Page 28
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

STEPPPER MOTOR INTERFACE

Stepper Motor Configuration:

A stepper motor is a special type of electric motor that moves in increments, or steps, rather than turning smoothly
as a conventional motor does. Typical increments are 0.9 or 1.8 degrees, with 400 or 200 increments thus
representing a full circle. The speed of the motor is determined by the time delay between each incremental
movement.

U8 is a Driver Buffer (ULN2003) device connected to LPC-1768 Device and can be used for driving Stepper Motor.
On the LPC-1768, P1.22 to P1.25 is used to generate the pulse sequence required to run the stepper Motor. Also,
the Stepper Motor is powered by its own power supply pin (COM), which is connected to a 12V supply. Table
shows connections for stepper Motor.

Stepper Motor Pin connection table.

Stepper LPC-1768 LPC-1768


Motor Coil Pin No Port No

A 39 P1.22
B 37 P1.23
C 38 P1.24
D 39 P1.25

P1.25 P1.24 P1.23 P1.22 Stepper motor


1 0 0 0 rotates Clockwise
0 1 0 0
0 0 1 0
0 0 0 1

P1.25 P1.24 P1.23 P1.22 Stepper motor rotates


0 0 0 1 Anti Clockwise
0 0 1 0
0 1 0 0
1 0 0 0

Page 29
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Expt No 5 .a. Interface a Stepper motor and rotate it in clockwise direction.

#include <LPC17xx.H>

int main (void)


{
unsigned int i, k, z;
LPC_GPIO1->FIODIR = (1<< 22)|(1<< 23)|(1<< 24)|(1<< 25); // P1.22 to P1.25 CONFIG AS O/P

while (1)
{
k = 1<< 25; // k = 0x02000000; //initially P.25 =1 [ 1000 ]
for(z=0; z<4; z++) // four coils to be made high one by one
{
LPC_GPIO1->FIOPIN =k; //Port1 pins assigned with Ka value
for ( i=120000; i >0 ; i - - ) ; // Delay , value of i decides speed of rotation.
k = k>>1; // k content rotate right 1 time. [0100] [0010] [0001]
}
}
}

Expt No 5.b. Interface a Stepper motor and rotate it in anti-clockwise direction.

#include <LPC17xx.H>

int main (void)


{
unsigned int i, k, z;
LPC_GPIO1->FIODIR = (1<< 22)|(1<< 23)|(1<< 24)|(1<< 25); // configure P1.22 to P1.25 as o/p,

while (1)
{
k = 1 << 22; //k =0x00400000; // initialize p1.22 as high [0001]
for(z=0; z < 4; z ++) // executes 4 times
{
LPC_GPIO1->FIOPIN =k; //port 1 pins assigned with k value
for (i=120000 ; i >0 ; i--) ; //delay
k = k<<1; // rotate left shift by 1 [0010] , [0100], [1000]
}
}
}

DC Motor Pin Configuration

DC (direct current) motor rotates continuously. It has two terminals positive and negative. Connecting DC
power supply to these terminals rotates motor in one direction and reversing the polarity of the power supply
reverses the direction of rotation.

U9 is L293 driver IC used to drive the dc motor. It has enable lines which is used to switch on the DC motor.
It is connected to P4.28. Logic ‘1’ enables the driver and logic ‘0’ disables the driver.P4.28 and P4.29 are
used for Motor 1 direction and speed control.

Page 30
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
DC Motor Pin connection table.

Motor Motor LPC-1768 LPC-1768


Selection Direction Pin No Port No
P4.28=1 &
Clockwise 82
P4.29=0
DCM0
85 P4.28=0 &
Anti clock
DCM1 P4.29=1
DCM_EN 65 P2.8=1

We can’t drive a dc motor directly through a microcontroller pin. It usually operates in 3.3v-5v and lower currents
but DC motor normally works in 6-12v, 300mA and it has other drawbacks like the back EMF produced by the DC
motor may harm the controller ports and damage them. The solution to the above problems is using motor driving
circuit usually known as H-Bridges. They are basically built using FETs and many dedicated ICs are also available
like L293D etc.

These are dual H-bridge motor drivers, i.e., by using one IC we can control two DC motors in both clock wise and
counter clockwise directions. The L293D can provide bidirectional drive currents of up to 60 0mA at voltages from
4.5 V to 36 V.

P4.28 P4.29 EN DC motor Action


0/1 0/1 0 Stop. Not enabled
1 0 1 Rotates Anticlockwise
0 1 1 Rotates Clockwise
1 1 1 Stop
0 0 1 Stop

Expt no 6 a .Interface and Control a DC Motor.


a. Anti Clock wise Direction

#include <lpc17xx.h>
int main()
{
LPC_GPIO2->FIODIR = (1<<8); //Configure the PORT2 pins as OUTPUT which enable DC motor
LPC_GPIO4->FIODIR = (1<<28) | (1<<29); //configure port4 pins p4.28,p4.29 as output by making 1

while(1)
{
LPC_GPIO2->FIOSET=(1<<8); //enable DC motor by making P2.8=1
LPC_GPIO4->FIOSET = (1<<28); // P4.28 =1
LPC_GPIO4->FIOCLR = (1<<29); // P4.29 = 0 DC motor Anti Clockwise rotation
}
}

Page 31
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

b. Clockwise Direction
#include <lpc17xx.h>
int main()
{
LPC_GPIO2->FIODIR = (1<<8); //Configure the PORT2 pins as OUTPUT
LPC_GPIO4->FIODIR = (1<<28) | (1<<29); //configure port4 pins p4.28,p4.29 as Input

while(1)
{
LPC_GPIO2->FIOSET = (1<<8); //enable DC motor by making P2.8=1
LPC_GPIO4->FIOCLR = (1<<28); // P4.28 = 0
LPC_GPIO4->FIOSET = (1<<29); // P4.29 =1 clockwise rotation
}
}

LED Pin Configuration

VTCM3_3board provides eight individual SMD led’s connected to LPC-1768 device through
74HC151driver IC. D1 to D8 are connected to general purpose I/O pins on LPC-1768 device as
shown in table(14) When LPC-1768 device drives Logic ‘1’ the corresponding LED turns on.

LED Pin connection table.

LED D1 D2 D3 D4 D5 D6 D7 D8
LPC-1768
81 80 79 78 77 76 48 49
Pin No
LPC-1768
P0.4 P0.5 P0.6 P0.7 P0.8 P0.9 P0.10 P0.11
Port No

Page 32
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
SEVEN SEGMENT DIPLAY Pin Configuration:

D11, D12, D13 and D14 are Common Cathode segments connected to LPC-1768 device so that each
segment is individually controlled by a general purpose I/O pin. When the LPC-1768 device drives
logic ‘0’ the corresponding segment turns on. See fig and table for more details.

D9 D10 D11 D12


Seven Segment Pin connection table.

Seven Segment
g f a b p c d e
Data Lines
LPC-1768 Pin No 75 74 73 70 69 68 67 66

LPC-1768 Port No P2.0 P2.1 P2.2 P2.3 P2.4 P2.5 P2.6 P2.7

SEVEN SEGMENT Selection Pin Configurations:

As VTCM3_3 board comes with 4 digit seven segment unit. Displays connected to the microcontroller
usually occupy a large number of valuable I/O pins, which can be a big problem especially if it is
needed to display multi digit numbers. The problem is more than obvious if, for example, it is needed
to display four digit numbers (a simple calculation shows that 32 output pins are needed in this case).
The solution to this problem is called MULTIPLEXING. This is how an optical illusion based on the
same operating principle as a film camera is made. Only one digit is active at a time, but they change
their state so quickly making impression that all digits of a number are simultaneously active. Each
digit can made active using switching transistors Q1, Q2, Q3 and Q4 and these on switched on and off
by selection lines which are in turn connected to LPC-1768 ports. Table shows the details of seven

segment selection lines.

Seven Segment Disp1 Disp2 Disp3 Disp4


Selection Lines (D9) (D10) (D11) (D12)
LPC-1768 Pin No 40 43 44 45
LPC-1768 Port No P1.26 P1.27 P1.28 P1.29

Page 33
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Digits to
Display Segments Hex code
display

g f a b p c d e CODE
0 1 0 0 0 1 0 0 0 88
1 1 1 1 0 1 0 1 1 EB
2 0 1 0 0 1 1 0 0 4C
3 0 1 0 0 1 0 0 1 49
4 0 0 1 0 1 0 1 1 2B
5 0 0 0 1 1 0 0 1 19
6 0 0 0 1 1 0 0 0 18
7 1 1 0 0 1 0 1 1 CB
8 0 0 0 0 1 0 0 0 08
9 0 0 0 0 1 0 0 1 09
A 0 0 0 0 1 0 1 0 0A
B 0 0 1 1 1 0 0 0 38
C 1 0 0 1 1 0 0 0 98
D 0 1 1 0 1 0 0 0 68
E 0 0 0 1 1 1 0 0 1C
F 0 0 0 1 1 1 1 0 1E

Page 34
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Expt no 7. Display the Hex digits 0 to F on a 7-segment LED interface, with an appropriate delay in
between.

#include <LPC17xx.H>
unsigned char data7seg[] = {0x88,0xeb,0x4c,0x49,0x2b,0x19,0x18,0xcb,0x8,0x9,0xa,0x38,0x9C,0x68,
0x1c,0x1e};
int main (void)
{
unsigned int i, j;
unsigned int count=0; // initially count=0;
LPC_GPIO2->FIODIR = 0x000000FF; // Seven seg on PORT2 p2.0 to p2.7 are output
LPC_GPIO1->FIODIR = (1<< 26) ; //configure PORT1 p1.26 as output

while(1)
{
if (count > 0xF) count = 0; // if count Greater than F, re initialize to 0
for (i=0; i < 20000; i++) //change to inc/dec speed of count
{
LPC_GPIO2->FIOPIN = data7seg[count]; // & 0x000F];
LPC_GPIO1->FIOSET = (1<<26); // 26 for first Sev segment , 27 for second
for (j=0; j<1000; j++); //change to inc/dec brightness of display
LPC_GPIO1->FIOCLR = (1<<26);
}
Count++; //count = count+1
}
}

Page 35
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

16 X 2 LCD Display
An LCD display is specifically manufactured to be used with microcontrollers, which means that it
cannot be activated by standard IC circuits. It is used for displaying different messages on a miniature
liquid crystal display. It displays all the letters of alphabet, Greek letters, punctuation marks,
mathematical symbols etc. In addition, it is possible to display symbols made up by the user. Other
useful features include automatic message shift (left and right), cursor appearance, LED backlight etc.

There are pins along one side of a small printed board. These are used for connecting to the
microcontroller. There are in total of 14 pins marked with numbers (16 if it has backlight). Their
function is described in the table below:

LCD Pin Configuration


LPC- LPC-
LCD
LCD Pin 1768 1768
Pin
Functions Pin Port
No
No No
1 GND - -
2 VCC - -
3 - -
4 RS 24 P2.28
5 R/W GND GND
6 EN 27 P2.27
7 DAT1 75 P2.0
8 DAT2 74 P2.1
9 DAT3 73 P2.2
10 DAT4 70 P2.3
11 DAT5 69 P2.4
12 DAT6 68 P2.5
13 DAT7 67 P2.6
14 DAT8 66 P2.7
15 VCC - -
16 GND - -

Page 36
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

8) Interface LCD with 1768 and write a Program to display Message on


LCD screen.
#include <LPC17xx.h>
#define LCD_RS (1<<28)
#define LCD_EN (1<<27)

void LCD_Command(unsigned char cmd)


{
LPC_GPIO2->FIOPIN = cmd ;
LPC_GPIO0->FIOCLR |= LCD_RS; // RS=0
LPC_GPIO0->FIOSET |= LCD_EN; // EN=1
for(int k=0;k<100000;k++); // delay
LPC_GPIO0->FIOCLR |= LCD_EN; //EN=0
}

void LCD_Data(unsigned char data)


{
LPC_GPIO2->FIOPIN = data;
LPC_GPIO0->FIOSET |= LCD_RS; // RS=1
LPC_GPIO0->FIOSET |= LCD_EN; //EN=1
for(int j=0;j<100000;j++); // delay
LPC_GPIO0->FIOCLR |= LCD_EN; // EN=0
}

void LCD_Init(void)
{
LPC_GPIO0->FIODIR |= (LCD_RS | LCD_EN); // EN and Read Select Pins are configured as o/p
LPC_GPIO2->FIODIR0 = 0x00FF; // Config P2.0 to P2.7 as o/p pins
LCD_Command(0x38); // 8 bits, 2 lines, 5x7 Dots
LCD_Command(0x01); // Clear Display screen
LCD_Command(0x0e); // Display on & cursor On
}

int main()
{
unsigned char str[]={"Acharya "};
unsigned int x=0; // initialize x=0
LCD_Init();
LCD_Command(0x80); // Force cursor to beginging of I row, [ 0xc0 for II row]
while(str[x] != '\0') // if content of str in not a null char
{
LCD_Data(str[x]); // send to LCD as Data

x++; //increment x
}
}

Page 37
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

11 .a) Interface a 4x4 keyboard and display the key code on an LCD.

#include <LPC17xx.H>
#include "lcd.h"

void col_write( unsigned char data )


{
LPC_GPIO1->FIOSET |= (data << 14) & (1<<14 | 1<<15 | 1<<16 | 1<<17);
}

int main (void)


{
unsigned char key, i;
unsigned char rval[] = {0x7,0xB,0xD,0xE}; // to make one coloumn low 0111, 1011, 1101, 1110
unsigned char keyPadMatrix[ ] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

init_lcd();

LPC_GPIO1->FIODIR = (1<<14 | 1<<15 | 1<<16 | 1<<17); //Set COLs as Outputs

lcd_putstring16(0,"Press HEX_KeyBoard..");
lcd_putstring16(1,"Key Pressed = ");

while (1)
{
key = 0;
for( i = 0; i < 4; i++ )
{
LPC_GPIO1->FIOCLR |= (1<<14 | 1<<15 | 1<<16 | 1<<17);
col_write(rval[i]); // turn on COL output one by one
if (!(LPC_GPIO1->FIOPIN & 1<<21)) // read rows - break when key press detected
break;
key++;
if (!(LPC_GPIO1->FIOPIN & 1<<20))
break;
key++;
if (!(LPC_GPIO1->FIOPIN & 1<<19))
break;
key++;
if (!(LPC_GPIO1->FIOPIN & 1<<18))
break;
key++;
}
if (key == 0x10) // if no key pressed key++ increments upto 16 i.e 0x10
lcd_putstring16(1,"Key Pressed = ");
else
{
lcd_gotoxy(1,14);
lcd_putchar(keyPadMatrix[key]);
}
}
}

Page 38
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
HEX KEY PAD Pin configurations:

The hex keypad is a peripheral that is organized in rows and Columns. Hex key Pad 16 Keys arranged in a 4
by 4 grid, labeled with the hexadecimal digits 0 to F. An example of this can been seen in Figure 1, below.
Internally, the structure of the hex keypad is very simple. Wires run in vertical columns (we call them C0 to
C3) and in horizontal rows (called R0 to R3). These 8 wires are available externally, and will be connected to
the lower 8 bits of the port. Each key on the keypad is essentially a switch that connects a row wire to a column
wire. When a key is pressed, it makes an electrical connection between the row and column. Table shows
connections for HEX KEY Pad matrix.

HEX KEY Pad matrix table.

ROW/COLOUMNS R1 R2 R3 R4 C1 C2 C3 C4
LPC-1768 Pin No 32 33 34 35 89 88 87 86
LPC-1768 Port No P1.18 P1.19 P1.20 P1.21 P1.14 P1.15 P1.16 P1.17

Page 39
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Expt no 11. Measurement of ambient temperature using a sensor and SPI ADC IC.
#include <LPC17xx.H>
#include <stdio.h>
#include "lcd.h"
#include "spi.h"

int main (void)


{
int msb,lsb;
int ADCValue;
float temp;
char lstr[10];

SPI_Init();
init_lcd();

lcd_putstring16(0,"TEMP = 000 Deg_C");

while(1)
{
SPI_EnableChipSelect();
delay(1);
SPI_Write(0x01);
msb = SPI_Write(0xA0); // SGL=1, ODD=0, MSBF=1
lsb = SPI_Write(0x00);

SPI_DisableChipSelect();
msb &= 0x0F;
ADCValue = (msb << 8) | lsb;

temp = ((ADCValue * 3.3) / 4096) * 100;


sprintf (lstr, "%0.1f", temp);
lcd_gotoxy(0,7);
lcd_putstring(lstr);

delay(500);
}
}

Vref =3.3V
LM35

1 2 3

5V

ADC1
75E

LPC1768
1µf

Page 40
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

Appendix
: Following supporting files will be provided in the exam. Add these files in the same folder where the
project is created.

Spi.c file

#include <lpc17xx.h>
#include "spi.h"

uint8_t dummy_u8;
static uint32_t spi_GetPclk(void);
void SPI_Init(void)
{
LPC_PINCON->PINSEL0 |= 0xC0000000; //SCK
LPC_PINCON->PINSEL1 |= 0x0000003C; //SSEL, MISO, MOSI

LPC_GPIO0->FIODIR |= 0x00058000; //SSEL, MOSI, SCK are Outputs 15,16,18


LPC_GPIO0->FIODIR &= ~0x00020000; //MISO is Input 17

SPI_DisableChipSelect(); // Disable the Slave Select

LPC_SC->PCONP |= (1 << 8); // enable power to spi clock

LPC_SPI->SPCCR = spi_GetPclk()/SCK_Freq; // Set Spi Clock

LPC_SPI->SPCR = ((0<<SBIT_CPHA) | (0<<SBIT_CPOL) | (1<<SBIT_MSTR));

dummy_u8 = LPC_SPI->SPSR; /* Dummy read to clear the flags */


dummy_u8 = LPC_SPI->SPDR; /* Dummy read to clear the flags */
}

uint8_t SPI_Write (uint8_t spiData_u8)


{
LPC_SPI->SPDR = spiData_u8;
dummy_u8 = 0;
while(dummy_u8 == 0)
{
dummy_u8 = LPC_SPI->SPSR & 0x80; } // wait until data is sent
dummy_u8 = LPC_SPI->SPSR;
spiData_u8 = (uint8_t)LPC_SPI->SPDR;
return spiData_u8;
}

static uint32_t spi_GetPclk(void)


{
uint32_t v_spiPclk_u32,v_Pclk_u32;
v_spiPclk_u32 = (LPC_SC->PCLKSEL0 >> 16) & 0x03;
switch( v_spiPclk_u32 )
{
case 0x00:
v_Pclk_u32 = SystemCoreClock/4; //SystemFrequency or SystemCoreClock
break;
case 0x01:
v_Pclk_u32 = SystemCoreClock;
break;

Page 41
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
case 0x02:
v_Pclk_u32 = SystemCoreClock/2;
break;
case 0x03:
v_Pclk_u32 = SystemCoreClock/8;
break;
}
return (v_Pclk_u32);
}

lcd.c file

#include <LPC17xx.H> /* NXP LPC17xx definitions */


#include "lcd.h"

void delay(unsigned int count)


{
unsigned int j=0,i=0;

for(j=0;j<count;j++)
{
for(i=0;i<12000;i++);
}
}

void lcd_command_write( unsigned char command )


{

//LCD_DATA_SET |= (command & LCD_DATA_MASK);


LCD_DATA_SET = command;

LCD_CTRL_CLR |= LCDRS;
LCD_CTRL_SET |= LCDEN;
delay(1);
LCD_CTRL_CLR |= LCDEN;
delay(1);
}

void lcd_data_write( unsigned char data )


{
//LCD_DATA_SET = (data & LCD_DATA_MASK);
LCD_DATA_SET = data;

LCD_CTRL_SET |= LCDRS;
LCD_CTRL_SET |= LCDEN;
delay(1);
LCD_CTRL_CLR |= LCDEN;
delay(1);
}
Page 42
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

void lcd_clear( void)


{
lcd_command_write( 0x01 );
}

int lcd_gotoxy( unsigned char x, unsigned char y)


{
unsigned char retval = TRUE;

if( (x > 1) && (y > 15) )


{
retval = FALSE;
}
else
{
if( x == 0 ) lcd_command_write( 0x80 + y );
else if( x==1 ) lcd_command_write( 0xC0 + y );
}
return retval;
}

void lcd_putchar( unsigned char c )


{
lcd_data_write( c );
}

void lcd_putstring( char *string )


{
while(*string != '\0')
{
lcd_putchar( *string );
string++;
}
}

void lcd_putstring16( unsigned char line, char *string )


{
unsigned char len = 16;

lcd_gotoxy( line, 0 );
while(*string != '\0' && len--)
{
lcd_putchar( *string );
string++;
}
}

Page 43
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
void init_lcd( void )
{
SEG_CTRL_DIR |= SEG_DIG_MASK; //switch off 7-seg
SEG_CTRL_SET &= ~SEG_DIG_MASK; //switch off 7-seg

LPC_GPIO0->FIODIR |= 0x00000FF0; /* LEDs on PORT0 are output */


LPC_GPIO0->FIOPIN &= ~0x00000FF0; /* LEDs off */

LCD_CTRL_DIR |= ( LCDEN | LCDRS );


LCD_DATA_DIR = LCD_DATA_MASK;

delay(1000);
lcd_command_write(0x38); /* 8-bit interface, two line, 5X7 dots. */
lcd_command_write(0x38);
lcd_command_write(0x38);
lcd_command_write(0x10); /* display shift */
lcd_command_write(0x0C); /* display on */
lcd_command_write(0x06) ; /* cursor move direction */
lcd_command_write(0x01) ; /* cursor home */
delay(1000);
}

spi.h file

#ifndef _SPI_H_
#define _SPI_H_

#define MOSI_PIN P0_18


#define MISO_PIN P0_17
#define SSEL_PIN P0_16
#define SCK_PIN P0_15
#define SPI_FUNCTION PINSEL_FUNC_3
#define SCK_Freq 4000000 // SPI clock frequency
#define SBIT_CPHA 3
#define SBIT_CPOL 4
#define SBIT_MSTR 5
#define SBIT_LSBF 6
#define SBIT_SPIE 7
#define SBIT_SPIF 7

void SPI_Init(void);
uint8_t SPI_Write (uint8_t var_data_u8);
#define SPI_EnableChipSelect() LPC_GPIO0->FIOCLR |= (1 << 16);
#define SPI_DisableChipSelect() LPC_GPIO0->FIOSET |= (1 << 16);

#endif

Page 44
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

lcd.h file

#ifndef _LCD_H
#define _LCD_H

#define TRUE 1
#define FALSE 0

#define LINE1 0x80


#define LINE2 0xC0

#define CONTROL_REG 0x00


#define DATA_REG 0x01

#define LCD_DATA_DIR LPC_GPIO2->FIODIR0


#define LCD_DATA_SET LPC_GPIO2->FIOPIN0
#define LCD_CTRL_DIR LPC_GPIO0->FIODIR
#define LCD_CTRL_SET LPC_GPIO0->FIOSET
#define LCD_CTRL_CLR LPC_GPIO0->FIOCLR

#define SEG_DATA_DIR LPC_GPIO2->FIODIR


#define SEG_DATA_SET LPC_GPIO1->FIOPIN
#define SEG_CTRL_DIR LPC_GPIO1->FIODIR
#define SEG_CTRL_SET LPC_GPIO1->FIOPIN

#define LCDEN (1 << 27)


#define LCDRS (1 << 28)

//scale
31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
#define LCD_DATA_MASK 0x000000FF
#define SEG_DIG_MASK 0x0F000000

void delay(unsigned int count);


void init_lcd(void);
void lcd_putstring(char *string);
void lcd_putstring16(unsigned char line, char *string);
void lcd_clear(void);
int lcd_gotoxy(unsigned char x, unsigned char y);
void lcd_putchar(unsigned char c);

#endif

Page 45
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

ARM Cortex M3 Series: An Introduction

Brief History
ARM was founded in 1990 as Advanced RISC Machines Ltd., a joint venture of Apple Computer,
Acorn Computer Group, and VLSI Technology. In 1991, ARM introduced the ARM6 processor
family, and VLSI became the initial licensee. Subsequently, additional companies, including Texas
Instruments, NEC, Sharp and ST Microelectronics, licensed the ARM processor designs. Nowadays
ARM partners ship in excess of 2 billion ARM processors each year. Unlike many semiconductor
companies, ARM does not manufacture processors or sell the chips directly. Instead it licenses the
processor designs to business partners. This business model is commonly called intellectual
property (IP) licensing.

Architecture Versions
Over the years, ARM has continued to develop new processors and system blocks. These include
the popular ARM7TDMI processors, more recently the ARM11 processor family and latest being the
ARM Cortex Processor family. Table 2.1 summarizes the various architecture versions and
processor families.

Architecture Processor Family


ARMv1 ARM1
ARMv2 ARM2, ARM3
ARMv3 ARM6, ARM7
ARMv4 StrongARM, ARM7TDMI, ARM9TDMI
ARMv5 ARM7EJ, ARM9E, ARM10E, XScale
ARMv6 ARM11, ARM Cortex –M
ARMv7 ARM Cortex-A, ARM Cortex-R, ARM Cortex-M

Page 46
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66

ARM Cortex Processor Profiles


In the ARMv7 architecture the design is divided into three profiles –
1. A Profile (ARMv7-A) - is designed for high performance open application platforms. They can
handle complex applications such as high end embedded operating systems.
Example products include high-end smartphones, tablet PCs and PDAs.

2. R Profile (ARMv7-R) - is designed for high end embedded systems in which real time
performance is needed. Example applications include high-end car braking systems.

3. M-Profile (ARMv7-M) – is designed for deeply embedded microcontroller type systems.


Processors belonging to this profile are the subject for this manual and are studied in greater detail.

Evolution of the ARM Instruction Set


Enhancement and extension of instruction sets used by the ARM processors has been one of the
key driving forces of the architecture’s evolution. Historically, two different instruction sets were
supported on the ARM processor: the ARM instructions, which are 32 bits and Thumb instructions,
which are 16 bits. During program execution, the processor can be dynamically switched between
the ARM state and the Thumb state. The Thumb instruction set provides only a subset of the ARM
instructions, but it can provide higher code density. It is useful for products with tight memory
requirements.
The Thumb-2 technology extended the Thumb Instruction Set Architecture (ISA) into a highly
efficient and powerful instruction set that delivers significant benefits in terms of ease of use, code
size and performance. The extended instruction set in Thumb-2 is a superset of the previous 16-bit
Thumb instruction set, with additional 16-bit instructions alongside 32-bit instructions. It allows
more complex operations to be carried out in the Thumb state, thus allowing higher efficiency by
reducing the number of states switching between ARM state and Thumb state.
The Cortex-M3 processor supports only the Thumb-2 (and traditional Thumb) instruction
set. Instead of using ARM instructions, as in traditional ARM processors, it uses Thumb-2
instruction set for all operations. As a result, the Cortex-M3 processor is not backward compatible
with traditional ARM processors, which use the ARM as well as Thumb instruction set.
The Thumb-2 instruction set is a very important feature of the ARMv7 architecture. For the
first time, hardware divide instruction is available on an ARM processor, and a number of multiply
instructions are also available.
Salient Features of the Cortex-M3
• 32-bit microprocessor.
• 32-bit data path, 32-bit register bank and 32-bit memory interfaces.
• Harvard Architecture – separate instruction bus and data bus.
• 3-stage pipeline with branch speculation.
• Thumb-2 instruction set.
• No switching between ARM state and thumb state.
• Instruction fetches are 32 bits. Up to two instructions can be fetched in one cycle. As a result,
there’s more available bandwidth for data transfer.
• ALU with hardware divide and single cycle multiply.
• Configurable Nested Vector Interrupt Controller (NVIC).
• Maximum of 240 external interrupts can be configured.
• Low gate count, suitable for low power designs.
• Memory Protection Unit (MPU).
• Operation Mode Selection – user and privilege modes.
• Advanced debug components.

Registers

• The Cortex-M3 has registers R0 through R15. R13 (the stack pointer) is banked, with only one
copy of the R13 visible at a time.
• R0 – R12: General Purpose Registers. These are 32 bit registers for data operations. Some 16-bit
Thumb instructions can only access a subset of these registers (low registers R0-R7).
• R13: Stack Pointers. Contains two stack pointers. They are banked so that only one is visible at
a time.
 Main Stack Pointer (MSP) – The main stack pointer used by the Operating system
and exception handlers.
 Process Stack Pointer (PSP) – used by the application code.
• R14: Link Register. When a subroutine is called, the return address is stored in the link register.

Page 47
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in
Embedded Systems Lab Manual 18ECL66
• R15: Program Counter. The program counter is the current program address.
• The Cortex-M3 also has a number of special registers. They are
• Program Status registers (PSR)
• Interrupt Mask registers (PRIMASK, FAULTMASK and BASEPRI).
• Control register (CONTROL)
• The Cortex-M3 has 18 registers in total compared to 37 registers for traditional ARM.
Memory Map
The Cortex-M3 has predefined memory maps, which allows built in peripherals, such as the
interrupt controller and debug components, to be accessed by simple memory access instructions.
The predefined memory map also allows the Cortex-M3 processor to be highly optimized for speed
and ease of integration in system-on-a-chip (SoC) designs.
The Cortex-M3 design has an internal bus infrastructure optimized for this memory usage. In
addition, the design allows these regions to be used differently. For example, data memory can still
be put into the CODE region, and program code can be executed from an external Random Access
Memory (RAM) region. The Cortex-M3 memory map is outlined in figure as shown.
Operation Modes
The Cortex-M3 processor has two modes of operation and two privilege levels. The operation modes
(thread mode and handler mode) determine whether the processor is running a normal program or
running an exception handler like an interrupt handler or system exception handler. The privilege
levels provide a mechanism for safeguarding memory accesses to critical regions as well as
providing a basic security model.
When the processor is running a main program (thread mode), it can be either in a privileged state
or a user state, but exception handlers can only be in a privileged state. When the processor exits
reset, it is in thread mode with privileged access right. In this state, a program has access to all
memory ranges and can use all supported instructions. Software in the privileged access level can
switch the program into the user access level using the control register. When an exception takes
place, the processor will always
switch back to the privileged state and return to the previous state when exiting the exception
handler. A user program cannot change back to the privileged state by writing to the control
register. It has to go through an exception handler that programs the control register to switch the
processor back into the privileged access level when returning to thread mode.

Nested Vector Interrupt Controller (NVIC)


The Cortex-M3 processor includes an interrupt controller called the Nested Vectored Interrupt
Controller (NVIC). It is closely coupled to the processor core and provides a number of features as
follows:
 Nested interrupt support
 Vectored interrupt support
 Dynamic priority changes support
 Reduction of interrupt latency
 Interrupt masking
Nested Interrupt support - All the external interrupts and most of the system exceptions can be
programmed to different priority levels. When an interrupt occurs, the NVIC compares the priority
of this interrupt to the current running priority level. If the priority of the new interrupt handler
is higher than the current level, the interrupt handler of the new interrupt will override the current
running task.
Vectored Interrupt Support - When an interrupt is accepted, the starting address of the interrupt
service routine (ISR) is located from a vector table in memory.
Dynamic Priority Changes Support - Priority levels of interrupts can be changed by software
during run time. Interrupts that are being serviced are blocked from further activation until the
ISR is completed, so their priority can be changed without risk of accidental reentry.
Reduction of Interrupt Latency - The Cortex-M3 processor also includes a number of advanced
features to lower the interrupt latency. These include automatic saving and restoring some register
contents and reducing delay in switching from one ISR to another.
Interrupt Masking - Interrupts and system exceptions can be masked based on their priority level
or masked completely using the interrupt masking registers BASEPRI, PRIMASK, and FAULTMASK.

Page 48
Dept of ECE, Acharya Institute of Technology raghunath@acharya.ac.in

You might also like