Professional Documents
Culture Documents
Embeded Lab
Embeded Lab
INTRODUCTION
Step1: Open the Keil software and select the New Microvision project from Project
Menu as shown below.
Step2: Browse to your project folder and provide the project name and click on save.
Step3: Once the project is saved a new pop up “Select Device for Target” opens, Select
the controller (NXP:LPC1768) and click on OK.
Step5: As LPC1768 needs the startup code, click on Yes option to include the
LPC17xx Startup file.
Step7: Type the code or Copy paste the below code snippet.
Step11: Build the project and fix the compiler errors/warnings if any.
Step12: Code is compiled with no errors. The .hex file is still not generated.
Step13: Click on Target Options to select the option for generating .hex file.
Step17: Check the project folder for the generated .hex file.
Install the Flash Magic software provided on the CD. Run the EXE file and
follow the on screen process.
Open the flash magic software and follow the below steps.
Note: If you want to download a .Hex file then put the Sliding switch SW4 to
programming mode and press RESET button once. After downloading the .Hex
files put the switch SW4 to execution mode and press the RESET switch again.
TTL Ch5Ex1
Area Program, CODE, READONLY
MAIN
LDR R0, Number1
LDR R1,Number2
Mul R0, R1,R0
MUL R0,R0,R1
SWI &11
AREA Data1, DATA
Number1 DCD &706F
Number2 DCD &7016
ALIGN
AREA Data2, DATA
Result DCD
ALIGN
END
Main Code:-
#include <lpc17xx.h>
#include "stdutils.h"
PCLKSELx registers contains the PCLK info for all the clock dependent peripherals.
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
0x00 SystemFreq/4
0x01 SystemFreq
0x02 SystemFreq/2
0x03 SystemFreq/8
**/
switch( var_UartPclk_u32 )
{
case 0x00:
var_Pclk_u32 = SystemCoreClock/4;
break;
Objective
In this tutorial we are going to discuss the serial communication using UART. 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.
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.
UART Registers
The below table shows the registers associated with LPC1768 UART.
Register Description
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.
case 0x01:
var_Pclk_u32 = SystemCoreClock;
break;
case 0x02:
var_Pclk_u32 = SystemCoreClock/2;
break;
case 0x03:
var_Pclk_u32 = SystemCoreClock/8;
break;
}
int main()
{
char a[]="\n\rHello World";
int i;
SystemInit();
uart_init(9600); // Initialize the UART0 for 9600 baud rate
FCR
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.
Reserved DLAB Break COntrol Parity Select Parity Enable Stop Bit Select Word Length Select
31:8 7 6 5 4 3 2 1 0
31:8 7 6-0
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).
Result:
Main code:-
#include <lpc17xx.h>
#define SBIT_PWMMR0R 1 //This bit is used to Reset PWMTC whenever it Matches PWMRx(x:0-6)
#define SBIT_PWMENA3 11 //This bit is used to enable/disable the PWM output for PWMx(x:1-6)
int main(void)
{
int dutyCycle;
SystemInit();
while(1)
{
{
if(dutyCycle<0)
{
dutyCycle=0;
}
}
In most of the applications controlling the speed of DC motor is essential where the precision
and protection are the essence. Here we will use the PWM technique to control the speed of the motor
LPC1768 has one PWM channel with six ports. PWM changes the average output voltage by fast
switching. By changing the on time, the output voltage can be 0 to 100%. There are two software
parameters that need a little explanation: cycle and offset. Cycle is the length of a PWM duty cycle and
offset is the on time of a duty cycle.
The block diagram below shows the PWM pins multiplexed with other GPIO pins. The PWM pin
can be enabled by configuring the corresponding PINSEL register to select PWM function. When the
PWM function is selected for that pin in the Pin Select register, other Digital signals are disconnected
from the PWM input pins.
PWM REGISTERS:
if(dutyCycle>100)
{
dutyCycle=99;
}
}
}
}
MCR-> Match Control Register: The MCR is used to control if an interrupt is generated and if the
TC is reset when a Match occurs.
MR0 – MR6-> Match Register: Each can be enabled in the MCR to reset the TC, stop both the TC
and PC, and/or generate an interrupt when it matches the TC.
PCR-> PWM Control Register: Enables PWM outputs and selects PWM channel types as either
single edge or double edge controlled.
LCR-> Load Enable Register: Enables use of new PWM match values.
Note: for detailed description of each registers kindly refer PWM waveform section
If you need to control the speed of a DC motor you have a few options. Controlling the speed by
controlling either voltage or current is inefficient. Let‟s understand a bit the speed control of DC motor
Using Pulse Width Modulation because controlling how long the voltage is applied with a certain
frequency gives you the best control over the motor‟s speed.
Conventional power supplies tend to generate lots of heat because are working as variable
resistors pumping current through external circuits. The pulse width modulation circuits are digital
circuits which produce pulsed current. Due to the fact that the pulsed width modulation power
supplies works in a state in between on and off, the heat generated is very low compared to the
conventional power supplies.
The duty cycle of the circuit can be changed by pressing the switches SW22 and SW23. If we increase
the duty cycle(press SW22), the speed of the motor increases and if we decrease the duty cycle(press
SW23), the speed of the motor decreases.
Result:
#include <lpc17xx.h>
for(i=0;i<ms;i++)
for(j=0;j<20000;j++); //delay subroutine
}
int main()
{
int cycle;
SystemInit(); //Clock and PLL configuration
for(cycle=0; cycle<13; cycle++) // for loop condition for number of rotation. It gives approx 90 degree rotation
{
LPC_GPIO0->FIOPIN = 0x00008000 ; // p0.15 pin
delay(100);
#include "lpc17xx.h"
void delay();
void delay()
{
int i,j;
for(i=0;i<0xff;i++)
for(j=0;j<0x400;j++);
}
LPC_GPIO0->FIODIR |= 0x00078000;
while(1)
{
if(rotate==1)
{
LPC_GPIO0->FIOPIN = 0x00008000 ;
A stepper motor or step motor or stepping motor is a brushless DC electric motor that divides a
full rotation into a number of equal steps. The motor's position can then be commanded to move and
hold at one of these steps without any position sensor for feedback (an open-loop controller), as long as
the motor is carefully sized to the application in respect to torque and speed.
What is a stepper motor?
A Stepper Motor or a step motor is a brushless, synchronous motor which divides a full rotation
into a number of steps. Unlike a brushless DC motor which rotates continuously when a fixed DC
voltage is applied to it, a step motor rotates in discrete step angles. The Stepper Motors therefore are
manufactured with steps per revolution of 12, 24, 72, 144, 180, and 200, resulting in stepping angles
of 30, 15, 5, 2.5, 2, and 1.8 degrees per step. The stepper motor can be controlled with or without
feedback.
Stepper motors work on the principle of electromagnetism. There is a soft iron or magnetic rotor
shaft surrounded by the electromagnetic stators. The rotor and stator have poles which may be teethed
or not depending upon the type of stepper. When the stators are energized the rotor moves to align
itself along with the stator (in case of a permanent magnet type stepper) or moves to have a minimum
gap with the stator (in case of a variable reluctance stepper). This way the stators are energized in a
sequence to rotate the stepper motor. Get more information about working of stepper motors through
interesting images at the stepper motor Insight.
delay();
LPC_GPIO0->FIOPIN = 0x00010000 ;
delay();
LPC_GPIO0->FIOPIN = 0x00020000 ;
delay();
LPC_GPIO0->FIOPIN = 0x00040000 ;
delay();
}
else
{
LPC_GPIO0->FIOPIN = 0x00040000 ;
delay();
LPC_GPIO0->FIOPIN = 0x00020000 ;
delay();
LPC_GPIO0->FIOPIN = 0x00010000 ;
delay();
LPC_GPIO0->FIOPIN = 0x00008000 ;
delay();
}
rotate=1;
}
else if(!(LPC_GPIO2->FIOPIN & 0x00001000))
{
while(!(LPC_GPIO2->FIOPIN & 0x00001000));
rotate=0;
}
}
}
Positioning – Since steppers move in precise repeatable steps, they excel in applications
requiring precise positioning such as 3D printers, CNC, Camera platforms and X,Y Plotters.
Some disk drives also use stepper motors to position the read/write head.
Speed Control – Precise increments of movement also allow for excellent control of rotational
speed for process automation and robotics.
Low Speed Torque - Normal DC motors don't have very much torque at low speeds. A Stepper
motor has maximum torque at low speeds, so they are a good choice for applications requiring
low speed with high precision.
Stepper motors consist of a permanent magnetic rotating shaft, called the rotor, and
electromagnets on the stationary portion that surrounds the motor, called the stator. Figure 1
illustrates one complete rotation of a stepper motor. At position 1, we can see that the rotor is
beginning at the upper electromagnet, which is currently active (has voltage applied to it). To move the
rotor clockwise (CW), the upper electromagnet is deactivated and the right electromagnet is activated,
causing the rotor to move 90 degrees CW, aligning itself with the active magnet. This process is
repeated in the same manner at the south and west electromagnets until we once again reach the
starting position.
Figure 1
this. For example, a motor with a resolution of 1.8 degrees would move its rotor 1.8 degrees per
step, thereby requiring 200 pulses (steps) to complete a full 360 degree rotation.
Here we are using 200 pole stepper motor hence it gives 360degree/200 pole=1.8 degree per step.
So for example if we need 120 degree rotation then we have to apply approximately 67 pulses to
complete 120 degree rotation
Here one cycle means 4 steps. So if we need 90 degree rotation then 90/1.8=50 steps.
Here one cycle means 4 steps. So 50/4=12.5 =~ 13. So we need 13 cycles to rotate 90 degree.
If we want to run 180 degree then 180/1.8=100. So 100/4=25 cycles would make a stepper motor to
rotate 180 degree.
Result:
#include "LPC17xx.h"
uint32_t val;
int main()
{
SystemInit();
LPC_PINCON->PINSEL1 |= 0x02<<20; //p0.26 pinsel bits 20 and 21
while(1)
{
while(1)
{
val++; // increment values by 6
LPC_DAC->DACR=(val<<6); //send values to dac
if(val>=0x3ff) // if value exceeds 1024
{
break;
}
}
while(1)
{
val--; // decrement value by 6
LPC_DAC->DACR=(val<<6); // send value to dac
if(val<=0x000) // if value come down by 0
{
break;
}
}
}
#include "LPC17xx.h"
void delay(unsigned int ms)// delay subroutine
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<2000;j++);
}
int main()
{
SystemInit();
LPC_PINCON->PINSEL1 |= 0x02<<20; //p0.26 pinsel bits 20 and 21
while(1)
{
LPC_DAC->DACR=0xffff; // send maximum values to dac
delay(20); // delay
LPC_DAC->DACR=0x0000; // send min values to dac
delay(20);
}
}
In this article, we will go through a discussion on ARM Cortex-M3 LPC1768 DAC programming
tutorial. As you might be knowing, DAC stands for Digital to Analog Conversion. The DAC block in ARM
Cortex-M3 LPC176x microcontroller is one of the simplest to program and also supports DMA(direct
memory access). This tutorial is also applicable for LPC1769 MCU. Basically we assign a digital value to
a register and the DAC block outputs it equivalent analog signal as shown below:
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 2N 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:
Where VALUE is the 10-bit digital value which is to be converted into its Analog counterpart
and VREF is the input reference voltage.
AOUT Analog Output pin. Provides the converted Analog signal which is referenced to V SSA i.e. the
(P0.26) 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,
reference voltage and VREFN is negative reference voltage pin. In example shown below we will
VREFN
use VREFN=0V(GND).
VDDA is Analog Power pin and VSSA is Ground pin used to power the ADC module. These are
VDDA, VSSA
generally same as VCC and GND but with additional filtering to reduce noise.
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 output.
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: After a new VALUE is written to this field, given settling time selected using
BIAS has elapsed, we get the converted Analog voltage at the output. The formula for analog
voltage at AOUT pin is as shown above.
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
As evident, without using DMA, programming the DAC block is very straight forward. We just
need to select AOUT function for P0.26 pin and apply a 10-bit value which needs to be converted into
its Analog form. Lets see a basic LPC1768 DAC example. For most development boards V REFP will be
connected to VDD/VDDA and VREFP will be connected to VSS/VSSA using some form of noise isolation. In
this DAC example, we will be changing the output from 0V to V REFP (using VREFN=0V) and then falling
back to 0V in steps of 10ms. This DAC program will basically output a sawtooth waveform. We will be
using BIAS = 0 i.e. settling time of 1us. You can connect an Oscilloscope or a Multimeter between P0.26
and GND to check the changing analog output. Since the output is buffered you can drive an LED from
AOUT but it won‟t glow until it reaches its forward bias voltage of around 1.7 Volts. So, keep this in mind
when checking for analog output using an LED. Also, I have used Timer0 for generating
delay(Alternatively this can be using DMA Timer itself). You can check my previous LPC1768 timer
tutorial.
Result:
Main code:-
#include "lpc17xx.h"
#include "lcd.h"
/////////////////////////////////////////////
// Matrix Keypad Scanning Routine
//
// COL1 COL2 COL3 COL4
// 0 1 2 3 ROW 1
// 4 5 6 7 ROW 2
// 8 9 A B ROW 3
// C D E F ROW 4
//////////////////////////////////////////////
#define COL1 0
#define COL2 1
#define COL3 4
#define COL4 8
#define ROW1 9
#define ROW2 10
#define ROW3 14
#define ROW4 15
KEY_CTRL_CLR |= COLMASK;
KEY_CTRL_SET |= temp;
}
There are various methods to provide an input for the GPIO pins of a microcontroller which can
be software controlled or hardware controlled. We have seen a hardware controlled method by taking
an input from a switch or a press button. Push Button Interfacing with LPC1768
The keypad is another external input device which is hardware controlled, but is used for a specific
purpose. In this tutorial we take a look at how a 4×4 matrix keypad is interfaced with the LPC1768
microcontroller. The input taken from the matrix keypad will be displayed on a 16x2 LCD display.
Basic Configuration
NOTE: Please read this section carefully as it is important to understand the hardware connection
before writing software for this application.
As we are using a 4×4 matrix keypad, a total of 8 input-output pins of the micro-controller will
be required for interfacing.
One half of the 8 pins will be hardware controlled and the other half will be software controlled.
Therefore, the columns can be pulled up or pulled down. The rows are the four LSBs of the 8 bit
pins and the columns are the MSBs of the 8 bit pins.
(GENERAL CONVENTION: ROWS: Horizontal & COLUMNS: Vertical)
In our program, the MSBs (columns) will be set in the input mode and the LSBs (rows) will be
set in the output mode. The default state of the MSBs can be HIGH or LOW based on the
hardware connection. Based on this we have two modes of operation for the keypad, i.e. Pull Up
mode or Pull Down mode (refer the fig.). In the pull up mode, MSBs (columns) by default will be
high and in the pull down mode, MSBs by default will be low. We will be operating in the Pull
Up Mode.
SystemInit();
init_lcd();
while (1)
{
key = 0;
for( i = 0; i < 4; i++ )
{
// turn on COL output one by one
col_write(rval[i]);
key++;
if (!(KEY_CTRL_PIN & (1<<ROW2)))
break;
key++;
key++;
if (!(KEY_CTRL_PIN & (1<<ROW4)))
break;
key++;
}
if (key == 0x10)
lcd_putstring16(1,"Key Pressed = ");
else
{
lcd_gotoxy(1,14);
lcd_putchar(keyPadMatrix[key]);
}
}
When a key is pressed, the output and input line or in other words, rows and columns common
to the pressed key will be connected to each other and hence the value on the output line will be
reflected on the corresponding input line.
Without any software change, the columns, which we will be configuring as input pins in the
software, will continue to be in the pulled up state. Therefore, when any key is pressed our aim
is to cause a deviation from this default state. This change is performed in the software.
When a software change occurs and a value is written on the output pins (rows), the four rows
will reflect the value from the controller. This value gets passed to the corresponding column
when the key common to the row and column is pressed. As we are operating in pull up state,
we will continuously send a LOW state to each of the four output pins (rows) keeping all other
pins HIGH.
For every LOW state to each rows, we scan for a key press by checking for a LOW state at any of
the column pins. This is because, when the rows and columns get connected, the circuit takes
the path of least resistance (internal pull up when configured in the input mode is weak) and
the LOW state on the row is reflected on the corresponding column, thus deviating from the
default state. Based on this change in the state of the signal on the respective input line
(column), we can determine the identity of the pressed key.
Firmware
These are the definitions that will be used for the keypad programming.
Keypad Definitions
Next, we must set the direction of the hardware pins according to its software functionality. As
discussed, the LSB (rows) is set in the output mode and the MSB (columns) will be set in the
input mode. The KEYPAD_DATA_MASK definition is used to set the pin direction.
We will be using the UART0 built in module to display the output of the keypad press. Therefore
we must initialize the UART0 communication protocol as well.
The GetKey() performs a continuous scan and checks for a key press. The design logic is based
on the following figure of the keypad connection and the functioning is as follows.
o The ROWS are the LSB pins and the COLUMNS are the MSB pins.
LCD code:-
#include "lpc17xx.h"
#include "lcd.h"
#define LCD_D4 19
#define LCD_D5 20
#define LCD_D6 21
#define LCD_D7 22
#define LcdData LPC_GPIO0->FIOPIN
#define LcdControl LPC_GPIO0->FIOPIN
#define LcdDataDirn LPC_GPIO0->FIODIR
#define LcdCtrlDirn LPC_GPIO0->FIODIR
#define LCD_ctrlMask ((1<<LCDRS)|(1<<LCDRW)|(1<<LCDEN))
#define LCD_dataMask ((1<<LCD_D4)|(1<<LCD_D5)|(1<<LCD_D6)|(1<<LCD_D7))
void delay(unsigned int count)
{
int j=0, i=0;
for (j=0;j<count;j++)
for (i=0;i<30;i++);
}
delay(10000);
delay(1000);
}
o Since, the MSB is hardware controlled (pull up or pull down), these bits on the keypad
will only take the logic value set in the hardware (LOGIC HIGH in our case).
o When a key is pressed, the corresponding row and column will be connected.
o We will be writing and shifting LOGIC 0 continuously to row „n‟ keeping all the other row
pins at LOGIC 1. (n: 1-4)
o When a key is pressed and LOGIC 0 appears on the corresponding row pin, LOGIC 0
from the row will be reflected to the corresponding column.
o Since the columns are set as input pins in the microcontroller, while reading the values
of the rows, if any of the pin is at LOGIC 0, then it is an indication that a key has been
pressed. The reading operation is done by readbite() function.
o The readbite() uses a switch to identify the row corresponding to the pressed key. If any
of the switch case is satisfied, then it checks for the column corresponding to the
pressed key. If the column reflects a LOGIC 0, then we can determine the value of the
pressed key.
o Now, using a while loop, we will wait till the LOGIC 0 disappears so that the software
waits till the current state in the hardware is changed. This is done to avoid a hardware
debouncing.
o A small delay is also provided in between each column write so that the reading
operation does not get skipped.
Once we have the value of the pressed key, this is displayed on the LCD
delay(1000);
delay(1000);
}
lcd_gotoxy( line, 0 );
while(*string != '\0' && len--)
{
lcd_putchar( *string );
string++;
}
}
Lcd_CmdWrite(0x03);
delay(2000);
Lcd_CmdWrite(0x03);
delay(1000);
Lcd_CmdWrite(0x03);
delay(100);
Lcd_CmdWrite(0x2);
Lcd_CmdWrite(0x28);
Lcd_CmdWrite(0x0e);
Lcd_CmdWrite(0x06);
Lcd_CmdWrite(0x01);
delay(1); // display on
Result:
Main code:-
#include <lpc17xx.h>
void delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<60000;j++);
}
#define SBIT_CNTEN 0
#define SBIT_PWMEN 2
#define SBIT_PWMMR0R 1
#define SBIT_PWMENA1 9
while(1)
{
for(dutyCycle=0; dutyCycle<100; dutyCycle++)
{
LPC_PWM1->MR1 = dutyCycle; /* Increase the dutyCycle from 0-100 */
delay_ms(5);
}
Register Description
Interrupt Register: The IR can be read to identify which of eight possible interrupt sources are
IR
pending. Writing Logic-1 will clear the corresponding interrupt.
Timer Control Register: The TCR is used to control the Timer Counter
TCR
functions(enable/disable/reset).
Timer Counter: The 32-bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled
TC
through the TCR.
PR Prescalar Register: This is used to specify the Prescalar value for incrementing the TC.
Prescale Counter: The 32-bit PC is a counter which is incremented to the value stored in PR.
PC
When the value in PR is reached, the TC is incremented.
Match Control Register: The MCR is used to control the reseting of TC and generating of
MCR
interrupt whenever a Match occurs.
MR0 Match Register: This register hold the max cycle Time(Ton+Toff).
MR1- Match Registers: These registers holds the Match value(PWM Duty) for corresponding PWM
MR6 channels(PWM1-PWM6).
PWM Control Register: PWM Control Register. Enables PWM outputs and selects PWM
PCR
channel types as either single edge or double edge controlled.
LER Load Enable Register: Enables use of new PWM values once the match occurs.
Register Configuration
The below table shows the registers associated with LPC1768 PWM.
TCR
31:4 3 2 1 0
MCR
31:21 20 19 18 -5 4 3 2 1 0
Reserve PWMMR6 PWMMR6 PWMMR PWMMR1 PWMMR1 PWMMR PWMMR0 PWMMR0 PWMMR
-
d S R 6I S R 1I S R 0I
PWMMRxI
This bit is used to Enable or Disable the PWM interrupts when the PWMTC matches PWMMRx (x:0-6)
0- Disable the PWM Match interrupt
1- Enable the PWM Match interrupt.
PWMMRxR
This bit is used to Reset PWMTC whenever it Matches PWMRx(x:0-6)
0- Do not Clear.
1- Reset the PWMTC counter value whenever it matches PWMRx.
PWMMRxS
This bit is used to Stop the PWMTC,PWMPC whenever the PWMTC matches PWMMRx(x:0-6).
0- Disable the PWM stop o match feature
1- Enable the PWM Stop feature. This will stop the PWM whenever the PWMTC reaches the Match
register value.
PCR
PWMSELx
This bit is used to select the single edged and double edge mode form PWMx (x:2-6)
0- Single Edge mode for PWMx
1- Double Edge Mode for PWMx.
PWMENAx
This bit is used to enable/disable the PWM output for PWMx(x:1-6)
0- PWMx Disable.
1- PWMx Enabled.
LER
31-7 6 5 4 3 2 1 0
LENx
This bit is used Enable/Disable the loading of new Match value whenever the PWMTC is reset(x:0-6)
PWMTC will be continously incrementing whenever it reaches the PWMMRO, timer will be reset
depeding on PWMTCR configuraion. Once the Timer is reset the New Match values will be loaded from
MR0-MR6 depending on bits set in this register.
PWM Working
After looking into the PWM registers, its time to see how the LPC1768 PWM module works.
The TC is continuously incremented and once it matches the MR1(Duty Cycle) the PWM pin is pulled
Low. TC still continues to increment and once it reaches the Cycle time(Ton+Toff) the PWM module
does the following things:
Reset the TC value.
Pull the PWM pin High.
Loads the new Match register values.
Result:
Main code:-
#include <lpc17xx.h>
void EINT1_IRQHandler(void)
{
LPC_SC->EXTINT = (1<<SBIT_EINT1); /* Clear Interrupt Flag */
LPC_GPIO1->FIOPIN ^= (1<< LED1); /* Toggle the LED1 everytime INTR1 is generated */
}
void EINT2_IRQHandler(void)
{
LPC_SC->EXTINT = (1<<SBIT_EINT2); /* Clear Interrupt Flag */
LPC_GPIO1->FIOPIN ^= (1<< LED2); /* Toggle the LED2 everytime INTR2 is generated */
}
int main()
{
SystemInit();
while(1)
{
// Do nothing
}
}
EINTx Pins
LPC1768 has four external interrupts EINT0-EINT3. As LPC1768 pins are multi functional, these four
interrupts are available on multiple pins.
Below table shows mapping of EINTx pins.
Port Pin PINSEL_FUNC_0 PINSEL_FUNC_1 PINSEL_FUNC_2 PINSEL_FUNC_3
EINT Registers
Below table shows the registers associated with LPC1768 external interrupts.
Register Description
EXTINT External Interrupt Flag Register contains interrupt flags for EINT0,EINT1, EINT2 & EINT3.
EXTINT
31:4 3 2 1 0
EXTMODE
31:4 3 2 1 0
EXTPOLAR
31:4 3 2 1 0
Result:
Main Code:-
#include <lpc17xx.h>
while(1)
{
The 7-segment display, also written as “seven segment display”, consists of seven LEDs (hence
its name) arranged in a rectangular fashion as shown. Each of the seven LEDs is called a segment
because when illuminated the segment forms part of a numerical digit (both Decimal and Hex) to be
displayed. An additional 8th LED is sometimes used within the same package thus allowing the
indication of a decimal point, (DP) when two or more 7-segment displays are connected together to
display numbers greater than ten.
Each one of the seven LEDs in the display is given a positional segment with one of its
connection pins being brought straight out of the rectangular plastic package. These individually LED
pins are labelled from a through to g representing each individual LED. The other LED pins are
connected together and wired to form a common pin.
So by forward biasing the appropriate pins of the LED segments in a particular order, some
segments will be light and others will be dark allowing the desired character pattern of the number to
be generated on the display. This then allows us to display each of the ten decimal digits 0 through to 9
on the same 7-segment display.
The displays common pin is generally used to identify which type of 7-segment display it is. As
each LED has two connecting pins, one called the “Anode” and the other called the “Cathode”, there are
therefore two types of LED 7-segment display called: Common Cathode (CC) and Common Anode
(CA).
The difference between the two displays, as their name suggests, is that the common cathode
has all the cathodes of the 7-segments connected directly together and the common anode has all the
anodes of the 7-segments connected together and is illuminated as follows.
The Common Cathode (CC) – In the common cathode display, all the cathode connections of the
LED segments are joined together to logic “0” or ground. The individual segments are
illuminated by application of a “HIGH”, or logic “1” signal via a current limiting resistor to
forward bias the individual Anode terminals (a-g).
The Common Anode (CA) – In the common anode display, all the anode connections of the LED
segments are joined together to logic “1”. The individual segments are illuminated by applying a
ground, logic “0” or “LOW” signal via a suitable current limiting resistor to the Cathode of the
particular segment (a-g).
In general, common anode displays are more popular as many logic circuits can sink more current
than they can source. Also note that a common cathode display is not a direct replacement in a circuit
for a common anode display and vice versa, as it is the same as connecting the LEDs in reverse, and
hence light emission will not take place.
Depending upon the decimal digit to be displayed, the particular set of LEDs is forward biased. For
instance, to display the numerical digit 0, we will need to light up six of the LED segments
corresponding to a, b, c, d, e and f. Thus the various digits from 0 through 9 can be displayed using a
7-segment display as shown.
Then for a 7-segment display, we can produce a truth table giving the individual segments that need to
be illuminated in order to produce the required decimal digit from 0 through 9 as shown below.
0 × × × × × ×
1 × ×
2 × × × × ×
3 × × × × ×
4 × × × ×
5 × × × × ×
6 × × × × × ×
7 × × ×
8 × × × × × × ×
9 × × × × ×
Although a 7-segment display can be thought of as a single display, it is still seven individual
LEDs within a single package and as such these LEDs need protection from over current. LEDs
produce light only when it is forward biased with the amount of light emitted being proportional to the
forward current.
This means then that an LEDs light intensity increases in an approximately linear manner with
an increasing current. So this forward current must be controlled and limited to a safe value by an
external resistor to prevent damage to the LED segments.
The forward voltage drop across a red LED segment is very low at about 2-to-2.2 volts, (blue and
white LEDs can be as high as 3.6 volts) so to illuminate correctly, the LED segments should be
connected to a voltage source in excess of this forward voltage value with a series resistance used to
limit the forward current to a desirable value.
Typically for a standard red colored 7-segment display, each LED segment can draw about 15
mA to illuminated correctly, so on a 5 volt digital logic circuit, the value of the current limiting resistor
would be about 200Ω (5v – 2v)/15mA, or 220Ω to the nearest higher preferred value. So to understand
how the segments of the display are connected to a 220Ω current limiting resistor consider the circuit
below.
In this example, the segments of a common anode display are illuminated using the switches. If
switch a is closed, current will flow through the “a” segment of the LED to the current limiting
resistor connected to pin a and to 0 volts, making the circuit. Then only segment a will be illuminated.
So a LOW condition (switch to ground) is required to activate the LED segments on this common
anode display.
But suppose we want the decimal number “4” to illuminate on the display. Then switches b, c, f and g
would be closed to light the corresponding LED segments. Likewise for a decimal number “7”, switches
a, b, c would be closed. But illuminating 7-segment displays using individual switches is not very
practical.
Here we are controlling the segments using LPC1768 controller. And we have used Common
Anode(CA) type display here
Used schematic is as follows
For illuminate a digit we have to make a appropriate port Low (send 0).
Here 1st make P0.8 or P4.28 High. It will send control active signal to segment. Then initially make
P1.0,P1.1,P1.4,P1.8,P1.9,P1.10,P1.14 all high. Now all the digits become off. Then make
respected segment low by sending CLR signal to GPIO. This cause the segment to illuminate.
Result:
Main code:-
#include <lpc17xx.h>
uint32_t switchStatus;
LPC_GPIO1->FIODIR = 0x1ff80000; /* P1.xx defined as Outputs */
LPC_GPIO1->FIOCLR = 0x1ff80000; /* turn off all the LEDs&relay&buzzer */
LPC_GPIO2->FIODIR = 0x00000000; /* P2.xx defined as input */
while(1)
{
}
}
}
Register Configuration
The Below registers will be used for Configuring and using the GPIOs registers for sending and
receiving the Digital signals.
0 Input
1 Output
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
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
FIOPIN:
Fast Port Pin Value Register. This register is used for both reading and writing data from/to the PORT.
Output: Writing to this register places corresponding values in all bits of the particular PORT pins.
Input: The current state of digital port pins can be read from this register, regardless of pin direction or
alternate function selection (as long as pins are not configured as an input to ADC).
Note:It is recommended to configure the PORT direction and pin function before using it.
Here switch is pulled up to +3.3 volt. So when pressed port should read active low
signal(0),normal condition is active high(1).
Result:
Main code:-
#include <LPC17xx.H>
#include <stdint.h>
#include <stdio.h>
#include "delay.h"
#include "spi_manul.h"
#include "lcd.h"
#define pulse_val 2
main()
{
unsigned int spi_rsv=0;
float vin;
char buf[20];
SystemInit ();
lcd_init();
lcd_str("SPI 3202-b");
delay(60000);
delay(60000);
while(1)
{
lcd_clr();
lcd_cmd(0x80);
spi_rsv = spi_data1(15);
vin = ( ( spi_rsv & 0xfff ) * (3.3) ) / 4096 ;
sprintf(buf,"Temp: %0.2f degC",(vin*100) );
lcd_str(buf);
delay(50000);
delay(50000);
}
}
#include <LPC17xx.H>
#include "delay.h"
#define pulse_val 2
#define CLK 1<<27
#define CS 1<<28
#define DDOUT 26
#define DOUT 1<<25
#define DIN 1<<26
#define spi_stst 0
To work around this problem, asynchronous serial connections add extra start and stop bits to each
byte help the receiver sync up to data as it arrives. Both sides must also agree on the transmission
speed (such as 9600 bits per second) in advance. Slight differences in the transmission rate aren‟t a
problem because the receiver re-syncs at the start of each byte.
(By the way, if you noticed that “11001010” does not equal 0x53 in the above diagram, kudos to your
attention to detail. Serial protocols will often send the least significant bits first, so the smallest bit is
on the far left. The lower nybble is actually 0011 = 0x3, and the upper nybble is 0101 = 0x5.)
Asynchronous serial works just fine, but has a lot of overhead in both the extra start and stop bits sent
with every byte, and the complex hardware required to send and receive data. And as you‟ve probably
noticed in your own projects, if both sides aren‟t set to the same speed, the received data will be
LPC_GPIO0->FIOCLR = CS;
nop_delay(pulse_val);
while(clks)
{
LPC_GPIO0->FIOCLR = CLK;
nop_delay(pulse_val);
LPC_GPIO3->FIOPIN = (sel & 1) << DDOUT;
sel = sel >> 1;
LPC_GPIO0->FIOSET = CLK;
nop_delay(pulse_val);
clks--;
}
LPC_GPIO0->FIOCLR = CLK;
nop_delay(pulse_val);
if (!( LPC_GPIO3->FIOPIN & DIN ) )
{
return 'U';
}
clks = 12;
while(clks)
{
clks--;
LPC_GPIO0->FIOCLR = CLK;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(pulse_val);
}
nop_delay(pulse_val);
if (!( LPC_GPIO3->FIOPIN & DIN ) )
{
return 'U';
}
return 'Z';
}
unsigned int spi_data1(char sel)
{
unsigned int spi_reg=0;
char clks = 12;
LPC_GPIO0->FIODIR |= CS|CLK;
LPC_GPIO3->FIODIR = DOUT;
LPC_GPIO0->FIOSET = CS|CLK;
LPC_GPIO3->FIOSET = DOUT;
LPC_GPIO3->FIOPIN = DIN;
nop_delay(100);
LPC_GPIO0->FIOCLR = CS;
//start condition
LPC_GPIO0->FIOCLR = CLK;
LPC_GPIO3->FIOSET = DOUT;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(5);
//single mode
LPC_GPIO0->FIOCLR = CLK;
LPC_GPIO3->FIOSET = DOUT;
garbage. This is because the receiver is sampling the bits at very specific times (the arrows in the above
diagram). If the receiver is looking at the wrong times, it will see the wrong bits.
A Synchronous Solution
SPI works in a slightly different manner. It‟s a “synchronous” data bus, which means that it uses
separate lines for data and a “clock” that keeps both sides in perfect sync. The clock is an oscillating
signal that tells the receiver exactly when to sample the bits on the data line. This could be the rising
(low to high) or falling (high to low) edge of the clock signal; the datasheet will specify which one to use.
When the receiver detects that edge, it will immediately look at the data line to read the next bit (see the
arrows in the below diagram). Because the clock is sent along with the data, specifying the speed isn‟t
important, although devices will have a top speed at which they can operate (We‟ll discuss choosing the
proper clock edge and speed in a bit).
One reason that SPI is so popular is that the receiving hardware can be a simple shift register. This
is a much simpler (and cheaper!) piece of hardware than the full-up UART (Universal Asynchronous
Receiver / Transmitter) that asynchronous serial requires.
Receiving Data
You might be thinking to yourself, self, that sounds great for one-way communications, but how do you
send data back in the opposite direction? Here‟s where things get slightly more complicated.
In SPI, only one side generates the clock signal (usually called CLK or SCK for Serial ClocK). The side
that generates the clock is called the “master”, and the other side is called the “slave”. There is always
only one master (which is almost always your microcontroller), but there can be multiple slaves (more
on this in a bit).
When data is sent from the master to a slave, it‟s sent on a data line called MOSI, for “Master Out /
Slave In”. If the slave needs to send a response back to the master, the master will continue to generate
a prearranged number of clock cycles, and the slave will put the data onto a third data line called
MISO, for “Master In / Slave Out”.
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(5);
//chanl 1
LPC_GPIO0->FIOCLR = CLK;
LPC_GPIO3->FIOSET = DOUT;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(5);
//msb first
LPC_GPIO0->FIOCLR = CLK;
LPC_GPIO3->FIOSET = DOUT;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(5);
LPC_GPIO0->FIOCLR = CLK;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
nop_delay(5);
clks = 12;
while(clks)
{
LPC_GPIO0->FIOCLR = CLK;
nop_delay(pulse_val);
LPC_GPIO0->FIOSET = CLK;
if( ( LPC_GPIO3->FIOPIN & DIN ) )
{
spi_reg |= 1<<(clks-1);
}
else
{
spi_reg = spi_reg;
}
clks--;
nop_delay(5);
}
nop_delay(1);
return spi_reg;
}
#include <LPC17xx.H>
#include "delay.h"
#define RRW (7<<9)
#define DATA_L (15<<19)
void lcd_pin(void)
{
LPC_GPIO0->FIODIR |= RRW|DATA_L;
}
Notice we said “prearranged” in the above description. Because the master always generates the clock
signal, it must know in advance when a slave needs to return data and how much data will be
returned. This is very different than asynchronous serial, where random amounts of data can be sent
in either direction at any time. In practice this isn‟t a problem, as SPI is generally used to talk to
sensors that have a very specific command structure. For example, if you send the command for “read
data” to a device, you know that the device will always send you, for example, two bytes in return. (In
cases where you might want to return a variable amount of data, you could always return one or two
bytes specifying the length of the data and then have the master retrieve the full amount.)
Note that SPI is “full duplex” (has separate send and receive lines), and, thus, in certain situations, you
can transmit and receive data at the same time (for example, requesting a new sensor reading while
retrieving the data from the previous one). Your device‟s datasheet will tell you if this is possible.
There‟s one last line you should be aware of, called SS for Slave Select. This tells the slave that it
should wake up and receive / send data and is also used when multiple slaves are present to select the
one you‟d like to talk to.
LPC_GPIO0->FIOCLR |= RRW|DATA_L;
delay(10);
}
void lcd_data(unsigned char cmd)
{
LPC_GPIO0->FIOPIN =(1<<9)|( ( ( cmd & 0xf0 )>> 4) << 19 )| (1<<11);
delay(200);
LPC_GPIO0->FIOPIN =( ( ( cmd & 0xf0 )>> 4) << 19 );
LPC_GPIO0->FIOCLR |= RRW|DATA_L;
delay(10);
The SS line is normally held high, which disconnects the slave from the SPI bus. (This type of logic is
known as “active low,” and you‟ll often see used it for enable and reset lines.) Just before data is sent to
the slave, the line is brought low, which activates the slave. When you‟re done using the slave, the line
is made high again. In a shift register, this corresponds to the “latch” input, which transfers the
received data to the output lines.
Multiple slaves
There are two ways of connecting multiple slaves to an SPI bus:
1. In general, each slave will need a separate SS line. To talk to a particular slave, you‟ll make that
slave‟s SS line low and keep the rest of them high (you don‟t want two slaves activated at the
same time, or they may both try to talk on the same MISO line resulting in garbled data). Lots of
slaves will require lots of SS lines; if you‟re running low on outputs, there are binary decoder
chips that can multiply your SS outputs.
1. On the other hand, some parts prefer to be daisy-chained together, with the MISO (output) of
one going to the MOSI (input) of the next. In this case, a single SS line goes to all the slaves.
Once all the data is sent, the SS line is raised, which causes all the chips to be activated
simultaneously. This is often used for daisy-chained shift registers and addressable LED
drivers.
Note that, for this layout, data overflows from one slave to the next, so to send data to any one slave,
you‟ll need to transmit enough data to reach all of them. Also, keep in mind that the first piece of data
you transmit will end up in the last slave.
This type of layout is typically used in output-only situations, such as driving LEDs where you don‟t
need to receive any data back. In these cases you can leave the master‟s MISO line disconnected.
However, if data does need to be returned to the master, you can do this by closing the daisy-chain loop
(blue wire in the above diagram). Note that if you do this, the return data from slave 1 will need to pass
through all the slaves before getting back to the master, so be sure to send enough receive commands
to get the data you need.
You will need to select some options when setting up your interface. These options must match those of
the device you‟re talking to; check the device‟s datasheet to see what it requires.
Advantages of SPI:
It‟s faster than asynchronous serial
The receive hardware can be a simple shift register
It supports multiple slaves
Disadvantages of SPI:
It requires more signal lines (wires) than other communications methods
The communications must be well-defined in advance (you can‟t send random amounts of data
whenever you want)
The master must control all communications (slaves can‟t talk directly to each other)
It usually requires separate SS lines to each slave, which can be problematic if numerous slaves
are needed.
MCP3202
Pin description and Pin functional table of MCP3202
Serial Peripheral interface allows high speed synchronous data communication between lpc1768
microcontrollers.
first we need to send start bit , it is last bit of first byte we are going to send to ADC and then we have
to select Configuration modes.there are two modes single ended and pseudo differential mode here i am
choosing single ended mode . MSBF bit chosses order of format of byte either MSB first or LSB first
here i am choosing MSB bit first format so MSBF=1. SO i am transfering
Secondbyte=0xA0forchannel0and Secondbyte=0xE0
for channel 1. ADC will return B11 to B8 of data in the lower nibble of byte so we need to perform some
mathematical manipulation. after that we need to send any byte to receive third byte of data.
CS P0.28
CLK P0.27
MCP
3202
Dout P3.26
Din P3.25
Result:
#include "lpc17xx.h"
#include "lcd.h"
#define VREF 3.3 //Reference Voltage at VREFP pin, given VREFN = 0V(GND)
#define ADC_CLK_EN (1<<12)
#define SEL_AD0_2 (1<<2) //Select Channel AD0.2
#define CLKDIV 1 //ADC clock-divider (ADC_CLOCK=PCLK/CLKDIV+1) = 12.5Mhz @ 25Mhz PCLK
#define PWRUP (1<<21) //setting it to 0 will power it down
#define START_CNV (1<<24) //001 for starting the conversion immediately
#define ADC_DONE (1U<<31) //define it as unsigned value or compiler will throw #61-D warning
#define ADCR_SETUP_SCM ((CLKDIV<<8) | PWRUP)
////////// Init ADC0 CH2 /////////////////
Init_ADC()
{
// Convert Port pin 0.25 to function as AD0.2
LPC_SC->PCONP |= ADC_CLK_EN; //Enable ADC clock
LPC_ADC->ADCR = ADCR_SETUP_SCM | SEL_AD0_2;
LPC_PINCON->PINSEL1 |= (1<<18) ; //select AD0.2 for P0.25
}
}
////////// DISPLAY ADC VALUE /////////////////
Display_ADC()
{
unsigned int adc_value = 0;
char buf[4] = {5};
float voltage = 0.0;
adc_value = Read_ADC();
sprintf((char *)buf, "%3d", adc_value); // display 3 decima place
lcd_putstring16(0,"ADC VAL = 000 "); //1st line display
lcd_putstring16(1,"Voltage 00 V"); //2nd line display
lcd_gotoxy(0,10);
lcd_putstring(buf);
voltage = (adc_value * 3.3) / 4095 ;
lcd_gotoxy(1,8);
sprintf(buf, "%3.2f", voltage);
lcd_putstring(buf);
}
////////// MAIN /////////////////
int main (void)
{
init_lcd();
Init_ADC();
lcd_putstring16(0,"** MICROLAB **");
lcd_putstring16(1,"** INSTRUMENTS **");
delay(60000);
delay(60000);
delay(60000);
lcd_putstring16(0,"ADC Value.. ");
lcd_putstring16(1,"voltage.......");
Additional Programs
DISPLAY DIGITAL OUTPUT FOR GIVEN ANALOG INPUT USING INTERNAL ADC
The other features like Burst Conversion, accessing different register for each channel, ADC conversion
depending on Timers,ADC Interrupts etc will be out of scope of this tutorial.
Later we will see how to interface a POT,LDR,Temp Sensor(LM35).
Finally we will see how to use the ExploreEmbedded libraries for ADC.
while(1)
{
Display_ADC();
delay(100000);
}
}
LCD Code:-
#include "lpc17xx.h"
#include "lcd.h"
void Lcd_CmdWrite(unsigned char cmd);
void Lcd_DataWrite(unsigned char dat);
#define LCDRS 9
#define LCDRW 10
#define LCDEN 11
#define LCD_D4 19
#define LCD_D5 20
#define LCD_D6 21
#define LCD_D7 22
#define LcdData LPC_GPIO0->FIOPIN
#define LcdControl LPC_GPIO0->FIOPIN
#define LcdDataDirn LPC_GPIO0->FIODIR
#define LcdCtrlDirn LPC_GPIO0->FIODIR
#define LCD_ctrlMask ((1<<LCDRS)|(1<<LCDRW)|(1<<LCDEN))
#define LCD_dataMask ((1<<LCD_D4)|(1<<LCD_D5)|(1<<LCD_D6)|(1<<LCD_D7))
ADC 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 familiar with LPC1768 ADC, you can explore the other features and the
associated registers.
Register Description
A/D Global Data Register: This register contains the ADC‟s DONE bit and the result of
ADGDR
the most recent A/D conversion
ADDR0 -
A/D Channel Data Register: Contains the recent ADC value for respective channel
ADDR7
ADSTAT A/D Status Register: Contains DONE & OVERRUN flag for all the ADC channels
ADCR
Bit 16 – BURST
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.
CLearing this bit will disable the BURST conversion.
Bit 27 - EDGE
This bit is significant only when the START field contains 010-111. It starts conversion on selected CAP
or MAT input.
0 - On Falling Edge
1 - On Rising Edge
ADGD
R
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.
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.
Result:
VIVA QUESTIONS
QUESTION BANK
6. Using the Internal PWM module of ARM controller generate PWM and vary its duty
cycle.
9. Interface a simple Switch and display its status through Relay, Buzzer and LED.
10. Measure ambient temperature using a sensor and SPI ADC IC.