Unit 3 - Real World Interfacing With ARM7 Based Microcontroller - Notes
Unit 3 - Real World Interfacing With ARM7 Based Microcontroller - Notes
LPC2148 has two inbuilt UARTs available i.e. UART0&UART1. So, we can connect two
UART enabled devices (GSM module, GPS module, Bluetooth module etc.) with LPC2148 at a
time.
UART0 and UART1 are identical other than the fact that UART1 has modem interface included.
Features of UART0
Features of UART1
One stop bit is sent by the transmitter. Word length, parity availability and type, and
numbers of stop bits all have to be agreed in advance for successful communication
because UART uses two wires. The transmitter of device-A connected to receiver of
device-B and receiver of device-A connected to transmitter of device-B. This is how
devices can send data simultaneously to each other, a mode of communication called
‘full duplex’.
LPC2148 ARM7 core supports two UART in it, UART0 and UART1. UART0 can be used as
general purpose UART and also can support ISP Programming through it, whereas UART1 has
additional modem support. Both have built in baud rate generator and 16-byte transmit and
receive FIFOs. For UART0 the TxD Pin is at P0.0 and RxD Pin is at P0.1 and similarly for
UART1 the TxD Pin is at P0.8 and RxD Pin is at P0.9 as shown in table below;
RS232 Level Converter
Most of microchips work on TTL or CMOS voltage level which can’t be used to communicate
over RS-232 protocol. In this case voltage or level converter is needed which can convert TTL to
RS-232 and RS-232 to TTL voltage levels. The most commonly used RS-232 level converter is
MAX3232 chip. This chip includes charge pump which can generate RS232 voltage levels (-10V
and +10V) from 5V power supply. It also includes two receiver and two transmitters and is
capable of full-duplex UART communication. RS232 communication enables point-to-point data
transfer, which often used in data acquisition applications and for data transfer between
microcontroller and PC.
Transmit Hold Register: This register contains 8-bit write data which can be
U0THR
transmitted through UART0. This is write only register.
Receive Buffer Register: This register contains 8-bit received data from
UART0. This data is nothing but top most byte of Rx FIFO. When we use 5, 6 or
U0RBR
7-bit data then remaining bits are padded with 0’s by default. This is read only
register.
Line Control Register: The value or settings in this register configure the
UART0 block. As this is an 8-bit register. There are several parameters
U0LCR configured through this register such as word length, stop bit, parity enable,
parity select, break control, divisor latch access bit. This register setting plays
important role while initializing UART0 before using it.
U0DLL & U0DLM are standard UART0 baud rate generator divider registers.
U0DLL
Each of this register holds 8-bit values. Together these registers form a 16-bit
&
divisor value which will be used for baud rate generation. This will be discussed
U0DLM
further while code explanation with respect to real world example.
Interfacing GPS with LPC2148 We now want to receive data from satellite to LPC2148 Primer
Board by using GPS module through UART0. The serial data is taken from the GPS module
through MAX232 into the SBUF register of LPC2148 microcontroller (refer serial interfacing
with LPC2148). The serial data from the GPS receiver is taken by using the Serial Interrupt of
the controller. This data consists of a sequence of NMEA sentences from which GPGGA
sentence is identified and processed. Pin Assignment with LPC2148
3. GSM Module Interfacing with LPC2148
GSM Module
• GSM/GPRS module is used to establish communication between a computer and a GSM-
GPRS system.
• Global System for Mobile communication (GSM) is an architecture used for mobile
communication in most of the countries.
• Global Packet Radio Service (GPRS) is an extension of GSM that enables higher data
transmission rate
AT Commands
• AT commands are used to control MODEMs.AT is the abbreviation for Attention.
• These commands come from Hayes commands that were used by the Hayes smart modems.
• The Hayes commands started with AT to indicate the attention from the MODEM.
• The dial up and wireless MODEMs need AT commands to interact with a computer.
• AT commands with a GSM/GPRS MODEM
Algorithm for GSM module interfacing with LPC2148
1) Start
2) Initialise UART0 or UART1 serial interfface using following i nstruction
PINSEL0=0X0000 0005;//Enable P0.0-TxD0,P0.1-RxD0
U0LCR=0X83; //8-BIT Character lenth,NO parity,1 stop bit
U0DLL=97; //Baud rate=9600@PCLK=15Mhz
U0LCR=0X03;//Dlab=0
3) Transmit different AT commands through UART module using instruction
while(!(U0LSR&0X20));//Monitor TI flag
4) If transmission buffer is Empty,Transmit AT commands
U0THR=ch;
5) Provide delay while transmitting each command
6) To transmit a single character use PUTCH function & to transmit a string use PUTS
function
7) END
3. On-chip ADC using interrupt
Introduction: ADC in LPC2148 ARM7 Microcontroller
The ADC in LPC2148 ARM7 Microcontroller is 10-bit successive approximation analog to
digital converter. The features are listed as:
▪ LPC2148 has two inbuilt ADC Modules, named as ADC0 & ADC1.
▪ ADC0 has 6-Channels (AD0.1-AD0.6).
▪ ADC1 has 8-Channels (AD1.0-AD1.7).
▪ ADC operating frequency is 4.5 MHz (max.), operating frequency decides the conversion
time.
▪ Supports power down mode.
▪ Burst conversion mode for single or multiple inputs.
There are several registers associated with ADC feature but we will mainly discussing about
ADC Control Register (ADCR) & ADC Global Data Register (ADGDR).
Register Description
ADxCR A/D COntrol Register: Used for Configuring the ADC
A/D Global Data Register: This register contains the ADC’s DONE bit and the result
ADxGDR
of the most recent A/D conversion
ADxDR0 -
A/D Channel Data Register: Contains the recent ADC value for respective channel
ADxDR7
ADxSTAT A/D Status Register: Contains DONE & OVERRUN flag for all the ADC channels
A/D Global Start Register: This address can be written (in the AD0 address range) to
ADxGSR
start conversions in both A/D converters simultaneously.
#include <lpc214x.h>
#include "serial.h"
#include <stdio.h>
char String[]="Wel-Come to BINARYUPDATES.COM, ADC and UART Configured
@LPC2148 \n\r Serial Communication @ 9600 baudrate, 8 bits, no Parity, 1 Stop bit\n\r\n";
char Newline[]="\n\r\n";
char adcreading[16] ;
void ADC_Init (void)
{
PINSEL1 = 0x01000000 ; // P0.28, AD0.1
}
unsigned int ADC_GetAdcReading()
{
unsigned int adcdata;
AD0CR = 0x01200302 ; // Select AD0.1, Select clock for ADC, Start of conversion
while(!((adcdata = AD0GDR) & 0x80000000)) // Check end of conversion (Done bit) and read
result
{
}
return((adcdata >> 6) & 0x3ff) ; // Return 10 bit result
}
int main(void)
{
unsigned int delay, adc;
initClocks(); // Set CCLK=60Mhz and PCLK=60Mhz
initUART0();
ADC_Init() ;
Send_String(String);
while(1)
{
adc = ADC_GetAdcReading();
sprintf(adcreading,"ADC0 CH1= %u",adc); // read data in decimal format
//sprintf(adcreading,"ADC0 CH1= 0x%03X",adc); // read data in hexx format
Send_String(adcreading);
Send_String(Newline);
for(delay=0; delay<10000000; delay++); // delay
}
}
4. Interfacing I2C – EEPROM
Fig. 1 shows how to interface the EEPROM with microcontroller through I2C. I2C is a Master-
Slave protocol. I2C has a clock pulse along with the data. Normally, the master device controls
the clock line, SCL. This line dictates the timing of all transfers on the I2C bus. No data will be
transferred unless the clock is manipulated. All slaves are controlled by the same clock, SCL.
I2c bus supports many devices, each device is recognized by a unique address—whether it’s a
micro-controller, LCD Driver, memory or keyboard interface and can operate as transmitter or
receiver based on the functioning of the device. The controller designed controls the EEPROM
device through I2C protocol. The I2C Controller here acts as a master device and controls
EEPROM which acts as a slave. The read-write operations are accomplished by sending a set of
control signals including the address and/or data bits. The control signals must be accompanied
with proper clock signals.
include <LPC214x.h>
#include <stdio.h>
#include <string.h>
#include "UART.h"
#define SW23 1<<24
#define SW24 1<<25
#define SW25 1<<26
#define MAX 10
#define AA 2
#define SI 3
#define STO 4
#define STA 5
#define I2EN 6 void I2C_ISR(void)__irq;
void Wait (unsigned int);
void I2C_Init (void); int I2C_Start (unsigned int Slave_Addr);
int I2C_Write (unsigned char *Buff, unsigned int Count);
char ReLoad[MAX] = {0x00,0x00,'A','R','M','7','P','R','I','M', 'E',
'R'};
char Buff[MAX] = {0x00,0x00,'A','R','M','7','P','R','I','M', 'E',
'R'};
unsigned char Rec[MAX] = {"NO-DATA!"};
unsigned char index = 0;
unsigned char flag = 0, ii, Ready=0, Erase = 0;
void I2C_ISR(void)__irq
{
if (I2C0CONSET & 0x08)
{
switch (I2C0STAT)
{
case (0x08): if (flag == 'W')
{
I2C0CONCLR = 1 << STO;
I2C0CONCLR = 1 << STA;
I2C0DAT = 0xA0;
I2C0CONCLR = 1 << SI;
}
else if (flag == 'R')
{ I2C0DAT = 0xA0;
I2C_Start (0xA1);
I2C0CONCLR = 1 <<
SI;
}
index = 0;
break;
case (0x10): I2C0CONCLR = 1 <<
STA; if (flag == 'W') I2C0DAT = 0xA0;
else if (flag == 'R')
{
I2C0CONCLR = 1 <<
STA;
I2C0CONCLR = 1 <<
STO;
I2C0DAT = 0xA1;
I2C0CONCLR = 1 <<
SI; index = 0;
}
break;
case (0x18): I2C0CONCLR = 0x20;
I2C0CONCLR = 0x38;
I2C0DAT = Buff[index];
index++; break;
case (0x20): I2C0CONCLR = 0x20;
I2C0CONCLR = 0x38;
I2C0DAT = Buff[index];
index++;
break;
case (0x28): if (index < MAX)
{
if (flag == 'W')
{ I2C0DAT = Buff[index];
I2C0CONCLR = 0x20; I2C0CONCLR = 0x38;
}
else if ((index > 1) &&
flag == 'R')
{
I2C0CONCLR = 0x18;
I2C0CONSET = 1 <<
STA;
}
else
{
I2C0DAT = Buff[index];
I2C0CONCLR = 0x20;
I2C0CONCLR = 0x38;
}
index++;
}
else
{
index = 0;
flag = 'R';
I2C0CONSET = 1 <<
STO; if (Erase == 1)
{
UART0_PutS ("\n\r MemoryErase successfull..! \n");
}
else
{
UART0_PutS ("\n\r Data Successfully Written on Memory!\n");
}
I2C0CONCLR = 1 << STA; I2C0CONCLR = 1 << SI; } break; case (0x30):
I2C0CONCLR = 0x20; if (index < MAX) { if (flag == 'W') { I2C0DAT =
Buff[index]; } index++;
}
else
{
index = 0;
flag = 0;
I2C0CONSET = 0x10;
I2C0CONCLR = 1 << SI;
}
break;
case (0x38): I2C0CONSET = 0x20;
break;
case (0x40): I2C0CONSET = 1 << AA;
I2C0CONCLR = 1 << STA;
I2C0CONCLR = 1 << STO;
I2C0CONCLR = 1 << SI;
break;
case (0x48): I2C0CONSET = 1 <<
STA;
break;
case (0x50): I2C0CONSET = 1 <<
AA;
if (index < MAX)
{
Rec [index] = I2C0DAT; index++;
}
else
{
I2C0CONSET = 1 << STO; I2C0CONCLR = 1 <<
SI; index = 0;
Ready = 'T';
}
break;
case (0x58): Rec [index] = I2C0DAT;
I2C0CONCLR = 1 << STA;
I2C0CONCLR = 1 << STO; break;
}
}
I2C0CONCLR = 1 <<
SI;
VICVectAddr = 0x00;
}
int main()
{
unsigned int i;
VPBDIV = 0x02;
PINSEL0 = 0x00000055;
//P0.3-SDA0 &
P0.2-SCL0 PINSEL2 = 0xFFFFFFF3;
IO1DIR = 0x00 <<
SW23;
UART0_Init (9600);
VICIntSelect = 0<<9;
VICVectCntl0 = 0x020 | 9;
VICVectAddr0 = (unsigned long)I2C_ISR;
VICIntEnable = 1<<19; I2C_Init();
UART0_PutS ("********* ARM Primer LPC-2148 I2CEEPROM Demo
**********\n\n\r");
UART0_PutS
(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\r");
UART0_PutS ("[~] Turn SW 23 ON to Write default data to EEPROM!
\n\r");
UART0_PutS ("[~] Turn SW 24 ON to Read and Display data from EEPROM!
\n\r");
UART0_PutS ("[~] Turn SW 25 ON to Erase data from EEPROM \n\r");
while (1) { if((IOPIN1 & SW23) == 0)
{ ii = 0;
while (ii < MAX)
{
Buff [ii] = ReLoad [ii];
ii++; }
Wait (5000);
flag = 'W';
I2C_Start (0x70);
for (i=0;i<30;i++) Wait(10000);
I2C0CONCLR = 1 << SI;
while (!(IOPIN1 & SW23));
Wait (5000);Wait (5000);
} else if ((IOPIN1 & SW24) == 0 { flag = 'R';
I2C_Start (0x70); for (i=0;i<30;i++) Wait(10000);
I2C0CONCLR = 1 << SI; while (Ready == 'F');
if (Ready == 'T') {
ii=0;
UART0_PutS ("\n\r The Read Data are: \t");
while (ii<MAX) { //U0THR = '\n';
Wait (1000);
U0THR = Rec[ii];
Wait (1000); ii++;
}
UART0_PutC ('\n');
Wait (1000);
Ready = 'F';
}
while (!(IOPIN1 & SW24));
Wait (5000);
Wait (5000);
Wait (5000);
Wait (5000);
} if ((IOPIN1 & SW25) == 0)
{ ii = 2; Erase = 1;
while (ii < MAX) { Buff[ii] = 0xFF; ii++;
} flag = 'W';
I2C_Start (0x70);
for (i=0;i<30;i++) Wait(10000);
I2C0CONCLR = 1 << SI;
while (!(IOPIN1 & SW25));
Wait (5000);Wait (5000);Wait (5000);Wait (5000);
}
}
}
void Delay(void)
{
unsigned int i,j;
for(i=0;i<150;i++)
for(j=0;j<900;j++);
}
void Wait (unsigned int Delay)
{
while(Delay--);
}
void I2C_Init (void)
{
I2C0SCLH = 150; //50%duty,I2CFreq->100KHz,PCLK=30MHz
I2C0SCLL = 150;
I2C0CONSET = 1 << I2EN; //Enable I2C 0
}
int I2C_Start (unsigned int Slave_Addr)
{
I2C0CONCLR = 1 << STO;
I2C0CONSET = 1 << AA;
I2C0CONSET = 1 << STA;
return 0;
}
int I2C_Write (unsigned char *Buff, unsigned int Count)
{
while(Count--)
{
I2C0DAT = *Buff++;
}
return 0;
}
5. On-chip DAC for waveform generation:
Introduction to DAC
Digital to Analog Converter (DAC) are mostly used to generate analog signals (e.g. sine
wave, triangular wave etc.) from digital values.
• LPC2148 has 10-bit DAC with resistor string architecture. It also works in Power
down mode.
• LPC2148 has Analog output pin (AOUT) on chip, where we can get digital value
in the form of Analog output voltage.
• The Analog voltage on AOUT pin is calculated as ((VALUE/1024) * VREF).
Hence, we can change voltage by changing VALUE(10-bit digital value) field in
DACR (DAC Register).
e.g. if we set VALUE = 512, then, we can get analog voltage on AOUT pin as
((512/1024) * VREF) = VREF/2.
DAC in LPC2148(ARM7)
http://www.electronicwings.com/arm7/lpc2148-dac-digital-to-analog-converter
*/
#include <lpc214x.h>
#include <stdint.h>
void delay_ms(uint16_t j)
{
uint16_t x,i;
for(i=0;i<j;i++)
{
uint16_t value;
uint8_t i;
i = 0;
PINSEL1 = 0x00080000; /* P0.25 as DAC output */
0xFFFFF0FF ); /* Input pins for switch. P0.8 sine, P0.9 t
IO0DIR = ( IO0DIR &
riangular, P0.10 sawtooth, P0.11 square */
uint16_t sin_wave[42] = { 512,591,665,742,808,873,926,968,998,1017,1
023,1017,998,968,926,873,808,742,665,591,512,
while(1)
{
while(i !=42)
{
value = sin_wave[i];
delay_ms(1);
i++;
}
i = 0;
}
value = 0;
while ( value != 1023 )
{
value++;
}
while ( value != 0 )
{
value--;
}
}
value = 0;
while ( value != 1023 )
{
value++;
}
}
value = 1023;
DACR = ( (1<<16) | (value<<6) );
delay_ms(100);
value = 0;
DACR = ( (1<<16) | (value<<6) );
delay_ms(100);
value = 1023;
DACR = ( (1<<16) | (value<<6) );
}
}
}