Cycle-II
Introduction to ARM7 Development BoardIntroduction to ARM Board (LPC2148)
This section of the document introduces LPC2148 microcontroller board based on a 16-bit/32-bit ARM7TDMI-S CPU with real-time emulation and embedded trace support, that combine microcontrollers with embedded high-speed flash memory ranging from 32 kB to 512 kB. A 128-bit wide memory interface and unique accelerator architecture enable 32-bit code execution at the maximum clock rate. Forcritical code size applications, the alternative 16-bit Thumb mode reduces code by more than 30% with minimal performance penalty. The meaning of LPC is Low Power Low Cost microcontroller. This is 32 bit microcontroller manufactured by Philips semiconductors (NXP).Due to their tiny size and low power consumption, LPC2148 is ideal for applications where miniaturization is a key requirement, such as access control and point-of-sale.
1.1 Features of ARM Microcontroller1. 16-bit/32-bit ARM7TDMI-S microcontroller in a tiny LQFP64 package. 8 kB to
40 kB of on-chip static RAM and 32 kB to 512 kB of on-chip flash memory; 128-bit wide interface/accelerator enables high-speed 60 MHz operation.
2. In-System Programming/In-Application Programming (ISP/IAP) via on-chip boot loader software, single flash sector or full chip erase in 400 ms and programming of 256 Bytes in 1 ms 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.
3. USB 2.0 Full-speed compliant device controller with 2kB of endpoint RAM. In addition, the LPC2148 provides 8 kB of on-chip RAM accessible to USB by DMA.
4. One or two (LPC2141/42 vs, LPC2144/46/48) 10-bit ADCs provide a total of 6/14 analog inputs, with conversion times as low as 2.44 ms per channel.
5. Single 10-bit DAC provides variable analog output (LPC2148 only) Two 32-bit timers/external event counters (with four capture and four compare channels each), PWM unit (six outputs) and watchdog.
Fig. No. 1 ARM7 Development BoardArchitecture:
The ARM7 core is based on the von Neumann architecture with 32-bit data bus that
carries both instruction and data. Data can be of 8 bits, 16 bits, 32 bits. It has following features:
· Instruction pipeline
· Memory format
· Operation modes
· Coprocessor
· Debugging feature
Instruction pipeline:
The ARMv7 core uses a three stage pipeline to increase the flow of instructions to the
processor. This allows multiple simultaneous operations to take place and continuous operations
and memory systems. The instructions are executed in three stages:
· Fetch
· Decode
· Execute.
Operating modes:
The ARMv7 core has seven modes of operation:
· User mode – normal ARM program execution mode and used for executing most
application programs.
· Fast Interrupt (FIQ) – mode supports data transfer or channel processes to allow very
fast interrupt
· Interrupt (IRQ) – mode is used for general purpose interrupt handling.
· Supervisor (SVC) – is protected mode for operating system.
· Abort (ABT) – mode is entered after a data or instruction fetch is aborted.
· Undefined (UND) – mode is entered when an undefined instruction is executed
Arm Board descriptionPower:
DC 6.5V with power LEDOn-board linear regulators generate +3.3V/500mA
and +5v/500mA from power supply.USB connector ( as alternate power source).
Connectors:
Extension headers for all microcontroller pins.
RS232 connectors (2).
VGA connector.
PS/2 connector.
JTAG connector.
SD/MMC connector.
USB B-type connector with Link-LED.
All peripheral configurable via jumpers.
Other Peripherals:
256Kb I2C based EEPROM
Audio power amplifier.
2 line X 16 character LCD with back light control.
Configurable for manual and automatic program download(ISP) via serial
port.
8 controllable LEDs on SPI using 74HC595.
EXP.NO:01 DATE:
STUDY OF REALTIME OPERATING SYSTEM (UCOS-II)
OBJECTIVE: To study the real time operating system -UCOS.
REQUIREMENT ANALYSIS
Software requirements:
C-language
ARM GCC Tools
Keil µ vision 4
Flash magic device programmer
Hyper terminal.
Hardware requirements:
ARM7 Trainer Kit LPC2148
Power supply
RS232
THEORY: UCOS-II
uC/OS-II is a priority-based preemptive multi-tasking real-time operating system,
including a real-time kernel, task management, time management, inter-task
communication synchronization (semaphores, mailboxes, message queues), and memory
management functions. 它可以使各个任务独立工作,互不干涉,很容易实现准时而
且无误执行,使实时应用程序的设计和扩展变得容易,使应用程序的设计过程大为
减化。
It enables all tasks to work independently, and mutual non interference, it is easy
to achieve timely and accurate implementation of real-time applications to the design and
expansion easier, the application of the design process greatly reduced. 而且它内核源代
码公开,可移植性强,为编程人员提供了很好的一个软件平台。 And its kernel
source code open, portability strong, and the programming staff provided a good one
software platform.
Multi-tasking:
μC/OS-II can manage up to 64 tasks, however, the current version of the software
reserves eight (8) of these tasks for system use. This leaves your application with up to 56
tasks. Each task has a unique priority assigned to it which means that μC/OS-II cannot do
round robin scheduling. There are thus 64 priority levels.
Task stacks:
Each task requires its own stack, however, μC/OS-II allows each task to have a
different stack size. This allows you to reduce the amount of RAM needed in your
application. With μC/OS-II’s stack checking feature, you can determine exactly how
much stack space each task actually requires.
Procedure:
Go to start open RUN command in that type cmd then press enter.
Then command prompt is opened, verify whether the GNUARM tool is installed properly
or not by giving DOS command that PATH.
Then enter into the folder path where we created the make file. Then pass the command
that makefile. This GCC command will generate the hex file(.exe file).
Execution process:
Open the Flash magic which is a device programmer.
In device programmer select the Controller type, operating frequency and browse the
corresponding hex file then Press start which means loading of hex file.
comport : com 1
Baud rate : 19200
Device : LPC 2148
Frequency: 12 MHz
Before starting dumping process reset the trainer kit.
FLOWCHART:
SOURCE CODE: /* * Simple uCOS-II application.
#include "includes.h"
#include "LPC2148.h"
#include <stdio.h>
#include "UART0.h"
OS_STK TestTask1Stack[100];
void TestTask1(void *pdata);
OS_STK TestTask2Stack[100];
void TestTask2(void *pdata);
int main (void)
{
unsigned int i, j;
PINSEL0 = 0x00000005;
OSInit();
OSTaskCreate(TestTask1, (void *)0, &TestTask1Stack[99], 0);
OSStart();
return 0;
}
void TestTask1(void *pdata)
{
timer_init();
InitUart0();
puts("Demonstrating the multitasking feature of uC/OS-II.\n");
OSTaskCreate(TestTask2, (void *)0, &TestTask2Stack[99], 1);
while(1) {
puts("Task 1 running, sleeping for 4 seconds\n");
OSTimeDlyHMSM(0, 0, 4, 0);
}
}
void TestTask2(void *pdata)
{
while(1) {
puts("Task 2 running, sleeping for 1 second\n");
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
Result: The UCOS real time system is studied. The outputs task1 and task2 with time delays
1sec and 4 sec are displayed on hyperterminal.
EXP.NO:02 DATE:
SERIAL COMMUNICATION DEVICE DRIVER (SOFTWARE_UART)
OBJECTIVE: To study the serial communication device driver (software_uart)
REQUIREMENT ANALYSIS
Software requirements:
C-language
ARM GCC Tools
Keil µ vision4
Flash magic device programmer
Hyper terminal
Hardware requirements:
ARM7 Trainer Kit LPC2148
Power supply
RS232
Theory:
Transmission model Figure 1 “Software UART transmission model” show details of the
transmission model that is implemented in this software UART. An assumption was made that
once a waveform is started to be generated (i.e. the transmitter (Tx) line goes low because of the
start” bit) the CPU should have minimal involvement all the way till the end of the “stop” bit.
Having the requested waveform finished, the sw UART Tx checks for more data in the Tx FIFO.
If there is none, it turns itself off. Otherwise, the next available character is fetched from the Tx
FIFO and the cycle is repeated.
There are two routines provided with the demo code one can use to write into the Tx FIFO. They
are swu_tx_wr_chr(unsigned char) and swu_tx_wr(unsigned char*). The first one updates the Tx
FIFO content with a new character if the Tx FIFO is not full. Otherwise, this routine will sit and
wait for the software UART Tx to send at least one character and make more space available.
“Software UART reception model” illustrates fundamentals of the receiving process
implemented here.
A single falling edge on the Rx line triggers a reception of the character. TIMER0 with its ability
to capture timestamp of an edge event on the dedicated input is the perfect candidate to provide
hardware support for the software Rx UART.
Similarly to the way the software UART Tx functionality is implemented, it is the edges in
the received waveform that are used by the software UART Rx to estimate the actual data
sent. In this process the software UART keeps track of all input line level changes using
the TIMER0 CAP0 pin. At the same time, sampling points located in the middle of each of
the data bits in the waveform are compared against the timestamps the TIMER0 capture
pin provides. If an edge is recorded between two sampling points, the next data bit will be
different from the previous one. It is the change in the input line level that drives the whole
reception process. Once the second reference point is reach (the center of the “stop” bit),
the received content is tested for framing error. After this the data is stored in the Rx FIFO.
Procedure:
Go to start open RUN command in that type cmd then press enter.
Then command prompt is opened, verify whether the GNUARM tool is installed properly
or not by giving DOS command that PATH.
Then enter into the folder path where we created the make file. Then pass the command
that make file. This GCC command will generate the hex file(.exe file).
Execution procedure:
Open the Flash magic which is a device programmer.
In device programmer select the Controller type, operating frequency and browse the
corresponding hex file then Press start which means loading of hex file.
comport : com 1
Baud rate : 19200
Device : LPC 2148
Frequency: 12 MHz
Before starting dumping process reset the trainer kit.
FLOWCHART:
SOURCECODE:
#include "LPC214x.h"
#define U32 unsigned long int
#define pin_txpro ((U32)1<<10)
#define pin_int ((U32)1<<12)
#define pin_inttx ((U32)1<<15)
#define pin_intrx ((U32)1<<17)
#define pin_call ((U32)1<<18)
#define pin_swrx ((U32)1<<30)
//void T0_Handler(void) __attribute__ ((interrupt("IRQ")));
//void IRQ_default(void) __attribute__ ((interrupt("IRQ")));
void T0_Handler(void) __irq;
void IRQ_default(void) __irq;
volatile unsigned char cnt_edges;
volatile unsigned char edge_index;
volatile unsigned char swu_tx_st;
volatile unsigned long int edge[11];
volatile unsigned char last_edge_index, char_end_index;
void swu_tx(void);
#define TXBUFF_LEN 16
#define RXBUFF_LEN 16
//12000000/9600 = 1250 PCLKs
//PCLK=12MHz:
#define BIT_LENGTH 6250
//60000000/9600 = 6250 PCLKs
//PCLK=60MHz:
//#define BIT_LENGTH 6250
#define STOP_BIT_SAMPLE (9*BIT_LENGTH)
volatile unsigned long int swu_status;
#define RX_OVERFLOW 4
#define RX_ACTIVE 2
#define TX_ACTIVE 1
#define ADJUST (1<<30)
#define ALL1 0x000000FF
volatile unsigned long int tx_fifo_wr_ind,tx_fifo_rd_ind;
volatile signed long int swu_tx_cnt, swu_tx_trigger;
volatile unsigned short int swu_tx_fifo[TXBUFF_LEN];
void swu_tx_wr(unsigned char *);
void swu_tx_wr_chr(unsigned char);
volatile unsigned long int rx_fifo_wr_ind,rx_fifo_rd_ind;
volatile signed long int swu_rx_cnt, swu_rx_trigger;
volatile unsigned char swu_bit, cnt, cnt_bits, swu_rx_chr_fe;
volatile unsigned long int swu_rbr, swu_rbr_mask;
volatile signed long int edge_last, edge_sample, edge_current, edge_stop;
volatile unsigned short int swu_rx_fifo[RXBUFF_LEN];
unsigned char swu_rx_rd_chr(void);
void swu_rx_isr(void);
int main(void)
{
PCONP = 0x00000000; //turn off all peripherals
VPBDIV = 0x01; //PCLK = CCLK
//setup the software uart
swu_tx_cnt = 0; //no data in the swu tx FIFO
tx_fifo_wr_ind = 0; //last char written was on 0
tx_fifo_rd_ind = 0; //last char updated was on 0
swu_rx_trigger = 1; //>=1 char gnrts a rx interrupt
swu_status = 0; //neither tx nor rx active
//TIMER0 setup
PCONP |= (1<<1); //enable TIMER0 clock
T0TCR = 0x00; //stop TIMER0
T0TCR = 0x02; //reset counters
T0TCR = 0x00; //release the reset
T0IR = 0x0FF; //clear all TIMER0 flags
T0PR = 0x00000000; //no prescaler
T0MR0 = 0x3FFFFFFF; //TIMER0 counts 0 - 0x3FFFFFFF
T0MCR = 2; //reset TIMER0 on MR0
T0EMR = 0x0008; //drive MAT0.3 high
T0TCR = 0x01; //let TIMER0 run
//VIC setup
VICIntSelect = 0x00000000; //all interrupts are IRQs
VICIntEnClr = 0xFFFFFFF0; //disable all interrupts
VICVectCntl0 = 0x20 | 4; //use slot 0 for TIMER0
VICVectAddr0 = (unsigned long)T0_Handler; //set the TIMER0 handler
VICDefVectAddr = (unsigned long)IRQ_default; //set the default handler
VICIntEnable = 1<<4; //enable TIMER0 interrupts
//port pin control: P0.29
PINSEL0 = 0x00000000; //P0 pins are GPIOs except...
PINSEL1 = (PINSEL1 & 0xC3FFFFFF) | 0x3C000000; //...
P0.30:CAP0.0,P0.29:MAT0.3
IODIR0 = pin_txpro | pin_int | pin_inttx | pin_intrx | pin_call;//set indicator pins to high...
IOSET0 = pin_txpro | pin_int | pin_inttx | pin_intrx | pin_call; //...
IOSET0 = pin_txpro | pin_int | pin_inttx | pin_intrx | pin_call; //...
while((IOPIN0&pin_swrx)==0); //wait for 1 on sw UART rx line
T0IR = 0x10; //clear CAP0.0 flag
T0CCR = 0x0006; //int on CAP0.0 falling edge
cnt_bits = 0; //reset the rx bit count
//main demo code outputs a greeting message and
//waits for user's input to echo it
swu_tx_wr("\x0D\x0A\x0D\x0A\x0D\x0A\x0D\x0A");
swu_tx_wr("Software UART demo code\x0D\x0A");
swu_tx_wr("=======================\x0D\x0A");
swu_tx_wr("This application echoes characters entered by the user.\x0D\x0A");
swu_tx_wr_chr('\x0D');
swu_tx_wr_chr('\x0A');
swu_tx_wr("Echo: ");
while(1); //idle loop
}
void swu_tx(void)
{
unsigned char bit,i;
unsigned long int ext_data, delta_edges, mask, reference;
IOCLR0 = pin_txpro; //indicate routine begin
if(tx_fifo_wr_ind!=tx_fifo_rd_ind)
{ //data to send, proceed
swu_status |= TX_ACTIVE; //sw uart tx is active
tx_fifo_rd_ind++; //update the tx fifo ...
if(tx_fifo_rd_ind==TXBUFF_LEN) //read index...
tx_fifo_rd_ind = 0; //...
ext_data = (unsigned long int) swu_tx_fifo[tx_fifo_rd_ind]; //read the data
ext_data = 0xFFFFFE00 | ( ext_data<<1); //prepare the pattern
edge[0] = BIT_LENGTH; //at least 1 falling edge...
cnt_edges = 1; //... because of the START bit
bit = 1; //set the bit counter
reference = 0x00000000; //init ref is 0 (start bit)
mask = 1<<1; //prepare the mask
delta_edges = BIT_LENGTH; //next edge at least 1 bit away
while(bit!=10)
{ //until all bits are examined
if((ext_data&mask)==(reference&mask))
{ //bit equal to the reference?
delta_edges += BIT_LENGTH; //bits identical=>update length
} //...
else{ //bits are not the same:
edge[cnt_edges] = //store new...
edge[cnt_edges-1] + delta_edges; //... edge data
reference = ~reference; //update the reference
delta_edges = BIT_LENGTH; //reset delta_ to 1 bit only
cnt_edges++; //update the edges counter
}
mask = mask<<1; //update the mask
bit++; //move on to the next bit
}
edge[cnt_edges]= //add the stop bit end...
edge[cnt_edges-1]+delta_edges; //... to the list
cnt_edges++; //update the number of edges
last_edge_index = cnt_edges-2; //calculate the last edge index
char_end_index = cnt_edges-1; //calc. the character end index
edge_index = 0; //reset the edge index
reference = T0TC + BIT_LENGTH; //get the reference from TIMER0
for(i=0;i!=cnt_edges;i++) //recalculate toggle points...
edge[i] = (edge[i] + reference) //... an adjust for the...
& 0x3FFFFFFF; //... timer range
T0MR3 = edge[0]; //load MR3
T0MCR = T0MCR | (1<<9); //enable interrupt on MR3 match
T0EMR = T0EMR | (3<<10); //enable toggle on MR3 match
}
IOSET0 = pin_txpro; //indicate routine exit
return; //return from the routine
}
void T0_Handler(void) __irq
{
signed long int edge_temp;
IOCLR0 = pin_int; //indicate TIMER0 isr activity
//sw uart receive isr code begin
if((T0IR&0x10)!=0x00)
{ //capture interrupt occured:
IOCLR0 = pin_intrx; //rx interrupt activity begin
T0IR = 0x10; //edge dtcted=>clear CAP0 flag
T0CCR = 0x0004 | (0x0003 - (T0CCR&0x0003)); //change the targeted edge
if((swu_status&RX_ACTIVE)==0)
{ //sw UART not active (start):
edge_last = (signed long int) T0CR0; //initialize the last edge
edge_sample = edge_last+(BIT_LENGTH>>1);//initialize the sample
edge
if(edge_sample<edge_last) //adjust the sample edge...
edge_sample |= ADJUST; //... if needed
swu_bit = 0; //rx bit is 0 (a start bit)
T0IR = 0x02; //clear MAT1 int flag
edge_stop = edge_sample+STOP_BIT_SAMPLE;//estimate the end of the
byte
if (edge_stop<edge_last) //adjust the end of byte...
edge_stop |= ADJUST; //... if needed
T0MR1 = edge_stop; //set MR1 (stop bit center)
T0MCR = T0MCR | (1<<3); //int on MR1
cnt = 9; //initialize the bit counter
swu_status |= RX_ACTIVE; //update the swu status
swu_rbr = 0x0000; //reset the sw rbr
swu_rbr_mask = 0x0001; //initialize the mask
}
else{ //reception in progress:
edge_current = (signed long int) T0CR0; //initialize the current edge
if (edge_current<edge_last) //adjust the current edge...
edge_current |= ADJUST; //... if needed
while(edge_current>edge_sample)
{ //while sampling edge is within
if(cnt_bits!=0)
{
if(swu_bit!=0) //update data...
swu_rbr |= swu_rbr_mask; //...
swu_rbr_mask = swu_rbr_mask<<1; //update mask
}
cnt_bits++; //update the bit count
edge_temp = edge_last + BIT_LENGTH; //estimate the last edge
if(edge_temp<edge_last) //adjust...
edge_last = edge_temp | ADJUST; //... the last edge...
else //... if...
edge_last = edge_temp; //... needed
edge_temp = edge_sample+BIT_LENGTH; //estimate the sample
edge
if(edge_temp<edge_sample) //adjust...
edge_sample = edge_temp|ADJUST; //... the sample edge...
else //... if...
edge_sample = edge_temp; //... needed
cnt--; //update the no of rcved bits
}
swu_bit = 1 - swu_bit; //change the received bit
}
IOSET0 = pin_intrx; //rx interrupt activity end
}
if((T0IR&0x02)!=0x00)
{ //stop bit timing matched:
IOCLR0 = pin_intrx; //rx interrupt activity begin
T0IR = 0x02; //clear MR1 flag
if(cnt!=0)
{ //not all data bits received...
swu_rbr = swu_rbr<<cnt; //... make space for the rest...
if(swu_bit!=0) swu_rbr += ALL1<<(8-cnt);//... add needed 1(s)...
} //...
swu_rbr &= 0x00FF; //extract data bits only
if(swu_bit==0) //if the stop bit was 0 =>
swu_rbr |= 0x00000100; //... framing error!
swu_status &= ~RX_ACTIVE; //sw UART not active any more
cnt_bits = 0; //reset the rx bit count
if(swu_rx_cnt!=RXBUFF_LEN)
{ //store the rcved character...
swu_rx_cnt++; //... into the sw UART...
rx_fifo_wr_ind++; //... rx FIFO
if(rx_fifo_wr_ind==RXBUFF_LEN) rx_fifo_wr_ind = 0; //...
swu_rx_fifo[rx_fifo_wr_ind] = swu_rbr; //...
if(swu_rx_cnt>=swu_rx_trigger) swu_rx_isr(); //rx 'isr' trig excded
}
else{
swu_status |= RX_OVERFLOW; //rx FIFO full => overflow
}
T0MCR &= ~(7<<3); //MR0 impacts TIMER0 no more
IOSET0 = pin_intrx; //rx interrupt activity end
}
//sw uart receive isr code end
//sw uart transmit isr code begin
if((T0IR&0x08)!=0){ //tx routine interrupt begin
IOCLR0 = pin_inttx; //tx interrupt activity begin
T0IR = 0x08; //clear the MAT3 flag
if(edge_index==char_end_index)
{ //the end of the char:
T0MCR &= ~(7<<9); //MR3 impacts T0 ints no more
swu_tx_cnt--; //update no.of chars in tx FIFO
if(tx_fifo_wr_ind!=tx_fifo_rd_ind) //if more data pending...
swu_tx(); //... spin another transmission
else
swu_status &= ~TX_ACTIVE; //no data left=>turn off the tx
}
else{ //not the end of the character:
if(edge_index==last_edge_index) //is this the last toggle?
T0EMR = 0x000003FF; //no more toggle on MAT3
edge_index++; //update the edge index
T0MR3 = edge[edge_index]; //prepare the next toggle event
}
IOSET0 = pin_inttx; //tx interrupt activity end
} //tx routine interrupt end
//sw uart transmit isr code end
VICVectAddr = 0xFF; //update the VIC
IOSET0 = pin_int; //indicate TIMER1 isr end
}
void IRQ_default(void) __irq//default IRQ isr
{
VICVectAddr=0xFF; //update the VIC
}
//this routine transfers a string of characters one by one into
//the software UART tx FIFO
void swu_tx_wr(unsigned char *ptr_out)
{
while(*ptr_out!=0x00)
{ //read all chars...
swu_tx_wr_chr(*ptr_out); //...put the char in tx FIFO...
ptr_out++; //...move to the next char...
} //...
return; //return from the routine
}
//this routine puts a single character into the software UART tx FIFO
void swu_tx_wr_chr(unsigned char out_char)
{
IOCLR0 = pin_call; //write access to tx FIFO begin
while(swu_tx_cnt==TXBUFF_LEN); //wait if the tx FIFO is full
tx_fifo_wr_ind++; //update the write pointer...
if(tx_fifo_wr_ind==TXBUFF_LEN) //...
tx_fifo_wr_ind = 0; //...
swu_tx_fifo[tx_fifo_wr_ind] = out_char; //put the char into the FIFO
swu_tx_cnt++; //update no.of chrs in the FIFO
if((swu_status&TX_ACTIVE)==0) swu_tx(); //start tx if tx is not active
IOSET0 = pin_call; //write access to tx FIFO end
return; //return from the routine
}
//this routine reads a single character from the software UART rx FIFO
//if no new data is available, it returns the last one read; framing error
//indicator is updated, too
unsigned char swu_rx_rd_chr(void)
{
if(swu_rx_cnt!=0)
{ //update the rx indicator...
rx_fifo_rd_ind++; //... if data are present...
if(rx_fifo_rd_ind==RXBUFF_LEN) rx_fifo_rd_ind = 0; //...
swu_rx_cnt--; //...
}
if((swu_rx_fifo[rx_fifo_rd_ind]&0x0100)==0) //update...
swu_rx_chr_fe = 0; //... the framing error...
else //... indicator...
swu_rx_chr_fe = 1; //...
swu_status &= ~RX_OVERFLOW; //clear the overfloe flag
return((unsigned char)(swu_rx_fifo[rx_fifo_rd_ind]&0x00FF)); //return data
}
//this code acts as a standard uart rx interrupt routine for the specified
//received count character trigger; this routine is called at the end
//of the received byte that increased overall number of characters in the
//rx FIFO to or beyond the specified trigger
void swu_rx_isr(void)
{
swu_tx_wr_chr(swu_rx_rd_chr()); //transmit the last rcvd char
return; //return from the routine
}
RESULT: Serial communication software uart is studied.
XP.NO:03 DATE:
.
Objective: To verify the CORDIC algorithm on LPC2148(ARM) processor.
Requirement Analysis:
Software requirements:
C-language
ARM GCC Tools
Keil µ vision4
Flash magic device programmer
Hyper terminal
Hardware requirements:
ARM7 Trainer Kit LPC2148
Power supply
RS232
PROGRAM:
#include <LPC214X.H>
unsigned int count=0,count2=0,count_samples=0,count_samples_value = 0;
unsigned int sample[330]; // array stores the samples
unsigned int sampleIndex=0; // index for sample updation.
unsigned int DACIndex=0; // index for writing into DAC.
//unsigned int phase_change_value_2 = 36,phase_change_value_1 = 1;
unsigned int phase=0;
unsigned int phaseIncValue= 9*65536; // corresponds to 50 khz at 500 ksps degree (36 *
65536)
unsigned int sampleIncrement=1; // number of samples to be
unsigned int amplitude=1;
unsigned char compute=1;
//void T0isr(void) __attribute__ ((interrupt));
//void def_isr(void) __attribute__ ((interrupt));
void processCommand(void);
void compute_samples(void);
void CORDIC(unsigned int,unsigned int*);
int calc_pow(int,int);
__irq void T0isr (void)
{
++count_samples;
if(DACIndex ==40)
DACIndex=0;
DACIndex = DACIndex + 1;
DACR = sample[DACIndex];
T0IR |= 0x00000001; //Clear match 0 interrupt
VICVectAddr = 0x00000000; //Dummy write to signal end
of interrupt
if(count_samples == count_samples_value )
count_samples = 0;
}
__irq void def_isr(void)
{
Tx_string("Unknown interrupt");
VICVectAddr = 0x00000000; //Dummy write to
signal end of interrupt
}
int main ()
{
unsigned int i,j;
PINSEL0 = 0x00000005 ; // enabling the UART0 pins
// PORT(0.2) configured as input by mading bits 5,4 as 00, bits 4,3,2,1 0101 for UART0
// bits 7,6, are zero for using p0.3
PINSEL1 = 0x00080000 ; // to use P0.25 as DAC output pin.
// PLL configuration
InitUart0();
//IO0DIR= IO0DIR & PIN; // only our output pin will be configured as output
processCommand();
compute_samples();
T0TCR= T0TCR | (0x01); // to set bit0 to 1 to enable timer counter 0
T0PR = 0x00;
T0MR0= 300 ;
T0MCR = T0MCR | (0x03); // to set the bit1 to 1 to enable the reset feature for Timer0 when
MR0 matches // bit0 =1 to generate
interrupt
VICIntSelect = 0x00000000;
VICDefVectAddr = (unsigned long) def_isr;
VICVectAddr0 = (unsigned long) T0isr;
VICVectCntl0= 0x00000024;
VICIntEnable = 0x00000010; // to enable TIMER0
//temp_1=0;
while(1)
{
}
}
void compute_samples(void)
{
unsigned int i=0,temp;
int flag=0;
phase=0;
for(i=0;i<320;i++)
{
phase += phaseIncValue;
if(phase >= 0x01680000) // 0x01680000 corresponds to 360 degreess
phase=phase-0x01680000; // to bring angle in 0 to 360 degreess range;
CORDIC(phase,&sample[i]);
adc_out(sample[i]);
Tx_char('\n');
sample[i] = (sample[i]) << 6 ;
}
}
void processCommand(void)
{
unsigned int i=0;
// debugging purpose...we have not fixed frquency for modulation
techniques
count_samples_value = 20; // these are the values which indicate the no of samples required to
make 360 degrees phase
phaseIncValue = 9*65536 ;
}
void CORDIC(unsigned int phase_in,unsigned int *sin_out)
{
int flag=0; // 0 for less than 180 and 1 for more than 180
int
phase_val[14]={2949120,1740967,919879,466945,234378,117303,58666,29334,14667,7333,36
66,1833,916,458};
/*
--actual value=45.0000000";
--actual value=26.565051
--actual value=14.036243
--actual value=7.125016
--actual value=3.576334
--actual value=1.789911
--actual value=0.895174
--actual value=0.447614
--actual value=0.223811
--actual value=0.111906
--actual value=0.055953
--actual value=0.027976
--actual value=0.013988
--actual value=0.006994
*/
int acc_angle,L;
int I,Q,varI,varQ,tempI,tempQ,scaledI,scaledQ;
int I_sign,Q_sign;
int angle_90,zero_angle;
while(phase_in >= 0x01680000) // 0x01680000 corresponds to 360 degreess
phase_in=phase_in - 0x01680000; // to bring angle in 0 to 360 degreess range;
if(phase_in > 0x00B40000)
{
phase_in = phase_in - 0x00B40000;
flag=1;
}
angle_90 = 5898240;
zero_angle = 0;
if ((phase_in > zero_angle) && (phase_in < angle_90)) // -- when angle less than 90
degrees
{
I = 256;
Q = 0;
acc_angle = 0;
I_sign=0; // cos positive
Q_sign =0; // sin positive
}
else // means (temp_phase_in>=angle_90) and less than 180
{
I = 0;
Q = 256;
acc_angle = angle_90;
I_sign=1; // cos negative
Q_sign =0; // sin positive
}
tempI=I;
tempQ=Q;
for(L=0;L<=8;L++)
{
varI=tempI;
varQ=tempQ;
scaledI = varI >> L; // (2^-L) I
scaledQ = varQ >> L; //// (2^-L) Q
if (phase_in > acc_angle)
{
tempI=varI-scaledQ;
tempQ=varQ+scaledI;
acc_angle=acc_angle+phase_val[L];
}
else
{
tempI=varI+scaledQ;
tempQ=varQ-scaledI;
acc_angle=acc_angle-phase_val[L];
}
}
if(Q_sign==1)
*sin_out = -tempI;
else
*sin_out = tempI;
if(flag==1) // if angle is greater than 180
{
*sin_out = -(*sin_out);
}
*sin_out=*sin_out+512;
}
Result: Hence the generation of sine wave using CORDIC algorithm is verified.
-
EXP.NO:04 DATE:
SERIAL COMMUNIVCATION DRIVER (UART0)
Objective: To transmit the serial data using UART0 on LPC2148(ARM) processor.
Requirement Analysis:
Software requirements:
C-language
ARM GCC Tools
Keil µ vision4
Flash magic device programmer
Hyper terminal
Hardware requirements:
ARM7 Trainer Kit LPC2148
Power supply
RS232
THEORY: LPC2148 microcontroller has two UARTs. The microcontroller has to
communicate to external world through the UARTs only. There is an importance for developing
serial port driver.
• 16 byte Receive and Transmit FIFOs.
• Register locations conform to ‘550 industry standard.
• Receiver FIFO trigger points at 1, 4, 8, and 14 bytes.
• Built-in baud rate generator.
• LPC2148 contains mechanism that enables software flow control implementation.
The below fig. shows the register mapping. For complete description of individual register refer
to user guide.
Procedure:
Go to start open RUN command in that type cmd then press enter.
Then command prompt is opened, verify whether the GNUARM tool is installed properly
or not by giving DOS command that PATH.
Then enter into the folder path where we created the make file. Then pass the command
that make file. This GCC command will generate the hex file(.exe file).
Dumping Program:
Open the Flash magic which is a device programmer.
In device programmer select the Controller type, operating frequency and browse the
corresponding hex file then Press start which means loading of hex file.
comport : com 1
Baud rate : 19200
Device : LPC 2148
Frequency: 12 MHz
Before starting dumping process reset the trainer kit.
Execution process:
Go to hyper terminal on host system. Make the configuration as per the requirements,i.e.
Step1 : communications
comport : com 1
Baud rate : 19200
Device : LPC 2148
Frequency: 12 Mhz
Rest the trainer kit.
FLOWCHART:
SOURCE CODE:
#include "LPC2148.h"
#include "UART0.h"
#include <stdio.h>
int main (void)
{
PINSEL0 = 0x00000055 ;
InitUart0();
puts("Hello WElcome to serial port driver program");
}
Result: .The transmitted string has been displayed on hyper terminal.
CASE STUDY
EXP.NO:05 DATE:
1.Configuring RTLinux
How to Configure RTLinux
The current hard real time OSs in the market is proprietary and we have to pay heavy license in
order to use it. The current 2.6 version of the Linux supports Real Time but it consists of the
features of Soft Real Time. But there is a big difference in between a soft Real Time OS and
Hard Real Time OS. Hard Real Time OS has a priority based pre-emptive task scheduling
system oppose to fair task scheduling which is generic to Linux kernel. Following are the
requirements to configure RTLinux on the system:
1) Vanilla version of the Linux : linux-2.4.21.tar.bz2
2) rtlinux-3.2-rc1.tar.bz2
3) findutils rpm : findutils-4.1.7-9.src.rpm
4) Also we need all the kernel development tools like gcc tool chain, etc
Now follow the steps given below to configure an RTLinux
Step 1:
1.1) Download linux-2.4.21.tar.bz2 and rtlinux-3.2-rc1.tar.bz2
1.2) Copy these two files to “/usr/src”
#cp /home/UTS/.gnome-desktop/*.bz2 /usr/src
#cd /usr/src
1.3) Extract the files,
#tar –xjvf linux-2.4.21.tar.bz2
#tar –xjvf rtlinux-3.2-rc1.tar.bz2
1.4) now give the following commands
#ln –s linux-2.4.21 linux
#ln –s rtlinux-3.2-rc1 rtlinux
Step 2:
2.1) we need to patch the vanilla version of the kernel with the rtlinux
patches. It is good practice to do a patch test before applying the changes.
To do one run the following command
#cd /usr/src/linux
#patch –p1 --dry-run < ../rtlinux-3.2-rc1/patches/kernel_patch-
2.4.21-rtl3.2-pre3
If the above command doesn’t give any error then you are good to proceed
and apply the patches (very rarely it is the chance that error comes)
#patch –p1 < /usr/src/rtlinux/patches/kernel_patch-2.4.21-rtl3.2-
pre3
Step 3:
This step focuses on compiling the new kernel. At this stage we will take the.config file of the
already build kernel. For this I copied the config of kernellinux-2.4.20
#cd /usr/src/linux
#cp /boot/config-2.4.20-8 .config
3.1) Now give the following command to configure the kernel#make menuconfig: This
command will bring you a graphicalinterface to configure the kernel Goto Network Device
Support _ Ethernet 1000 _ and unlock “sk98xxx”Now save and exit the configuration
3.2) Once the configuration is done you can check any dependencies,compile modules, install
modules and install the new kernel in to your system
#make dep
#make bzImaze
www.unistring.com 4
#make modules
#make modules_install
#make install
3.3) If you manage to go through above steps without any errors, it is safeto assume that you
have installed the new kernel successfully. To verify this check the grub.conf file
#vim /etc/grub.conf
Here we should see a new entry for the newly installed RealTime kernel. If this is there, next step
is to boot the system using this kernel. Once booted we can also run the following command to
check the kernel version.
Step 4
In this step we can begin compiling and installing the RTLinux kernel we downloaded to
/usr/src/rtlinux. Again this step is much similar to the earlier Steps
#cd /usr/src/rtlinux
#make config
#make
#make devices
#make install
NOTE: If you ever get an RTLinux kernel compile error like below,
xargs: environment is too large for exec
That means your “findutils” have a problem. The work around is re-install
“findutils” using the source rpm. Give the following steps,
Copy the rpm file findutils-4.1.7-9.src.rpm to the /usr/src folder by giving
the following command
#cp /home/UTS/.gnome-desktop/findutils-4.1.7-9.src.rpm /usr/src
#cd /usr/src
Now give the following command
#rpm –ivh findutils-4.1.7-9.src.rpm
#cd /usr/src/redhat/SOURCES/
#tar –xzvf findutils-4.1.7.tar.gz
#cd findutils-4.1.7
#. /configure
#cd xargs/
#vim xargs.c
And comment out the following two lines in the xargs.c file
/*
If(arg_max>20*1024)
Arg_max = 20 * 1024
*/
Now go back to the rtlinux folder by giving the following command
#cd /usr/src/rtlinux
#make config
#make
#make devices
#make install
#cp /usr/bin/xargs /usr/bin/xargs.old
#cp /usr/local/bin/xargs /usr/bin
Again goto the rtlinux-3.2.-rc1 and compile it by giving the following
command
#make
If you manage to install RTLinux kernel without any error, you can now reboot the machine and
select the RTLinux kernel in the Grub.Now you have fully pledged real time capable Linux
Kernel for which we don’t need to pay any license fee.
Step 5:
5.1) First of all make sure you got all your Real Time modules loaded.# rtlinux status This
command will show which modules are loaded.
5.2) To load the dynamic RT modules you can use insmod commands. But to save the time you
can simply run the following command #rtlinux start and again check the status. Now goto
example folder in RTLinux by giving the following command
#cd /usr/src/rtlinux/ rtlinux-3.2-wr/examples/hello
#make
This command will generate the .o file which is to be loaded.
Load the module by giving the following command
#insmod hello.o
To verify whether it is loaded or not give the following command
#lsmod
To verify the output give the command
#dmesg
To unload the module
#rmmod hello
2.CROSS COMPILER
For building applications or compiling source code, software toolslike compiler, assembler,
linker etc., are required. When developing embedded applications are concerned, certain things
should be taken into account regarding compilers. When the developing applications for native
architecture i.e., target architecture is same as the host architecture on which applications are
developed, native compilers can be used. If the target architecture is different from the host
architecture, then cross compilers are required.
A cross compiler is a compiler capable of creating executable code for a platform other than the
one on which the compiler is run. Cross compiler tools are used to generate executables for
embedded system or multiple platforms. It is used to compile for a platform upon which it is not
feasible to do.
The use of a cross compiler is to separate the build environment from the target environment.
This is useful in a number of situations when compare to native compiler:
• Embedded computers where a device has extremely limited resources. Forexample, a
microwave oven will have an extremely small computer to read
its touchpad and door sensor, provide output to a digital display and speaker,and to control the
machinery for cooking food. This computer will not bepowerful enough to run a compiler, a file
system, or a development
environment. Since debugging and testing may also require more resources than are available on
an embedded system, cross-compilation can be less involved and less prone to errors than native
compilation.
• Compiling for multiple machines. For example, a company may wish to
support several different versions of an operating system or to support several different operating
systems. By using a cross compiler, a single build environment can be set up to compile for each
of these targets.
• Compiling on a server farm. Similar to compiling for multiple machines, a complicated build
that involves many compile operations can be executed across any machine that is free regardless
of its brand or current version of an operating system.
• Bootstrapping to a new platform. When developing software for a new platform, or the
emulator of a future platform, one uses a cross compiler to compile necessary tools such as the
operating system and a native compiler.
Compiling native code for emulators for older now-obsolete platforms like the Commdore 64 or
Apple II by enthusiasts who use cross compilers that run on a current platform (such as Aztec C's
MS DOS 6502 cross compilers running under Windows XP).
In this project, Cross compilers are used for developing applications for ARM microcontroller.
The cross compilers run on host computer and develops application for different architecture i.e.,
for ARM architecture.
Features of GCC:
GCC is a portable compiler--it runs on most platforms available today, andcan produce output
for many types of processors. In addition to the processors used in personal computers, it also
supports microcontrollers, DSPs and 64-bit CPUs.
GCC is not only a native compiler--it can also cross-compile any program, producing executable
files for a different system from the one used by GCC itself. This allows software to be compiled
for embedded systems which are not capable of running a compiler. GCC is written in C with a
strong focus on portability, and can compile itself, so it can be adapted to new systems
easily.
GCC has multiple language frontends, for parsing different languages. Programs in each
language can be compiled, or cross-compiled, for a architecture. For example, an ADA program
can be compiled for a microcontroller, or a C program for a supercomputer.
GCC has a modular design, allowing support for new languages and architectures to be added.
Adding a new language front-end to GCC enables the use of that language on any architecture,
provided that the necessary runtime facilities (such as libraries) are available. Similarly, adding
support for a new architecture makes it available to all languages.
Finally, and most importantly, GCC is free software, distributed under the GNU General Public
License (GNU GPL).(1) This means you have the freedom to use and to modify GCC, as with all
GNU software. If you need support for a new type of CPU, a new language, or a new feature you
can add it yourself, or hire someone to enhance GCC for you.
Furthermore, you have the freedom to share any enhancements you make to GCC. As a result of
this freedom you can also make use of enhancements to GCC developed by others. The many
features offered by GCC today show how this freedom to cooperate works to benefit you, and
everyone else who Understanding the differences between normal C Compiler and Cross
compiler(GNU-ARM) Compiler (Turbo C) Cross Compiler (GNU-ARM)
3. A native compiler is one that
compiles programs for the same architecture or operating system that it is running on. For
instance, a compiler running on an x86processor and creating x86 binaries
4. A native compiler generates code forits own execution environment• Most compilers include
an IDE to facilitate development and debugging
5. Not a portable compiler.
6. A cross-compiler is one that compiles binaries for architectures other than its own, such as
compiling SPARC binaries on a PowerPC processor
7. A cross compiler executes in one environment and generates code for another.
• The base tool distributions do not include a graphical Integrated Development Environment
(IDE) to facilitate point-and-click code generation or debugging
8. Portable compiler, it runs on most platforms available today.
ADDITIONAL EXPERIMENT:
IMPLIMENTATION OF FIR FILTER IN ARM PROCESSOR
OBJECTIVE: To implement FIR filter in ARM processor.
REQUIREMENT ANALYSIS
Software requirements:
C-language
ARM GCC Tools
Keil µ vision4
Flash magic device programmer
Hyper terminal
Hardware requirements:
ARM7 Trainer Kit LPC2148
Power supply
CRO
Function generator
Connecting cables
RS232
Theory:
The following block diagram shows the signal processing setup using microprocessors or
microcontrollers. The ADC converts the input signal in digital form, which will be read by the
processor. The digital signal processing application could be filtering, modulation, demodulation
or any typical algorithm.
DACADC µp / µc
Platform for DSP application
Any DSP algorithm finally need to be implemented by using arithmetic operations. Hence any
Digital Signal Processing (DSP) platform requires arithmetic blocks. In addition higher memory
space is required for handling larger programs. The following are the requirements for
implementing DSP applications.
(1) Enough Processing speed
(2) Required ALU size (like 32 bit, 16 bit etc)
(3) Sufficient code and data memories
(4) Special functional units such as MAC (multiply and accumulate)
The ARM core is not a dedicated DSP. There is no single instruction that issues a multiply
accumulate and data fetch in parallel. However by reusing loaded data we can achieve a
respectable DSP performance. LPC 2148 has on chip 10 bit Digital to analog converter.
The direct form of FIR filter is standard linear convolution, which described the output as
convolution of input and impulse response of the filter.
y[n] = x[n]*c[n] = ∑ x[k]c[n-k] = ∑ c[k]x[n-k].
k k
where c[n] values represent filter coefficients, and x[n] represents the input samples. The below
figure shows the direct form FIR structure
Figure , Direct form 6-tap FIR filter .
Low pass filter specifications
Sampling frequency fs = 50KHz
Pass band frequency fpass = 5khz
Stop band frequency fstop = 7khz
The FDA tool designs : 9 tap FIR filter (equiripple)
FDA TOOL SPECIFICATIONS:
To open the FDA window ,Type fda tool in Command window of MATLAB.
The specifications of filter as shown in the figure below. The various specifications to be
mentioned are:
1. Response type: To specify whether the desired filter is low pass, high pass, band pass or
band stop filter. Select the Low pass filter in this case.
2. Design method: The filter to be designed is either FIR or IIR filter. Select FIR filter here.
3. Order of the filter: Specify the Order of the filter is 9 here.
4.Frequency specification: Specify the sampling, pass band stop band and frequencies
50kHz,5 kHz and 7kHz respectively.
Fig 3.3.1.1, FDA Tool
After giving the specifications for the required filter click on “design filter” which generates the
coefficients for the fir filter .To export these coefficients,
Go to File->Export then following window will open
Click on “Export” and given a variable name as Num.
To convert the filter coefficients into required format, multiply Num with 128
Since Fractional part of coefficients is represented by 7 bit ,2 bits used to represents the integer
part and 1 bit used as signed bit.
Type Num in Command window in MATLAB,then multiply with 128 by typing
Num*128.Consider the integer parts as co efficients of given filter.
Procedure:
Go to start open RUN command in that type cmd then press enter.
Then command prompt is opened, verify whether the GNUARM tool is installed properly
or not by giving DOS command that PATH.
Then enter into the folder path where we created the make file. Then pass the command
that makefile. This GCC command will generate the hex file(.exe file).
Execution process:
Open the Flash magic which is a device programmer.
In device programmer select the Controller type, operating frequency and browse the
corresponding hex file then Press start which means loading of hex file.
comport : com 1
Baud rate : 19200
Device : LPC 2148
Frequency: 12 MHz
Before starting dumping process reset the trainer kit.
FLOW CHART:
PROGRAM:
#include "LPC2148.h"
void small_delay()
{
unsigned int i=0;
int j=0;
//for(j=0;j<4;j++)
for(i=0;i<1000;i++);
}
int main ()
{
unsigned int temp=0,value=0;
signed int x,x_1,x_2,x_3,x_4,x_5,x_6,x_7,x_8,x_9,x_10,y=0,temp1;
PINSEL0 = 0x00000005 ; // enabling the UART0 pins
PINSEL1 = 0x11080000;
// PLL configuration
PLLCFG=0x00000024;
PLLCON=0x00000001;
PLLFEED=0x000000AA;
PLLFEED=0x00000055;
while(!(PLLSTAT & 0x00000400));
PLLCON = 0x00000003;
PLLFEED =0x000000AA;
PLLFEED=0x00000055;
VPBDIV = 0x00000001;
while(1)
{
AD0CR=0x00211008; // for selecting AD0.3
value=0;
//small_delay();
while(!(value & 0x80000000)) // till the done =0
value=AD0GDR;
if((value & 0x07000000)==0x03000000)
{
temp=(value& 0x0000FFF0) >> 6;
x=temp-512;
x_10=x_9;
x_9=x_8;
x_8=x_7;
x_7=x_6;
x_6=x_5;
x_5=x_4;
x_4=x_3;
x_3=x_2;
x_2=x_1;
x_1=x;
// y=(((x_1)*-10)+((x_2)*13)+((x_3)*19)+((x_4)*26)+((x_5)*31)+
((x_6)*31)+((x_7)*26)+((x_8)*19)+((x_9)*13)+((x_10)*-10));
y=(((x_1)*-21)+((x_2)*27)+((x_3)*39)+((x_4)*53)+((x_5)*62)+
((x_6)*62)+((x_7)*53)+((x_8)*39)+((x_9)*27)+((x_10)*-21));
y=y/256;
temp1=y+512;
DACR = temp1<<6;
}
}
}
Result: Applying the sin wave with 1kHz (from function generator) as input to ADC0.3 pin of
LPC2148.To see the output , connect CRO probe positive and Ground pins to the DAC output of
LPC2148, ground pin of Board respectively. Now, to put the microcontroller in RUN mode,
press RESET. You can see the same sin wave as output ,change the frequency observe the
output.
Figure:Output of DAC
EXP.NO:02 DATE:
7 segment display INTERFACE TO 89c51ed2
OBJECTIVE: To implement 7 segment display INTERFACE TO 89c51ed2
REQUIREMENT ANALYSIS:
HARDWARE REQUIREMENTS:
Atmel 89C51ED2
Embedded controller evolution board (ALS-EMB-EVAL-02)
Power supply
RS232
SOFTWARE REQUIREMENTS:
Keil µ vision3
Atmel Flip 2.4.2
C language
THEORY: At the lowest level, keyboards are organized in a matrix of rows and columns. The
CPU accesses both rows and columns through ports; therefore, with two 8-bit ports, and 8x8
matrix of keys can be connected to a microprocessor. When a key is pressed, a row and column
make a contact; otherwise, there is no connection between rows and columns. In IBM PC
keyboards, a single microcontroller (consisting of the microprocessor, RAM and EPROM, and
several ports all on a single chip) takes care of hardware and software interfacing of the
keyboard. In such systems ,it is the function of programs stored in the EPROM of the
microcontroller to scan the keys continuously ,identify which one has the activiated,and present
it to the mother board .in this section we look at the mechanism by which the 8051 scans and
identifies the key. The switches SW4 to SW11 are organized as a 2 rows X 4 columns matrix.
One end of the switches SW4, SW5, SW6 and SW7 in first row are connected to the port line
P1.7* through the jumper JP5 (when pins 2 & 3 are shorted) and one end of the switches SW8,
SW9, SW10 and SW11 in second row are connected to the port line P2.4*. The other end of the
switches are connected to the port lines P2.0*, P2.1*,P2.2* and P2.3* respectively. Port lines
P2.0* to P2.3* are input lines to the controller device. Port lines P1.7* (ROW1) and P2.4*
(ROW2) are output lines from the controller. The interface diagram for keypad is shown below.
Operation: Initially take column lines P2.0* to P2.3* to a logic '1'.If first row P1.7* is at logic
'0' and second row P2.4* is at logic '1' then check which key is pressed in first row by scanning
column by column from P2.0* to P2.3*.If P1.7* = '1' and P2.4* = '0' then check which key is
pressed in second row byscanning column by column from P2.0* to P2.3*.
PROCEDURE:
Create a project folder before create project.
Open keil µvision 3 IDE software by double clicking on “Keil µ vision3” icon”
Go to project then to new project and save it with a name in the respective project
folder .
Select the device Atmel ,”AT89C51Ed2” then press OK and press NO button
not to add a “START UP.A51” File.
Right click on “Target1” in project window, click on “options for target’ target 1’
In target field select XTAL (MHZ):11.0592 and click on” Use on chip
ROM(0X0-0XFFFF)”, ”Use on chip XRAM (0X0-0X1EFF)”.In output field click
on create HEX file.
Go to file select ”NEW” to open an editor window. Create your source file and
use the Header file ”AT 89C51Xd2.h” in the source file and save the files.
Right click on “Source Group1” and select the option “Add files to group “source
group1’” and add the .c Source file to the Group.
After adding source file Go to “project” click on ”Translate ” to compile the file.
Go to “Project click on ”Build Target” for building all source files such as .c
files ,.asm files header files etc. which has been added to the target build. This
will create the .HEX file to be downloaded to the Target device.
FLOWCHART:
SOURCE CODE: /*Port lines P1.7 and P2.4 are connected to rows 1 & 2 respectively.Port
lines P2.0 to P2.3 are connected to columns 1 to 4 respectively.Observe the key numbers 0 to 7
for switches SW4 to SW11 respectivelydisplayed on the right most 7-segment display U15.*/
#include<at89c51xd2.h>
#include<intrins.h>
/*key_arr :-->
0x8E -> ROW1 SW4 0x1E -> ROW2 SW8
0x8D -> ROW1 SW5 0x1D -> ROW2 SW9
0x8B -> ROW1 SW6 0x1B -> ROW2 SW10
0x87 -> ROW1 SW7 0x17 -> ROW2 SW11
0x8E,0x8D,0x8B,0x87 -> 8(1000) is for ROW1 P1.7* going HI
0x1E,0x1D,0x1B,0x17 -> 1(0001) is for ROW2 P2.4* going HI
E -> 1110 -> for P2.0* SW4 & SW8
D -> 1101 -> for P2.1* SW5 & SW9
D -> 1011 -> for P2.2* SW6 & SW10
D -> 0111 -> for P2.3* SW7 & SW11 */
unsigned char key_arr[8] = {0x8E,0x8D,0x8B,0x87,0x1E,0x1D,0x1B,0x17};
/*array_dec[10]:->
value= h g f e d c b a On 7-SEG U15
0x66 = 0 1 1 0 0 1 1 0 -> Displaying '4'
0x6D = 0 1 1 0 1 1 0 1 -> Displaying '5'
0x7D = 0 1 1 1 1 1 0 1 -> Displaying '6'
0x07 = 0 0 0 0 0 1 1 1 -> Displaying '7'
0x3F = 0 0 1 1 1 1 1 1 -> Displaying '0'
0x06 = 0 0 0 0 0 1 1 0 -> Displaying '1'
0x5B = 0 1 0 1 1 0 1 1 -> Displaying '2'
0x4F = 0 1 0 0 1 1 1 1 -> Displaying '3'
0x7F = 0 1 1 1 1 1 1 1 -> Displaying '8'
0x6F = 0 1 1 0 1 1 1 1 -> Displaying '9' */
unsigned char array_dec[10] = {0x66,0x6D,0x7D,0x07,0x3F,0x06,0x5B,0x4F,0x7F,0x6F};
unsigned char key_rtn=0x00,key_flag=0x00,temp =0x00,temp2 = 0x00;
unsigned char row = 0xEF,temp_row = 0x00,key = 0x00,tmp_rw1=0x00,tmp_rw2=0x00;
unsigned int i = 0;
void key_press(void);
void scan(void);
void DelayMs(unsigned int);
void Display(void);
void led_init(void);
sbit EN = P1^2; //Latch Enable Line of second 2to4 LineDecoder of U8
//U8 is having two 2to4 line decoders
sbit SEL0 = P1^3; //Data Latch 1A of the 1st decoder of U8
sbit SEL1 = P1^5; //Data Latch 1B of the 1st decoder of U8
sbit ENL = P2^5; //Data Latch 2B of the 2nd decoder of U8
sbit ROW2 = P2^4; //Second row of thw 2X4 keypad
sbit ROW1 = P1^7; //First row of thw 2X4 keypad
sbit CS = P1^4; //Chip select line for SPI device U3
sbit CLKL = P2^6; //Clock Line (>CLK)of 8-bit shift reg U5(Serial In parrale Out)
sbit LED = P2^7; //Data Line of the 8-bit shift reg U5
void main()
{
AUXR = 0x10; //Accessing Ful XRAM
led_init(); //For Clearing All LEDs L3 to L10
P2 = 0xFF; //make Port 2 high;
P1 = 0xFF; //make Port 1 high;
P0 = 0x00; //port for 7-seg data
EN = 1; //Disabling 2nd Decoder
ENL = 0; //Data Latch Enable line
CS = 1; //to disable SPI
while(1)
{
ROW1 = 0; //fOR ROW1 (SW4 TO SW 7)
ROW2 = 1;
key_press();
if(key_flag == 0xFF)//If key Pressed
{
scan();
Display(); //Displying the num on the 7-Seg U15
}
ROW1 = 1; //fOR ROW2 (SW8 TO SW 11)
ROW2 = 0;
key_press();
if(key_flag == 0xFF)//If key Pressed
{
scan();
Display(); //Displying the num on the 7-Seg U15
}
} //end of while(1) loop
}
/* Key_press() function is used to check which portline has gone LO
Initialy the portlines P2.0*,P2.1*,P2.2*,P2.3* are HI, so when pressing
SWitches the perticular portline goes LO */
void key_press(void)
{
temp = P2 & 0x0F; //Read the keys (Masking the Lowr Nibble)
DelayMs(1); //wait for debounce
temp = P2 & 0x0F; //Again Read the keys(Masking the Lowr Nibble)
DelayMs(1); //wait for debounce
if(temp == 0x0F) //If No key has been pressed
key_flag = 0x00;
else
{
key_flag = 0xFF;//If Key pressed
DelayMs(1); //wait for debounce
while(temp == (temp2 = P2 & 0x0F));//waiting for key lift
key_rtn = temp; //taking the value read 'temp' wen pressing key
//i.e. P2=0x0F (Initialy P2.0 to P2.3 are at HI)
//P2=0x0E wen SW4 0r SW8 are pressed depending upon ROW1&ROW2
//P2=0x0D wen SW5 0r SW9 are pressed depending upon ROW1&ROW2
//P2=0x0B wen SW6 0r SW10 are pressed depending upon ROW1&ROW2
//P2=0x07 wen SW7 0r SW11 are pressed depending upon ROW1&ROW2
}
}
/* Initialy the ROW lines P1.7* & P2.4* are at HI,
Taking P1.7*(ROW1) LO & P2.4*(ROW2) HI for ROW1 scanning COL by COL
Taking P2.4*(ROW2) LO & P1.7*(ROW1) HI for ROW2 scanning COL by COL
When pressing key the perticular ROW will go HI
i.e. 0x80 for ROW1 and 0x01 for ROW2 */
void scan(void)
{
tmp_rw1 = P1 & 0x80; //Masking P1.7* portline
tmp_rw2 = tmp_rw1 | (P2 & 0x10);//Masking P2.4* portline
tmp_rw2 = tmp_rw2 & 0x90; //Again Masking P1.7* & P2.4*
key_rtn = key_rtn | tmp_rw2; //Combining ROWs(P1.7*&P2.4*)
//and COLs(P2.0* to P2.3*)
for(i=0;i<8;i++)
if(key_rtn == key_arr[i])
key = i; //Getting the correspondin index value for
//displaying 0,1,2,3,4,5,6,7 on U15
}
void Display(void)
{
P0 = array_dec[key];//Decoding the key value to that of 7-segment
ENL = 0;
SEL0 = 1; //Select lines for segments
SEL1 = 1; //00 for U12,01 for U13
//10 for U14,11 for U15
EN = 0;
DelayMs(2);
EN = 1;
}
void DelayMs(unsigned int count)
{ // 0.1 mSec Delay 11.0592 Mhz
unsigned int i;
while(count)
{
i = 11;
while(i>0) i--;
count--;
}
}
// To clear All LEDs
void led_init(void)
{
unsigned int j;
CLKL = 0;
LED = 1;
for(j=0;j<8;j++)
{
CLKL = 1;
_nop_();
_nop_();
CLKL =0;
_nop_();
}
}
DUMPING PROGRAM ON TO TRAINER KIT:
Set the slide switch SW1 ”PGM” position on the board and press the reset switch SW2.
Open the Atmel Flip
Go to the ‘device’ option, ”select”, select the specific device ‘AT89C51ED2” and press
ok.
Go to “File” then” load HEX File” select the corresponding .HEX file from the project
folder.
Go to “settings” option select “communications” select ”RS232”,one small window will
come and make sure that no other application is using COM port. Click on ‘connect’.
EXECUTION PROCEDURE:
The trainer kit consists of 2X4 matrix keypad(SW4-SW11).If any key is pressed the
corresponding digit will displayed on the right most 7-segment display.
RESULT:
The output is verified that the key numbers 0 to 7 for switches SW4 to SW11 respective
displayed on the right most 7-segment display.
Top Related