ARM PROGRAMS
GPIO
GPIO-LPC2129
P0.0 to P0.15 <======> PINSEL0 (32-Bit Register) ; (Reg_Bit_No= x*2+1: x*2) corresponds to P0.x
P0.16 to P0.30 <======> PINSEL1 (32-Bit Register); (Reg_Bit_No= x*2+1: x*2) EXCEPT P0.26
x= y-16 ; corresponds to P0.y
P1.16 - P1.31 <======> PINSEL2 (32-Bit Register)
PINSEL2 - pin2 :When 0, pins P1.31:26 are used as GPIO pins.
PINSEL2 - pin3 : When 0, pins P1.25:16 are used as GPIO pins.
1. Write a code to set P0.20 GPIO pin as o/p and HIGH without affecting other pins.
Logic:
I Configure Pin P0.20 as GPIO, using PINSEL1 (9:8)
II Configure the direction of the Pin P0.20 as o/p pin, using IO0DIR register
III Make P0.20 pin HIGH writing IO0SET register
CODE:
#include<LPC2129.H>
main(){
PINSEL1 &= ~(1<<8) ; To Reset PINSEL1(8) { alternative code (PINSEL1 &= 0xFFFF FEFF) }
PINSEL1 &= ~(1<<9) ; To Reset PINSEL1(9) ) { alternative code (PINSEL1 &=0xFFFF FDFF) }
IO0DIR |=(1<<20); To Set IO0DIR.20 and to make P0.20 in o/p mode ;{ alternative code (IO0DIR |=0x0010 0000) }
IO0SET |=(1<<20); To Set IO0SET.20 and to make P0.20 HIGH ;{ alternative code (IO0SET |=0x0010 0000) }
}
2. Write a code to configure P1.23 GPIO pin as o/p and make LOW without affecting other pins.
Logic:
I Configure Pin P1.23 as GPIO, using PINSEL2 (3)
II Configure the direction of the Pin P1.23 as o/p pin, using IO1DIR register
III Make P0.20 pin LOW writing IO1CLR register
CODE:
#include<LPC2129.H>
main(){
PINSEL2 &= ~(1<<3) ; To make p1.23 GPIO { alternative code (PINSEL2 &= 0xFFFF FFF7) }
IO1DIR |=(1<<23); To Set IO1DIR.23 and to make P1.23 in o/p mode
;{ alternative code ; (IO1DIR |=0x0080 0000) }
IO1CLR |=(1<<23); To set IO1CLR.23 and hence to make P1.23 LOW
;{ alternative code (IO1CLR |=0x0080 0000) }
3. GPIO –programming to turn - ON and turn - OFF LEDs ( Assume Common Anode)
Device GPIO Pin 'On' State PINSEL0
Cathode-LED1 p0.10 Low / 0 Bit 21:20
Cathode-LED2 p0.11 Low / 0 Bit 23:22
CODE:
include <LPC2129.H>
void Delay(void){
int i,j;
for(i=0; i<10; i++)
for(j=0;j<1000;j++);
int main(void){
PINSEL0 & = 0xFF0FFFFF; To configure P0.10, P0.11 as GPIOs
IO0DIR |= (1<<10) | (1<<11); To configure P0.10, P0.11 as o/p pins
while(1){
IO0CLR | = (1<<10) | (1<<11); To clear P0.10, P0.11 and hence TURN ON LED
Delay();
IO0SET | = (1<<10) | (1<<11); To set P0.10, P0.11 and hence TURN OFF LED
Delay();
return (0);
To Test GPIO pin
TEST_PIN=(IOxPIN & (1 << pinNumber)) ? 1 : 0;
OR
if ( (IOxPIN & (1 << pinNumber)) == "1" ) TEST_PIN=1;
else TEST_PIN=0;
4. Exercise: Toggling LEDs with a Button
objective: i) Test the LED functionality
ii) program to turn LED ON when button is pressed and OFF when button is released.
Assumptions:
1. Pin P0.10 (To cathode-LED; Common Anode type)
2. Pin P0.15 ( From push button; LOW ==> button is pressed and HIGH =Released)
LOGIC:
1. Configure pins as GPIOs
2. Set the direction of pushbutton to input with IODIR
3. Set the direction of LED to output with IODIR
4. Turn ON & OFF LED with some delay to test the functionality
i) Turn LED ON by setting P0.10 'LOW' ; Turn LED OFF by setting P0.10 'HIGH'
5. In an infinite loop ("while (1) { ... }"), do the following:
6. Read the current state of Button(P0.15) with IOPIN
7. If button is pressed (remember pressed = 'Low' or '0'), ...
8. ... turn the LED on by clearing P0.10 to 'Low'.
9. If a button is not pressed (released = 'High' or '1') ...
10. ... turn the LED off by setting P0.10 to 'High'
code:
#include "lpc2129.h"
#define LED_PIN (1 << 10)
#define BUTTON (1 << 15)
int getPinState(int pinNumber){
int PinsPort0 =IO0PIN; // Read the current state of all pins in GPIO ==> PORT0
int pinState = (PinsPort0 & (1 << pinNumber)) ? 1 : 0; // Read the value of 'pinNumber'
return pinState; // Return the value of pinState
void Delay(void){
int i,j;
for(i=0; i<10; i++)
for(j=0;j<1000;j++);
int main(void){
PINSEL0 & = 0x3FCF FFFF ; // To configure P0.10, P0.15 as GPIOs
IO0_IODIR &= ~BUTTON; // Set button as input
IO0DIR |= LED_PIN; // Set LED_PIN as output
// To TEST LED
GPIO0CLR |= LED_PIN; // Turn ON LED
Delay();
GPIO0SET |= LED_PIN; // Turn OFF LED
Delay();
while (1) {
// Check if button is pressed or not
if (getPinState(15)) IO0SET |= LED_PIN; // Button is currently 'high' Turn LED off
else IO0CLR |= LED_PIN; // Button is currently 'Low', Turn LED on
}
ADC
cclk=processor clock = Crystal freq= 60MHz(Max)
If VPBDIV=00 ====> pclk=(cclk/4)=15MHz (By default)
If VPBDIV=01 ====> pclk=cclk
If VPBDIV=10 ====> pclk=(cclk/2)=30MHz
*******************************************************************
LPC 2129 has 4-channel , 10-bit ADC(Successive Approx), conv Time = 2.44 mSec,
Basic clocking for the A/D converter is provided by the VPB clock. A programmable divider is included to scale
this clock to the 4.5 MHz (max) clock needed by the successive approximation process. A fully accurate
conversion requires 11 of these clocks.
Ain Range: 0V to 3V (Vss to V3A)
Dout = (2N-1)(Ain/ V3A)
***************************************************************************
Burst Mode; use Ain3, processor clock frequency=60MHz,Use ADC clock = 3MHz
cclk= 60MHz ; pclk=30MHz ===> VPBDIV = 0x00000002
pclk/ADC clk = (clkdiv+1)==> (clkdiv+1)= pclk/ADC clk =30MHz/3MHz=10 ===> clkdiv=9
4clk/3bits
ADCR: 0x 002F0908
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 9 8 7 6 5 4 3 2 1 0
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
X X X x 0 0 0 0 0 0 1 x 1 1 1 1 0 0 0 0 1 0 0 1 x x x x 1 0 0 0
ADDR
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 9 8 7 6 5 4 3 2 1 0
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
D D D D D D D D D D D
o 9 8 7 6 5 4 3 2 1 0
n
e
include<lpc2129.h>
VPBDIV = 0x00000002; // pclk=cclk/2 = 30MHz
int main(void){
ADCR= 0x002F0908; Ain3, ADC clk=3MHz, Burst mode, 4 clk / 3-bits;PDN=1;
while(1) A2D();
void A2D(void){
int ADC_VAL, CNT;
ADCR |=0x01000000; // Start of Conversion
do{
ADC_VAL = ADDR ; // Read ADC data register
} while( (ADC_VAL & 0x80000000) ==0 ); // DONE ?
ADCR &= 0xF8FFFFFF; // Stop conversion
ADC_VAL =( (ADC_VAL >>6) & 0x000003FF ) ; //Read ADC value in LS 10 bits
}
UART
P0.0 / TxD0 / PWM1 P0.1 / RxD0 / PWM3 / EINT0
UART Programming
Write a C code to transmit the message "SERIAL" first, then what ever data is received
serially, should be sent back serially using UART0. Assume 8-bit character size, 1-
stop bit, even parity, 9600 baud rate, processor clock=60MHz.
// Baud Rate Calculation
pclk 30 MHz
value= = =195 .31≈195≈0 xC 3
// 16 X 9600 16 X 9600
#include <lpc2129.h>
#include <stdio.h>
void init_serial (void);
int putchar (int ch);
int getchar (void);
int main(void){
char *Ptr = "SERIAL";
VPBDIV = 0x02; // pclk = 30MHz
init_serial();
while (*Ptr){
putchar(*Ptr++);
}
while(1){
putchar(getchar());
}
}
void init_serial (void){
PINSEL0 = 0x00000005; // TX & RX pins are configured
U0LCR = 0x0000009B; //8-bit character ;1-stop bit; even parity & Enable access to Divisor Latch
U0DLL = 0x000000C3; //BR =9600
U0LCR &= ~(1<<7); //Disable access to Divisor Latch
}
int putchar (int ch){
while (!(U0LSR & 0x20)); // Wait Till U0THR Empty
return (U0THR = ch);
}
int getchar (void){
while (!(U0LSR & 0x01)); // Wait till RBR FULL
return (U0RBR);
}
Solution for II TEST ARM-15
Develop a C code to generate a square wave on pin P0.5, when a key is pressed and stop the
square wave when this key is released. Assume that the key is connected to P0.10 of LPC 2129.
#include "lpc2129.h"
#define OUT_WAVE (1 << 5)
#define IN_KEY (1 << 10)
int getPinState(int pinNumber){
int PinsPort0 =IO0PIN; // Read the current state of all pins in GPIO ==> PORT0
int pinState = (PinsPort0 & (1 << pinNumber)) ? 1 : 0; // Read the value of 'pinNumber'
return pinState; // Return the value of pinState
}
void Delay(void){
int i,j;
for(i=0; i<10; i++)
for(j=0;j<1000;j++);
}
int main(void){
PINSEL0 & = 0xFFCFF3FF ; // To configure P0.10, P0.15 as GPIOs
IO0DIR &= ~IN_KEY; // Set key as input
IO0DIR |= OUT_WAVE ; // Set OUT_WAVE as output
while (1) {
// Generate Sq. Wave as long as key is pressed
if ( getPinState (10) ){
do{
IO0SET |= OUT_WAVE ; // p0.5 is made 'HIGH'
Delay();
IO0CLR |= OUT_WAVE ; // p0.5 is made 'LOW'
Delay();
} while (getPinState(10)) ;
}
if ( !getPinState(10) ){
do{
IO0CLR |= OUT_WAVE ;
} while(!getPinState(10)) ;
}
}
}
b) Develop a C code to convert an analog signal at pin Ain1 to digital value. For a cclk = 40MHz,
VPBDIV=0x02, configure ADC clock as 4MHz , in burst mode, for a conversion time of
1microsec with best precision possible.
pclk=20MHz., burst bit=1, clkdiv+1 =20M/4M=5; clkdiv =4; tc=1Microsec => clks=1microx4M=4
4clk/3 bits ==> clks = 111
Now ADCR=0x002F0402
include<lpc2129.h>
VPBDIV = 0x00000002; // pclk=cclk/2 = 20MHz
int main(void){
ADCR=0x002F0402; Ain1, ADC clk=4MHz, Burst mode, 4 clk / 3-bits;PDN=1;
while(1) A2D();
}
void A2D(void){
int ADC_VAL, CNT;
ADCR |=0x01000000; // Start of Conversion
do{
ADC_VAL = ADDR ; // Read ADC data register
} while( (ADC_VAL & 0x80000000) ==0 ); // DONE ?
ADCR &= 0xF8FFFFFF; // Stop conversion
ADC_VAL =( (ADC_VAL >>6) & 0x000003FF ) ; //Read ADC value in LS 10 bits
}
Configure the following LPC 2129 pins ( Ref fig1) i) AIN 2 ii) RxD0 iii)TxD0 iv) EINT3 for the
desired function. 6
i)AIN 2; p0.29 (01); ===> PINSEL1[27:26]=01
ii) RxD0 ; p0.1(01) ==> PINSEL0[3:2]=01 iii)TxD0:p0.0(01) ==> PINSEL0[1:0]=01
iv) EINT3; p0.9(11)===> PINSEL0[19:18]=11
PINSEL0 |=0x000C0005;
PINSEL0 &=0xfffffff5;
PINSEL1 |=0x04000000;
PINSEL1 &=0xf7ff ffff;