GRACE COLLEGE OF ENGINEERING
Tiruchendur Road, Thoothukudi - 628 005
LAB MANUAL
Department of Electrical and Electronics Engineering
B.E. – Electrical and Electronics Engineering
Subject : EE3018 Embedded Processor (lab)
Sem: VI
Year: III
Period: Jan2024 – May 2024
Prepared by HOD/EEE PRINCIPAL
1. Laboratory exercise:
a) Programming with IDE - ARM microcontroller
b) Advanced Timer Features, PWM Generator.
c) RTC interfacing with ARM using Serial communication programming, Stepper motor control.
d) ARM-Based Wireless Environmental Parameter Monitoring System displayed through Mobile device.
2. Seminar: a) ARM and GSM/GPS interfacing b) Introduction to ARM Cortex Processor
3. Raspberry Pi based Mini project.
[Link] OF ARM EVALUATION SYSTEM.
Aim :
To study the ARM7TDMI-S CPU based 32 bit microcontroller (LPC2148) features, Block
diagram, Pin diagram and Program used Register description.
Architecture of ARM Microcontroller:
The ARM (Advanced RISC Machine) has launched several processors that have different
features as well as the different cores for a wide variety of applications. The first ARM
architecture design has 26-bit processors, but now it reached 64-bit processors. The general
expansion of ARM products cannot be categorized into some particular information. But
ARM products can be understood based on its architecture. The standard ARM series
processors available in the market are starting from ARM7 to ARM11. These processors have
several features like cache, Data Tightly Coupled memory, MPU, MMU, etc. Some of the
widely known ARM processor series are ARM926EJ-S, ARM7TDMI, and ARM11 MPCore.
This article is particularly intended for ARM7 based LPC2148 microcontroller architecture
overview which will give you brief information about the microcontroller architecture.
The ARM7 is a 32-bit general-purpose microprocessor, and it offers some of the features like
little power utilization, and high performance. The architecture of an ARM is depended on
the principles of RISC. The associated decode mechanism, as well as the RISC- instructions
set are much easy when we compare with micro programmed CISC-Complex Instruction Set
Computers.
Interrupt sources Every peripheral device consists of a single interrupt line allied to the VIC
(vector interrupt controller), although it can have various interrupt flags inside. Individual
interrupt flags can also signify one or more interrupt resources.
The program application may also erase while the application of the program is running,
permitting flexibility of data storage field firmware improvements, etc. Because of the
selection of an architectural solution for an on-chip bootloader, the available memory for the
microcontrollers LPC2141/42/44/46/48 is 32-kilobytes, kilobytes, 128-kilobytes, 256-
kilobytes, & 500-kilobytes. The flash memory of these microcontrollers’ offers 1, 00,000
erase per cycles and data preservation for many years.
Pin Connect Block
This block permits chosen pins of the ARM7 based LPC2148 microcontroller for having
several functions. The multiplexers can be controlled by the configuration registers for
allowing the link between the pin as well as on-chip peripherals.
Peripherals must be coupled with the suitable pins previous to being triggered, and previous
to any connected interrupts being permitted. The microcontroller functionality can be defined
by the pin control module by its pin selection of registers in a given hardware environment.
After rearranging all pins of ports (port 0 & port 1) are arranged as i/p by the given
exceptions. If debug is allowed
If debug is allowed, the pins of the JTAG will guess the functionality of JTAG. If a trace is
allowed, then the Trace pins will guess the functionality of trace. The pins connected to the
I2C0 and I2C1 pins are open drain.
GPIO- General Purpose Parallel Input/output
GPIO registers control the device pins which are not linked to a particular peripheral
function. The device pins can be arranged as i/p[s or o/ps. Individual registers allow for
clearing any number of o/p’s concurrently. The output register value can be read back, & the
present condition of the port pins. These microcontrollers begin an accelerated function over
LPC200 devices.
General-purpose input/output registers are moved to the processor bus used for the best
probable I/O time.
These registers are addressable bytes.
The total value of a port can be
The complete value of the port can be written in the only instruction
LPC2148 Features
1. 16-bit/32-bit ARM7TDMI-S microcontroller in a tiny LQFP64 package.
2. 40 kB of on-chip static RAM and 512 kB of on-chip flash memory.
3. In-System Programming/In-Application Programming (ISP/IAP) via on-chip boot
loader software.
4. Embedded ICE RT and Embedded Trace interfaces offer real-time debugging with the
on-chip Real Monitor software and high-speed tracing of instruction execution.
5. USB 2.0 Full-speed compliant device controller with 2 kB of endpoint RAM.
6. Two 10-bit ADCs provide a total of 14 analog inputs
7. Single 10-bit DAC provides variable analog output
8. Two 32-bit timers/external event counters (with four capture and four compare
channels each), PWM unit (six outputs) and watchdog.
9. Low power Real-Time Clock (RTC) with independent power and 32 kHz clock input.
10. Multiple serial interfaces including two UARTs, two Fast I²C-bus (400 kbit/s), SPI
and SSP with buffering and variable data length capabilities.
11. Vectored Interrupt Controller (VIC) with configurable priorities and vector addresses.
12. Up to 45 of 5 V tolerant fast general purpose I/O pins in a tiny LQFP64 package.
13. 60 MHz maximum CPU clock available from programmable on-chip PLL with
settling time of 100 us.
14. On-chip integrated oscillator operates with an external crystal from 1 MHz to 25 MHz
15. Power saving modes include Idle and Power-down.
16. Individual enable/disable of peripheral functions as well as peripheral clock scaling
for additional power optimization.
17. Processor wake-up from Power-down mode via external interrupt or BOD.
18. Single power supply chip with POR and BOD circuits:
LPC2148 (32-bit ARM7TDMI-S processor) GPIO Ports and Registers
Introduction
General-purpose input/output (GPIO) is a pin on an IC (Integrated Circuit). It can be either
input pin or output pin, whose behaviour can be controlled at the run time. A group of these
pins is called a port (Example, Port 0 of LPC2148 has 32 pins).
LPC2148 has two 32-bit General Purpose I/O ports.
1. PORT0
2. PORT1
PORT0 is a 32-bit port
Out of these 32 pins, 28 pins can be configured as either general purpose input or output.
1 of these 32 pins (P0.31) can be configured as general-purpose output only.
3 of these 32 pins (P0.24, P0.26 and P0.27) are reserved. Hence, they are not available for
use. Also, these pins are not mentioned in pin diagram.
PORT1 is also a 32-bit port. Only 16 of these 32 pins (P1.16 – P1.31) are available for use as
general-purpose input or output.
Almost every pin of these two ports has some alternate function available. For example, P0.0
can be configured as the TXD pin for UART0 or as PWM1 pin as well. The functionality of
each pin can be selected using the Pin Function Select Registers.
Note : The Port 0 pins do not have built-in pull-up or pull-down resistors. Hence, while using
GPIOs on Port 0, in some cases, we need to connect pull-up or pull-down resistors
externally.
Pin Function Select Registers
Pin Function Select Registers are 32-bit registers. These registers are used to select or
configure specific pin functionality.
There are 3 Pin Function Select Registers in LPC2148:
1. PINSEL0 : - PINSEL0 is used to configure PORT0 pins P0.0 to P0.15.
2. PINSEL1 : - PINSEL1 is used to configure PORT0 pins P0.16 to P0.31.
3. PINSEL2 : - PINSEL2 is used to configure PORT1 pins P1.16 to P1.31.
Let’s see GPIO registers that control the GPIO operations.
Fast and Slow GPIO Registers
There are 5 Fast (also called Enhanced GPIO Features Registers) GPIO Registers and 4 Slow
(also called Legacy GPIO Registers) GPIO Registers available to control PORT0 and
PORT1.
The Slow Registers allow backward compatibility with earlier family devices using the
existing codes.
Slow GPIO Registers
There are 4 Slow GPIO registers :
1. IOxPIN (GPIO Port Pin value register): This is a 32-bit wide register. This register is used
to read/write the value on Port (PORT0/PORT1). But care should be taken while writing.
Masking should be used to ensure write to the desired pin.
Examples :
a) Writing 1 to P0.4 using IO0PIN
IO0PIN = IO0PIN | (1<<4)
b) Writing 0 to P0.4 using IO0PIN
IO0PIN = IO0PIN & (~(1<<4) )
c) Writing F to P0.7-P0.4
IO0PIN = IO0PIN | (0x000000F0)
2. IOxSET (GPIO Port Output Set register) : This is a 32-bit wide register. This register is
used to make pins of Port (PORT0/PORT1) HIGH. Writing one to specific bit makes that pin
HIGH. Writing zero has no effect.
3. IOxDIR (GPIO Port Direction control register) : This is a 32-bit wide register. This
register individually controls the direction of each port pin. Setting a bit to ‘1’ configures the
corresponding pin as an output pin. Setting a bit to ‘0’ configures the corresponding pin as an
input pin.
4. IOxCLR (GPIO Port Output Clear register) : This is a 32-bit wide register. This register is
used to make pins of Port LOW. Writing one to specific bit makes that pin LOW. Writing
zeroes has no effect.
Examples :
a) Configure pin P0.0 to P0.3 as input pins and P0.4 to P0.7 as output pins.
IO0DIR = 0x000000F0;
b) Configure pin P0.4 as an output. Then set that pin HIGH.
IO0DIR = 0x00000010; OR IO0DIR = (1<<4);
IO0SET = (1<<4);
c) Configure pin P0.4 as an output. Then set that pin LOW.
IO0DIR = 0x00000010; OR IO0DIR = (1<<4);
IO0CLR = (1<<4);
Result :
Thus study of Arm processor has been done and ensured its composition with internal
[Link] LED AND PWM.
Aim:
To write the program for LED(Toggling & Shift) and PWM interfacing with LPC2148.
Connection Details for LED:
P0.16-P0.23 connect to LED I/P 1-8 burg pins by burg wires.
Connection Details for PWM :
P0.0 connect to +ve(Red) Probe teriminal of CRO/DSO.
Gnd connect to -ve(Block) Probe teriminal of CRO/DSO.
3.1.1/Program for Toggling LED:
#include<LPC214x.h> / / Define LPC2148 Header File
#define led IO0PIN / / Define LED to Port0
#define tled IO0DIR
void delay(int x);
int main()
{
tled = 0x00FF0000; / / Define P0.16 – P0.23 as O/P
while(1) / / Loop forever
{
led = 0x00AA0000; / / Turn ON P0.16 – P0.23
delay(2000);
led = 0x00550000; / / Turn OFF P0.16 – P0.23
delay(2000);
}
}
void delay(int x)
{
unsigned int k,l;
for(k = x;k > 0;k --)
for(l = 0;l < x;l++);
}
[Link] for shifting LED:
#include<LPC214x.h> / / Define LPC2148 Header File
#define led IO0 PIN / / Define LED to Port1
#define tled IO 0DIR / / Define Port1 as output
void delay(int x);
int main()
{
long int i,j=0x1;
tled = 0x00FF0000; / / Define P0.16 – P0.23 as O/P
while(1) / / Loop forever
{
for(i=16;i<24;i++)
{
led= j <<i;
delay(2000);
}
}
}
void delay(int x)
{
unsigned int k,l;
for(k = x;k > 0;k --)
for(l = 0;l < x;l++);
}
3.1.3 .Program for 75% PWM Wave form:
#include <lpc214x.h>
void PWM_Init( )
{
PINSEL0 = 0x00000002; /* set GPIOs for PWM1*/
PWMTCR = 0x00000002; /* Counter Reset */ PWMPR
= 0x00000000; /* count frequency:Fpclk */
PWMLER = 0x0000007F; /* all PWM latch enabled */
}
void PWM_Set()
{
PWMMR0 = 2000; / / Total count.
PWMMR1 = 1500; / / On time count.
}
void PWM_Start( void )
{
PWMPCR = 0x00000200; /* Selects single edge controlled mode for PWM1 output
enabled.*/
PWMTCR = 0x09; /* counter enable, PWM enable */
}
int main(void)
{
PWM_Init( ); /* PWM Init */
PWM_Set(); /* Set % PWM Cycle */
PWM_Start(); /* Start PWM genration */
while(1);
}
Result:
Thus the Toggling LED, Shifting LED and PWM output was verified .
[Link] REAL TIME CLOCK AND SERIAL PORT.
4.1 . INTERFACING REAL TIME CLOCK WITH LPC2148.
Aim:
To write the program for on chip Real Time Clock or Calendar interfacing with LPC2148.
Connection Details for RTC:
P1.16-P1.23 connect to the LCD datelines of D0-D7 burg pins by burg wires.
P0.8 connect to the LCD RS(Register Select) burg pin by burg wire.
P0.9 connect to the LCD R/W(Read/Write) burg pin by burg wire.
P0.10 connect to the LCD ENA(Enable) burg pin by burg wire.
4.1 Program for Onchip RTC:
#include <lpc214x.h>
unsigned char arr1[16]="REAL TIME CLOCK";
unsigned char h1,h2,m1,m2,s1,s2;
#define lcd_data IO1PIN
#define EN 0x00000400
#define RW 0x00000200
#define RS 0x00000100
void DelayMs(unsigned int ms);
void lcd_cmd(unsigned char value);
void lcd_dat(unsigned char item);
void lcd_data_string(unsigned char *str);
void init_rtc(void);
void rtc_int(void)__irq
{
ILR = 0x01;
}
int main(void)
{
VPBDIV = 0x02;
DelayMs(1000);
IO0DIR=0x00000700;
IO1DIR=0x00FF 0000;
lcd_cmd(0x38);
lcd_cmd(0x0C);
lcd_cmd(0x01);
lcd_cmd(0x06);
lcd_cmd(0x80);
lcd_data_string(arr1);
init_rtc();
while(1)
{ lcd_cmd(0xC4);
lcd_dat(HOUR/ 10 + '0');
lcd_dat(HOUR%10 + '0');
lcd_dat(':') ;
lcd_dat(MIN/ 10 + '0');
lcd_dat(MIN%10 + '0');
lcd_dat(':'); lcd_dat(SEC/
10 + '0');
lcd_dat(SEC%10 + '0');
}
}
void DelayMs(unsigned int ms)
{
long i,j;
for (i = 0; i < ms; i++ ) for
(j = 0; j < 6659; j++ );
}
void busy_check()
{
DelayMs(5);
}
void lcd_cmd(unsigned char value)
{
busy_check();
IO0CLR=RS;
IO0CLR=RW;
lcd_data=(value<<16);
IO0SET=EN;
IO0CLR=EN;
return;
}
void lcd_dat(unsigned char item)
{
busy_check();
IO0SET=RS;
IO0CLR=RW;
lcd_data=(item<<16);
IO0SET=EN;
IO0CLR=EN;
return;
}
void lcd_data_string(unsigned char *str) / / Program to send string to LCD
{
int i=0;
while(str[i]!=' \ 0')
{
lcd_dat(str[i]); i++;
DelayMs(5);
}
return;
}
Output:
Result:
Thus the RTC operation was verified in LCD using LPC2148 ARM kit.
4.2. INTERFACING SERIAL PORT WITH LPC2148 ARM KIT
Aim:
To write the program for write the strings to UART-0 serial port.
Connection Details for Serial:
No need external connection except from serial cable.
[Link] FOR ONCHIP UART-0:
#include <LPC214x.H> /* LPC214xdefinitions */
/****************************************************************************************
UART0 Initialization
* Description : This function Initializes the UART0.
* Note : This function should be called once before any of the other functions of UART0.
***********************************************************************************
void UART0_Init( )
{
PINSEL0 = 0x00000005; /* lower 4bit selected for UART0 and remaining all bits selected for GPIO's.*/
/* frist LSB 2bit(0 and 1 bits) selected 01b for UART0 Tx.*/
/* LSB bit(2 and 3 bits) selected 01b for UART0 Rx.*/
U0LCR = 0x83; /* 0x83: enable Divisor Latch access, set 8 -bit word length,no Parity,1 Stop bit*/
VPBDIV = 0x01; /* VPBDIV: VPB bus clock divider 0x01: PCLK = processor clock*/
/* ----------------------------------------------------------------------------------------------- */
// BAUD RATE CALCULATION
// DIVISOR = (PCLK/(16*DESIRED_BAUDRATE))
// For Example
// Peripheral Clock Frequency (PCLK) = 60 Mhz
// Desired Baud Rate = 9600 bps
// Divisor = (60000000/(16*9600)) = 390(Decimal) =186(Hex)
/ / -----------------------------------------------------------------------------------------------
U0DLL = 0x86;
U0DLM = 0x01;
U0LCR = 0x03; /* 0x03: same as above, but disable Divisor Latch access.*/
}
/******************************************************************************************
Send_Char
* Description : Write a character to Serial Port
unsigned char Send_Char(unsigned char ch)
{
if (ch == ' \ n')
{
while(!(U0LSR & 0x20));
U0THR='\ r'; /* output CR */
}
while(!(U0LSR & 0x20));
return (U0THR = ch);
}
void Send_String(unsigned char *ch)
{
while(*ch != ' \ 0')
{
Send_Char(*ch++);
}
}
/********************************************************************************************
Main Routine
******************************************************************************
nt main (void)
{
int i;
UART0_Init(); /* Init UART 0 */
while (1) /* Infinite Loop */
{
Send_String("IElec Systems.,Nellai \ n");
}
}
Output:
Result:
Thus the strings write to serial UART -0 and verified by Hyper Terminal .
ARM with GSM Interface :
Components Required
GSM SIM900A module
LPC2148 Development Board
GSM Interfacing with LPC2148
Connection
Micro controller’s RX (P0.1) is connected to the GSM module’s TX and Micro
controller’s TX(P0.0) is Connected to the GSM module’s RX pin.
Code:
SMS Sending Code
This code is used to send the message to a particular number.
#include <lpc214x.h>
#define NUMBER "9876543210" //Here insert your number where you want to
send message
void ser_init(void);
void tx(unsigned char c);
unsigned char rx(void);
void tx_str(unsigned char *s);
void sms(unsigned char *num1,unsigned char *msg);
void gsm_delay(void);
unsigned int dell;
int main()
{
ser_init();
sms(NUMBER, "Welcome to the Embetronicx");
while(1);
}
void sms(unsigned char *num1,unsigned char *msg)
{
tx_str("AT");
tx(0x0d);
gsm_delay();
tx_str("AT+CMGF=1");
tx(0x0d);
gsm_delay();
tx_str("AT+CMGS=");
tx('"');
while(*num1)
tx(*num1++);
tx('"');
tx(0x0d);
gsm_delay();
while(*msg)
tx(*msg++);
tx(0x1a);
gsm_delay();
}
void gsm_delay()
{
unsigned long int gsm_del,ff;
for(gsm_del=0;gsm_del<=500000;gsm_del++)
for(ff=0;ff<25;ff++);
}
void ser_init()
{
VPBDIV=0x02; //PCLK = 30MHz
PINSEL0=0x5;
U0LCR=0x83;
U0DLL=195;
U0DLM=0;
U0LCR=0x03;
U0TER=(1<<7);
}
void tx(unsigned char c)
{
U0THR=c;
while((U0LSR&(1<<5))==0);
}
void tx_str(unsigned char *s)
{
while(*s) {
tx(*s++);
}
}
unsigned char rx()
{
while((U0LSR&(1<<0))==0);
return U0RBR;
}
Calling Code
This code is used to Call a particular number.
#include <lpc214x.h>
#define NUMBER "9876543210" //Here insert your number where you want to
send message
void ser_init(void);
void tx(unsigned char c);
unsigned char rx(void);
void tx_str(unsigned char *s);
void call(unsigned char *num2);
void gsm_delay(void);
unsigned int dell;
int main()
{
ser_init();
call(NUMBER);
while(1);
}
void call(unsigned char *num2)
{
tx_str("AT");
tx(0x0d);
gsm_delay();
tx_str("AT+CMGF=1");
tx(0x0d);
gsm_delay();
tx_str("ATD");
while(*num2)
tx(*num2++);
tx(';');
tx(0x0d);
for(dell=0;dell<=30;dell++)
gsm_delay();
tx_str("ATH");
tx(0x0d);
gsm_delay();
}
void gsm_delay()
{
unsigned long int gsm_del,ff;
for(gsm_del=0;gsm_del<=500000;gsm_del++)
for(ff=0;ff<25;ff++);
}
void ser_init()
{
VPBDIV=0x02; //PCLK = 30MHz
PINSEL0=0x5;
U0LCR=0x83;
U0DLL=195;
U0DLM=0;
U0LCR=0x03;
U0TER=(1<<7);
}
void tx(unsigned char c)
{
U0THR=c;
while((U0LSR&(1<<5))==0);
}
void tx_str(unsigned char *s)
{
while(*s) {
tx(*s++);
}
}
unsigned char rx()
{
while((U0LSR&(1<<0))==0);
return U0RBR;
}
GPS Module Interfacing with ARM LPC2148
Introduction
NEO-6M GPS Receiver Module
Global Positioning System (GPS) makes use of signals sent by satellites in space
and ground stations on Earth to accurately determine their position on Earth.
Radio Frequency signals sent from satellites and ground stations are received by
the GPS. GPS makes use of these signals to determine its exact position.
The GPS itself does not need to transmit any information.
The signals received from the satellites and ground stations contain time stamps
of the time when the signals were transmitted.
By calculating the time difference between the time the signal was transmitted
and the time the signal was received, and using the speed of the signal, the
distance between the satellites and the GPS can be determined using a simple
formula for distance using speed and time.
Using information from 3 or more satellites, the exact position of the GPS can be
triangulated.
For more information about GPS and how to use it, refer the topic GPS Receiver
Module in the sensors and modules section.
The GPS receiver module uses UART communication to communicate with
controller or PC terminal.
For information about UART in LPC2148 and how to use it, refer the
topic UART in LPC2148 in the ARM7-LPC2148 inside section.
Interfacing Diagram
Interfacing NEO-6M GPS Receiver Module with LPC2148
Example
We are going to display data (latitude, longitude, altitude and time) received by
the GPS receiver module on a serial monitor using UART.
The “$GPGGA” string is parsed to extract the time, latitude, longitude and
altitude information.
Program
/*
GPS interfacing with LPC2148(ARM7)
*/
#include <lpc214x.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char
Latitude_Buffer[15],Longitude_Buffer[15],Time_Buffer[15],Altitude_Buffer[8];
char iir_val[10];
char GGA_String[150];
uint8_t GGA_Comma_Pointers[20];
char GGA[3];
volatile uint16_t GGA_Index, CommaCounter;
bool IsItGGAString = false;
__irq void UART0_Interrupt(void);
void delay_ms(uint16_t j)
{
uint16_t x,i;
for(i=0;i<j;i++)
{
for(x=0; x<6000; x++); /* loop to generate 1 milisecond delay with Cclk =
60MHz */
}
}
void UART0_init(void)
{
PINSEL0 = PINSEL0 | 0x00000005; /* Enable UART0 Rx0 and Tx0
pins of UART0 */
U0LCR = 0x83; /* DLAB = 1, 1 stop bit, 8-bit character length */
U0DLM = 0x00; /* For baud rate of 9600 with Pclk = 15MHz */
U0DLL = 0x61; /* We get these values of U0DLL and U0DLM from
formula */
U0LCR = 0x03; /* DLAB = 0 */
U0IER = 0x00000001; /* Enable RDA interrupts */
}
void UART0_TxChar(char ch) /* A function to send a byte on UART0 */
{
U0IER = 0x00000000; /* Disable RDA interrupts */
U0THR = ch;
while( (U0LSR & 0x40) == 0 ); /* Wait till THRE bit becomes 1
which tells that transmission is completed */
U0IER = 0x00000001; /* Enable RDA interrupts */
}
void UART0_SendString(char* str) /* A function to send string on UART0 */
{
U0IER = 0x00000000; /* Disable RDA interrupts */
uint8_t i = 0;
while( str[i] != '\0' )
{
UART0_TxChar(str[i]);
i++;
}
U0IER = 0x00000001; /* Enable RDA interrupts */
}
__irq void UART0_Interrupt(void)
{
int iir_value;
char received_char;
iir_value = U0IIR;
received_char = U0RBR;
if( received_char == '$' )
{
GGA_Index = 0;
CommaCounter = 0;
IsItGGAString = false;
}
else if( IsItGGAString == true ) /* If $GPGGA
string */
{
if ( received_char == ',' )
{
GGA_Comma_Pointers[CommaCounter++] = GGA_Index; /*
Store locations of commas in the string in a buffer */
}
GGA_String[GGA_Index++] =
received_char; /* Store the $GPGGA string in a buffer */
}
else if( ( GGA[0] == 'G' ) && ( GGA[1] == 'G' ) &&
( GGA[2] == 'A' ) ) /* If GGA string received */
{
IsItGGAString = true;
GGA[0] = GGA[1] = GGA[2] = 0;
}
else /* Store received character */
{
GGA[0] = GGA[1];
GGA[1] = GGA[2];
GGA[2] = received_char;
}
VICVectAddr = 0x00;
}
void get_Time(void)
{
U0IER = 0x00000000; /* Disable RDA interrupts */
uint8_t time_index=0;
uint8_t index;
uint16_t hour, min, sec;
uint32_t Time_value;
/* parse Time in GGA string stored in buffer */
for(index = 0; GGA_String[index]!=','; index++)
{
Time_Buffer[time_index] = GGA_String[index];
time_index++;
}
Time_value = atol(Time_Buffer); /* convert string to integer */
hour = (Time_value / 10000); /* extract hour from integer */
min = (Time_value % 10000) / 100; /* extract minute from
integer */
sec = (Time_value % 10000) % 100; /* extract second from
integer*/
sprintf(Time_Buffer, "%d:%d:%d", hour,min,sec);
U0IER = 0x00000001; /* Enable RDA interrupts */
}
void get_Latitude(uint16_t Latitude_Pointer)
{
U0IER = 0x00000000; /* Disable RDA interrupts */
uint8_t lat_index = 0;
uint8_t index = (Latitude_Pointer+1);
/* parse Latitude in GGA string stored in buffer */
for(;GGA_String[index]!=',';index++)
{
Latitude_Buffer[lat_index]= GGA_String[index];
lat_index++;
}
float lat_decimal_value, lat_degrees_value;
int32_t lat_degrees;
lat_decimal_value = atof(Latitude_Buffer); /* Latitude in
[Link] */
/* convert raw latitude into degree format */
lat_decimal_value = (lat_decimal_value/100); /* Latitude in
[Link] */
lat_degrees = (int)(lat_decimal_value); /* dd of latitude */
lat_decimal_value = (lat_decimal_value - lat_degrees)/0.6; /*
.mmmm/0.6 (Converting minutes to eequivalent degrees) */
lat_degrees_value = (float)(lat_degrees + lat_decimal_value); /*
Latitude in [Link] format */
sprintf(Latitude_Buffer, "%f", lat_degrees_value);
U0IER = 0x00000001; /* Enable RDA interrupts */
}
void get_Longitude(uint16_t Longitude_Pointer)
{
U0IER = 0x00000000; /* Disable RDA interrupts */
uint8_t long_index = 0;
uint8_t index = (Longitude_Pointer+1);
/* parse Longitude in GGA string stored in buffer */
for(;GGA_String[index]!=',';index++)
{
Longitude_Buffer[long_index]= GGA_String[index];
long_index++;
}
float long_decimal_value, long_degrees_value;
int32_t long_degrees;
long_decimal_value = atof(Longitude_Buffer); /* Longitude in
[Link] */
/* convert raw longitude into degree format */
long_decimal_value = (long_decimal_value/100); /* Longitude in
[Link] */
long_degrees = (int)(long_decimal_value); /* ddd of Longitude */
long_decimal_value = (long_decimal_value - long_degrees)/0.6; /*
.mmmmmm/0.6 (Converting minutes to eequivalent degrees) */
long_degrees_value = (float)(long_degrees + long_decimal_value); /* Longitude in [Link] format */
sprintf(Longitude_Buffer, "%f", long_degrees_value);
U0IER = 0x00000001; /* Enable RDA interrupts */
}
void get_Altitude(uint16_t Altitude_Pointer)
{
U0IER = 0x00000000; /* Disable RDA interrupts */
uint8_t alt_index = 0;
uint8_t index = (Altitude_Pointer+1);
/* parse Altitude in GGA string stored in buffer */
for(;GGA_String[index]!=',';index++)
{
Altitude_Buffer[alt_index]= GGA_String[index];
alt_index++;
}
U0IER = 0x00000001; /* Enable RDA interrupts */
}
int main(void)
{
GGA_Index = 0;
memset(GGA_String, 0 , 150);
memset(Latitude_Buffer, 0 , 15);
memset(Longitude_Buffer, 0 , 15);
memset(Time_Buffer, 0 , 15);
memset(Altitude_Buffer, 0 , 8);
VICVectAddr0 = (unsigned) UART0_Interrupt; /* UART0 ISR
Address */
VICVectCntl0 = 0x00000026; /* Enable UART0 IRQ slot */
VICIntEnable = 0x00000040; /* Enable UART0 interrupt */
VICIntSelect = 0x00000000; /* UART0 configured as IRQ */
UART0_init();
while(1)
{
delay_ms(1000);
UART0_SendString(GGA_String);
UART0_SendString("\r\n");
UART0_SendString("UTC Time : ");
get_Time();
UART0_SendString(Time_Buffer);
UART0_SendString("\r\n");
UART0_SendString("Latitude : ");
get_Latitude(GGA_Comma_Pointers[0]);
UART0_SendString(Latitude_Buffer);
UART0_SendString("\r\n");
UART0_SendString("Longitude : ");
get_Longitude(GGA_Comma_Pointers[2]);
UART0_SendString(Longitude_Buffer);
UART0_SendString("\r\n");
UART0_SendString("Altitude : ");
get_Altitude(GGA_Comma_Pointers[7]);
UART0_SendString(Altitude_Buffer);
UART0_SendString("\r\n");
UART0_SendString("\r\n");
memset(GGA_String, 0 , 150);
memset(Latitude_Buffer, 0 , 15);
memset(Longitude_Buffer, 0 , 15);
memset(Time_Buffer, 0 , 15);
memset(Altitude_Buffer, 0 , 8);
}
}
Raspberry Pi: Python Scripting the GPIO
Introduction: Raspberry Pi: Python Scripting the GPIO
The GPIO: General Purpose Input/Output lets you interface your Raspberry Pi
with the outside world, making it a powerful interactive device for just $40-$50.
This Instructable will show you how to install the GPIO package on your
Raspberry Pi and how to wire up a simple push button circuit with an LED.
Step 1: Gather Your Components
Components
* Raspberry Pi
* Cobbler breakout board with cable — you can order this from Adafruit for $8.
* Breadboard
* Wires — breadboard or otherwise
* standard LED
* 270 Ohm resistor
* 1K resistor
* 10K resistor
* Push button
* USB power for RPI (not pictured)
* Monitor + keyboard (not pictured)
Tools
* wire-stripper
* small diagonal snips
* multimeter for checking continuity
Step 2: Assemble Your Circuit
We will have a simple push button that will turn an LED on when the button is
pressed and off when it is released. I know, it's not super-exciting, but think of
this as a building block for digital input and output.
Here is the schematic and breadboard diagram.
The LED is straightforward: 270 Ohm resistor is needed to light up the LED from
a 3.3V input.
The concept is simple: the LED is an output of pin 4 and the button is an input of
pin 22. The button circuit has a pull-down resistor. Pin 22 will be pulled down to
zero through the 10K resistor when the button is inactive. When it gets pressed,
the 3.3V power from the Raspberry Pi goes into the pin 22 input, bypassing the
10K resistor.
Without the 10K resistor, you'll have a floating input and will get erratic behavior
in your code. The 1K resistor protects the Raspberry Pi from too much current.
Step 3: Putting It on the Breadboard
After doing the wiring diagram in Fritzing, I laid out the components on a real
breadboard. Strip the wires and use the diagonal snips for a clean-looking
breadboard.
This is what it looks like with the Cobbler breakout board before I attach the
ribbon cable to the Pi.
Even with a simple circuit like this, double-check your components to make sure
you're not shorting your circuit or anything else like that.
Step 4: Connect to the Pi
Use the breakout cable and connect the cobbler to your Raspberry Pi.
You will want to be connected to the internet to download the latest packages via
Wifi or an Ethernet cable.
Power up your Raspberry Pi.
Step 5: Install the GPIO Package
The Raspberry Pi GPIO libraries may come with the latest versions of Wheezy,
but maybe not.
Just in case, I suggest installing them again, which involves first installing the
Python Development toolkit that [Link] uses and then the GPIO package
itself.
Type in
sudo apt-get install python-dev
Then, for the GPIO libraries:
sudo apt-get install [Link]
If asked for confirmation on either of these, press Y
You'll get the usual Linux garble like this. In my case, the Python development
tools were not installed but GPIO was.
Step 6: Blink an LED in Python
At this point, I run the Raspberry Pi from my monitor with a keyboard plugged in
— I usually do the package updates from ssh. On the command line, create a new
python script by invoking nano.
sudo nano gpio_blink.py
And enter in this script. The advantage with using ssh is that you can just copy-
and-paste the script. Alternatively, I have this on a GitHub repository.
# gpio_blink.py
# by Scott Kildall ([Link])
# LED is on pin 4, use a 270 Ohm resistor to ground
import [Link] as GPIO
import time
[Link](False)
[Link]([Link])
[Link](4, [Link])
state = True
# endless loop, on/off for 1 second
while True:
[Link](4,True)
[Link](1)
GPIO. output(4,False)
[Link](1)
Ctrl-X, Y to save the file.
Now run the script:
sudo python gpio_blink.py
Note: you have to invoke sudo — root access for the GPIO library.
You should have a blinking LED on your circuit. We're not using the switch at all
at this point.
Ctrl-C to exit the script
how it works
- Pin 4 is an input pin. We alternate between high (True) and low (False) for 1
second at a time.
- I turn warnings off because I was getting errors in my script because the GPIO
wasn't properly closed (this shouldn't matter and I found it an annoyance).
- Setting the mode to BCM means that the pin numbers etched on the Raspberry
Cobbler match the ones that you are using in your code.
Step 7: Python Script for Switch-activated LED
Now, we'll try adding a switch, using the same circuit.
Type in:
sudo nano gpio_blink.py
You can also refer to the GitHub repository, if need be.
# gpio_swtich.py
# by Scott Kildall ([Link])
# LED is on pin 4, use a 270 Ohm reistor to ground
# Switch is on pin 22, use a pull-down resistor (10K) to ground
import [Link] as GPIO
import time
[Link](False)
[Link]([Link])
[Link](4, [Link])
[Link](22,[Link])
# input of the switch will change the state of the LED
while True:
[Link](4,[Link](22))
[Link](0.05)
Cntl-X, Y to save the file
(note the indentations af
Now run the script:
sudo python gpio_switch.py
If you press the switch, the LED should turn on and when you let it go, it should
turn off. Congratulations, you have an input and output into your Raspberry Pi.
how it works
This is like the previous script, except that we are designating Pin 22 as an input
pin. We set the output of Pin 4 to match the input of Pin 22. When Pin 22 goes
high, so does Pin 4. The [Link](0.05) is there to account for any debouncing
in the button.
Step 8: Troubleshooting...or Done!
Troubleshooting
There's a lot that can go awry with electronics and interfacing with the outside
world. Here are some suggestions for things to look for:
- If you're getting no flashing LED or the switch doesn't seem to work, check your
breadboard connections or the switch doesn't work, check your breadboard
connections. Make sure you have the right components in the right places. Test
for continuity with a multimeter.
- Make sure your LED is facing the right direction. Flat side goes to ground.
Longer lead is oriented to the positive electron flow.
- You can test your LED and the GPIO connection by connecting the LED to the
3.3V output of the GPIO and to the 270 Ohm resistor and to the ground of the
GPIO