Microcontroller and
Microcontroller and
AND
APPLICATION
(ELECTRONICS ENGG)
Programming 8051 MICROCONTROLLER ASM and
c and implement in flash 8051 micro controller 1.
The assembly language is a low-level programming language used to write program code in terms of
mnemonics. Even though there are many high-level languages that are currently in demand, assembly
programming language is popularly used in many applications .It can be used for direct hardware
manipulations. It is also used to write the 8051 programming code efficiently with less number of clock
cycles by consuming less memory compared to the other high-level languages.
The assembly language is a fully hardware related programming language. The embedded designers
must have sufficient knowledge on hardware of particular processor or controllers before writing the
program. The assembly language is developed by mnemonics; therefore, users cannot understand it
easily to modify the program.
Assembly programming language is developed by various compilers and the “keiluvison” is best
suitable for microcontroller programming development. Microcontrollers or processors can
understand only binary language in the form of ‘0s or 1s’; An assembler converts the assembly language
to binary language, and then stores it in the microcontroller memory to perform the specific task.
The 8051 microcontroller is the CISC based Harvard architecture, and it has peripherals like 32 I/O,
timers/counters, serial communication and memories. The microcontroller requires a program to
perform the operations that require a memory for saving and to read the functions. The
8051 microcontroller consists of RAM and ROM memories to store instructions.
A Register is the main part in the processors and microcontrollers which is contained in the memory
that provides a faster way of collecting and storing the data. The 8051 assembly language
programming is based on the memory registers. If we want to manipulate data to a processor or
controller by performing subtraction, addition, etc., we cannot do that directly in the memory, but it
needs registers to process and to store the data. Microcontrollers contain several types of registers that
can be classified according to their instructions or content that operate in them.
8051 Microcontroller Programs in Assembly Language
The assembly language is made up of elements which all are used to write the program in sequential
manner. Follow the given rules to write programming in assembly language.
Rules of Assembly Language
3. The AT89LP51xx2 has a half-page buffer of 64 bytes. Therefore Page mode commands accept
only 64 bytes of data. However, Bootloader programming still allows a full 128 bytes to be sent.
4. Individual reprogramming of bytes is not possible. On AT89LP51xx2 one page is the smallest
erasable quantity whereas on AT89C51xx2 it was one byte. Programming algorithms must erase
and write an entire page when even only a single byte needs to change. This affects only the SPI-
based interface and not the Bootloader; however, the bootloader is most efficient when working
with full pages. Table 3-1. Summary of Programming Differences on AT89LP51xx2 Feature
AT89C51xx2 AT89LP51xx2 High-Voltage Parallel Interface YES NO 4-wire SPI Interface NO
YES Serial UART Bootloader YES YES Reset Polarity Active-High Selectable Flash Page Size
128 128 Flash Page Buffer Size 128 64 Flash Auto-Erase Programming Byte-Level Page-Level
Device Signature Locations(1) 30H, 31H, 60H, 61H 00H, 01H, 02H, 30H, 31H, 60H, 61H User
Signature Array 0 512 bytes EEPROM Data Memory 2KB 4KB EEPROM Page Size 1 32 User
Configuration Fuses 4 19 4 3716A–MICRO–10/11 Migrating from 89C51xx2 to 89LP51xx2
5. The Data[1] byte of the Program OSC Fuse command is changed from 20h on
AT89C51IC2/ID2 to 10h on AT89LP51IC2/ID2.
6. The AT89LP51xx2 has a selectable polarity RST pin. Existing AT89C51xx2 drivers expect the
reset to have active-high polarity. In most existing applications the EA pin is tied high, so dropping
in an AT89LP51xx2 will result in an active-high reset. See Section
“Reset” on page 12.
In addition to the above changes, the AT89LP51xx2 also supports the following new features:
1. The AT89LP51xx2 includes a User Signature Array for storing up to 512 bytes of user ID,
revision, configuration or other nonvolatile information. This information can be read/written
from the application code. The BSB, SBV and SSB bytes are stored in this array. The full array
is accessible to the SPI interface; however, only the first 256 bytes can be programmed through
the Bootloader.
2. The AT89LP51xx2 supports 19 User Configuration Fuses for configuring the default behavior
of the device. See Section 3.1 for more information. The fuses beyond the 4 used by the
AT89C51xx2 are not accessible by the Bootloader. These fuses may require configuration
before placing the device in system.
3. SPI-programming can be disabled during warm resets by clearing the ISP Enable Fuse. When
this fuse is disabled, programming is only available by asserting RST at powerup (cold reset).
This
4. The AT89LP51ED2/ID2 supports page programming of the EEPROM with up to 32 bytes
written per operation0
segment .text
inc [count]
dec [value]
• Register to register
• Memory to register
• Register to memory
• Register to constant data
• Memory to constant data
However, like other instructions, memory-to-memory operations are not possible using
ADD/SUB instructions. An ADD or SUB operation sets or clears the overflow and carry flags.
Example
The ADD/SUB instruction can take place between −
• Register to register
• Memory to register
• Register to memory
• Register to constant data
• Memory to constant data
However, like other instructions, memory-to-memory operations are not possible using
ADD/SUB instructions. An ADD or SUB operation sets or clears the overflow and carry flags.
Example
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
segment .data
segment .bss
num1 resb 2
num2 resb 2
res resb 1
section .text
global _start ;must be declared for using gcc
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
exit:
The first operand in all the cases could be either in register or in memory. The second operand
could be either in register/memory or an immediate (constant) value. However, memory-to-
memory operations are not possible. These instructions compare or match bits of the operands
and set the CF, OF, PF, SF and ZF flags.
This tells the processor to "jump" to line 400 and to then continue processing from
this point in the program. The use of go to statements was also encouraged by
languages such as Fortran and Cabo
1. If statements
2. Case statements
3. Pattern matching
IF STATEMENT
An if statement, sometimes referred to as a conditional, can be used in two forms:
Case Statement
Generally speaking an "if ... then ... else ..." statement supports selection from only two
alternatives; we can of course nest such statements, but it is usually more succinct to use
a case statement. Case statements allow selection from many alternatives where each
alternative is linked to a predicate, referred to as a selector, which when evaluated to true
causes an associated program statement (or statements) to be executed. Selections may be
made according to:
Also note that where selection is by distinct value, in some cases, these must be
presented in the correct numeric order (this is the case in C).
Note that C requires that selectors are presented according to their numeric order.
Note also that neither Ada nor C support selection using expressions involving
selectors, e.g. a conditional expression or an arithmetic expression. This is
supported by languages such as Pascal.
Program using Ports 4.
Delay generation using timer (Assembly
and c) 5.
In this project, I will discuss a little bit about Timers in 8051 Microcontroller and also
how to Generate a Delay using 8051 Timers.
Generation of time delay is most important concept in embedded systems. Most of the
times, we need to generate precise time delay between two actions in any
microcontroller applications. We can generate the time delay using the techniques like
LOOPs or by using in built delay functions.
But these are not precise methods for generating time delay so that we will go for
timers to produce accurate time delay. This concept is similar to Time Delay Relay
concept.
Outline
Timers on the other hand are used to generate delays. Timers in a microcontroller are
controlled by the SFRs (Special Function Registers). Timers in different mode of
operations are configured by special function registers.
The main principle behind this project is to generate a Delay using 8051 Timers with
the help of its Special Function Registers.
Circuit Design
The major component in this circuit is AT89C51 controller. A reset circuit for 8051
Microcontroller is made up of a Push Button, a 10KΩ Resistor and a 10μF Capacitor.
A 11.0592MHz uartz Crystal and two 33pF Ceramic Capacitors form the oscillator
circuit of the 8051 Microcontroller and are connected to Pins 18 and 19.
Finally, an LED is connected to the P2.0 through a 330Ω resistor to indicate the time
delay.
The upper nibble (TMOD.7 to TMOD.4) is used to configure timer1 and the lower
nibble (TMOD.3 to TMOD.0) is used to configure timer0.
GATE: If this pin is high, then corresponding timer is enabled when there is an
interrupt at corresponding INT pin of the microcontroller.
C/T: This pin is used to select timer or counter. If this pin is high, then used as a
counter to count the external event. If this pin is low, then used as a timer to produce
time delay.
M1 and M0: These bits are used to select the different timer modes.
13 Bit Timer: This mode uses 8 bits from high byte and remaining 5 bits from low
byte. The value of the timer in this mode is from 0000H to 1FFFH
16 Bit Timer: This mode is most commonly used for producing the time delay. In this
mode all the 16 bits are used for timer and values vary from 0000H to FFFFH.
If the value XXXXH is loaded into the timer register, then the produced time delay is
equal to the [(FFFFH – XXXXH+1)*(period of one clock pulse)].
The time period of one clock pulse is equal to the 1.085μs 11.0592 MHz frequency.
8-bit Auto Reload: In this mode, initial value is loaded in to the high byte and the
same value is loaded into the low byte. Timer value is from 00H to FFH. This mode is
used to set the baud rates for serial communication.
Split Mode: In this mode timer is divided in to two 8 bit timers. These 8 bit timers
can count from 00H to FFH. This mode is used in the applications where we require
an additional 8 bit timer or counter.
TCON Register
It is a special function register used to control the timer operation. In this register only
upper nibble is used to control the timer and remaining bits are used for interrupt
control.
• TF1: This bit is set to 1 automatically on the timer 1 overflow.
• TR1: This bit is used to enable the timer 1. This pin must be high to enable the
timer1.
• TF0: set to one automatically when timer0 overflows.
• TR0: place 1 in this bit to enable the timer 0.
TL=YYh
Void delay ()
TL0 = 0x66;
*/
#include<reg51.h>
#define ON 1
#define OFF 0
sbit led=P2^0;
void delay();
void delay()
TL0 = 0x66;
void main()
{
while(1)
led = ON;
for(i=0;i<1000;i++)
delay();
led = OFF;
for(i=0;i<1000;i++)
delay();
Circuit Applications
• Used in embedded system applications where we want precise time Delay.
• This system used to generate square wave.
• Used in Ultrasonic module applications.
Programming Interrupts (Assembly and c) 6.
what-when-how
In Depth Tutorials and Information
INTERRUPT PROGRAMMING IN C
SECTION 11.6: INTERRUPT PROGRAMMING IN C
So far all the programs in this chapter have been written in Assembly. In this section we show how to
program the 8051/52′s interrupts in 8051 C language. In reading this section, it is assumed that you
already know the material in the first two sections of this chapter.
The 8051 C compilers have extensive support for the 8051 interrupts with two major features as follows:
1. They assign a unique number to each of the 8051 interrupts, as shown in Table
11-4.
2. It can also assign a register bank to an ISR. This avoids code overhead due to
the pushes and pops of the RO – R7 registers.
Table 11-4: 8051/52 Interrupt Numbers in C
Example 11-14
Write a C program that continuously gets a single bit of data from PI. 7 and sends it to Pl.O, while
simultanepusly creating a square wave of 200 (as period on pin P2.5. Use timer 0 to create the square
wave. Assume that XTAL = 11.0592 MHz.
Solution:
Example 11-15
Write a C program that continuously gets a single bit of data from PI. 7 and sends it to Pl.O in the main,
while simultaneously (a) creating a square wave of 200 us period on pin P2.5, and (b) sending letter ‘A’
to the serial port. Use Timer 0 to create the square wave. Assume that XTAL = 11.0592 MHz. Use the
9600 baud rate.
Solution:
Example 11-16
SUMMARY
An interrupt is an external or internal event that interrupts the microcontroller to inform it that a device
needs its service. Every interrupt has a program associated with it called the ISR, or interrupt service
routine. The 8051 has 6 interrupts, 5 of which are user-accessible. The interrupts- are for reset: two for
the timers, two for external hardware interrupts, and a serial communication interrupt. The 8052 has an
additional interrupt for Timer 2.
The 8051 can be programmed to enable or disable an interrupt, and the interrupt priority can be altered.
This chapter showed how to program 8051/52 interrupts in both Assembly and C languages.
Implementation of standard UART
communication (using hyper terminal) 7.
In this tutorial we learn to Enable UART communication with PIC Microcontroller
and how to transfer data to and from your Computer. So far, we have covered all
basic modules like ADC, Timers, PWM and also have learnt how to interface
LCDs and 7-Segment displays. Now, we will equip our self with a new communication
tool called UART which widely used in most of the Microcontroller projects. Check
here our complete PIC Microcontroller Tutorials using MPLAB and XC8.
• Asynchronous (full-duplex)
• Synchronous – Master (half-duplex)
• Synchronous – Slave (half-duplex)
There are also two different modes namely the 8-bit and 9-bit mode, in this tutorial we
will configure the USART module to work in Asynchronous mode with 8-bit
communication system, since it is the most used type of communication. As it is
asynchronous it doesn't need to send clock signal along with the data signals. UART
uses two data lines for sending (Tx) and receiving (Rx) data. The ground of both devices
should also be made common. This type of communication does not share a common
clock hence a common ground is very important for the system to work.
At the end of this tutorial you will be able establish a communication (UART)
between your computer and your PIC Microcontroller and toggle an LED on the
PIC board from your laptop. The status of the LED will be sent to your laptop from the
PIC MCU. We will test the output using Hyper Terminal in computer. Detailed Video
is also given at the end of this tutorial.
Requirements:
Hardware:
Software:
• MPLABX
• HyperTerminal
A RS232 to USB converter is required to convert the serial data into computer readable
form. There are ways to design your own circuit instead of buying your own module
but they are not reliable as they are subjected noise. The one which we are using is
shown below
Note: Each RS232 to USB converter would require a special driver to be installed; most
of them should get installed automatically as soon as you plug in the device. But, if it
doesn’t relax!!! Use the comment section and I will help you out.
Now the baud rate has to be set. The baud rate is the rate at which information is
transferred in a communication channel. This can be one of the many default values,
but in this program we are using 9600 since its the most used baud rate.
The value of the baud rate has to be set using the register SPBRG, the value depends
on the value of the External crystal frequency, the formulae to calculate the baud rate is
shown below:
The bit BRGH has to be made high to enable high speed bit rate. According to datasheet
(page 13) it is always advantageous to enable it, as it can eliminate errors during
communication.
As said earlier we will be working in Asynchronous mode, hence the bit SYNC should
be made zero and bit SPEM must be made high to enable serial pins (TRISC6 and
TRICSC5)
In this tutorial we will be both sending and receiving data between MCU and computer
hence we have to enable both TXEN and CREN bits.
The bits TX9 and RX9 have to be made zero so that we operate in 8-bit mode. If there
has to be high reliability need to be established then 9-bit mode can be selected.
With this we complete our initialization setup. Now the Module is configured as
UART and is ready for operation.
The below function can be used to transmit data through the UART module:
Once the module is initialized whatever value is loaded into the register TXREG will
be transmitted through UART, but transmission might overlap. Hence we should always
check for the Transmission Interrupt flag TXIF. Only if this bit is low we can proceed
with the next bit for transmission else we should wait for this flag to get low.
However, above function can be used only to send only one byte of data, to send a
complete a string the below function should be used
As you can notice we have again called the UART_send_char() but now inside the while
loop. We have split the string into individual characters, each time this function is
called, one char will be sent to the TXREG and it will get transmitted.
The following function can be used to receive data from the UART module:
In that case the Receive flag bit RCIF comes to rescue. This bit will go low whenever
a data is received and is not yet processed. Hence we use it in the while loop creating a
delay to hold the program till we deal with that value.
Now let us come to the final part of the Program, the void main(void) function, where
we will be toggling a LED through the computer using the UART communication
between PIC and computer.
When we send a character “1” (from computer) the LED will be turned ON and the
status message “RED LED -> ON” will be sent back (from PIC MCU) to the computer.
Similarly we send a character “0” (from computer) the LED will be turned OFF and the
status message “RED LED -> OFF” will be sent back (from PIC MCU) to the
computer.
16×2 LCD
Pin Diagram
This is the pin diagram of a 16×2 Character LCD display. As in all devices it also has two
inputs to give power Vcc and GND. Voltage at VEE determines the Contrast of the display. A
10K potentiometer whose fixed ends are connected to Vcc, GND and variable end is connected
to VEE can be used to adjust contrast. A microcontroller needs to send two informations to
operate this LCD module, Data and Commands. Data represents the ASCII value (8 bits) of
the character to be displayed and Command determines the other operations of LCD such as
position to be displayed. Data and Commands are send through the same data lines, which are
multiplexed using the RS (Register Select) input of LCD. When it is HIGH, LCD takes it as
data to be displayed and when it is LOW, LCD takes it as a command. Data Strobe is given
using E (Enable) input of the LCD. When the E (Enable) is HIGH, LCD takes it as valid data
or command. The input signal R/W (Read or Write) determines whether data is written to or
read from the LCD. In normal cases we need only writing hence it is tied to GROUND in
circuits shown below.
The interface between this LCD and Microcontroller can be 8 bit or 4 bit and the difference
between them is in how the data or commands are send to LCD. In the 8 bit mode, 8 bit data
and commands are send through the data lines DB0 – DB7 and data strobe is given through E
input of the LCD. But 4 bit mode uses only 4 data lines. In this 8 bit data and commands are
splitted into 2 parts (4 bits each) and are sent sequentially through data lines DB4 – DB7 with
its own data strobe through E input. The idea of 4 bit communication is introduced to save pins
of a microcontroller. You may think that 4 bit mode will be slower than 8 bit. But the speed
difference is only minimal. As LCDs are slow speed devices, the tiny speed difference between
these modes is not significant. Just remember that microcontroller is operating at high speed in
the range of MHz and we are viewing LCD with our eyes. Due to Persistence of Vision of our
eyes we will not even feel the speed difference.
Hope that you got rough idea about how this LCD Module works. Actually you need to read
the datasheet of HD44780 LCD driver used in this LCD Module to write a Hi-Tech C program
for PIC. But we solved this problem by creating a header file lcd.h which includes all the
commonly used functions. Just include it and enjoy.
Functions in lcd.h
Lcd8_Init() & Lcd4_Init() : These functions will initialize the LCD Module connected to the
following defined pins in 8 bit and 4 bit mode respectively.
8 Bit Mode :
#define RS RB6
#define EN RB7
#define D0 RC0
#define D1 RC1
#define D2 RC2
#define D3 RC3
#define D4 RC4
#define D5 RC5
#define D6 RC6
#define D7 RC7
4 Bit Mode :
#define RS RB2
#define EN RB3
#define D4 RB4
#define D5 RB5
#define D6 RB6
#define D7 RB7
Lcd8_Clear() & Lcd4_Clear() : Calling these functions will clear the LCD Display when
interfaced in 8 Bit and 4 Bit mode respectively.
Lcd8_Set_Cursor() & Lcd4_Set_Cursor() : These functions set the row and column of the
cursor on the LCD Screen. By using this we can change the position of the character being
displayed by the following functions.
Lcd8_Shift_Left() & Lcd4_Shift_Left() : These functions are used to shift the content on the
LCD Display left without changing the data in the display RAM.
8 Bit Mode
Circuit Diagram
Hi-Tech C Code
#include<htc.h>
#include<pic.h>
#define RS RB6
#define EN RB7
#define D0 RC0
#define D1 RC1
#define D2 RC2
#define D3 RC3
#define D4 RC4
#define D5 RC5
#define D6 RC6
#define D7 RC7
#include "lcd.h"
void main()
{
int i;
TRISB = 0x00;
TRISC = 0x00;
Lcd8_Init();
while(1)
{
Lcd8_Set_Cursor(1,1);
Lcd8_Write_String("electroSome LCD Hello World");
for(i=0;i<15;i++)
{
__delay_ms(1000);
Lcd8_Shift_Left();
}
for(i=0;i<15;i++)
{
__delay_ms(1000);
Lcd8_Shift_Right();
}
Lcd8_Clear();
Lcd8_Set_Cursor(2,1);
Lcd8_Write_Char('e');
Lcd8_Write_Char('S');
__delay_ms(2000);
}
}
4 Bit Mode
Circuit Diagram
Hi-Tech C Code
#include<htc.h>
#include<pic.h>
#define RS RB2
#define EN RB3
#define D4 RB4
#define D5 RB5
#define D6 RB6
#define D7 RB7
#define _XTAL_FREQ 8000000
#include "lcd.h"
void main()
{
int i;
TRISB = 0x00;
Lcd4_Init();
while(1)
{
Lcd4_Set_Cursor(1,1);
Lcd4_Write_String("electroSome LCD Hello World");
for(i=0;i<15;i++)
{
__delay_ms(1000);
Lcd4_Shift_Left();
}
for(i=0;i<15;i++)
{
__delay_ms(1000);
Lcd4_Shift_Right();
}
Lcd4_Clear();
Lcd4_Set_Cursor(2,1);
Lcd4_Write_Char('e');
Lcd4_Write_Char('S');
__delay_ms(2000);
}
}
Interfacing LCD Keypad 9.
LCD (LIQUID CRYSTAL DISPLAY) INTERFAC
LCDs can display numbers, characters, and graphics. To produce a proper display, the information
has to be periodically refreshed. This can be done by the CPU or internally by the LCD device itself.
Incorporating a refreshing controller into the LCD, relieves the CPU of this task and hence many
LCDs have built-in controllers. These controllers also facilitate flexible programming for characters
and graphics. Table 5.1 shows the pin description of an LCD. from Optrex.
• Vss and VDD provide +5v and ground, V0 is used for controlling LCD contrast.
• If RS=0, the instruction command register is selected, allowing the user to send a command such as
clear display, cursor at home, etc.
• If RS=1 the data register is selected, allowing the user to send data to be displayed on the LCD.
• R/W input allows the user to Read/ Write the information to the LCD.
• The enable pin is used by the LCD to latch information presented to its data pins.
• Section 5.1 discusses about command codes for writing the instructions on the LCD register.
Section 5.2 gives an example program for displaying a character on the LCD.
LCD COMMAND CODES
The LCD’s internal controller can accept several commands and modify the display accordingly.
These commands would be things like:
✓ Clear screen
✓ Return home
✓ Decrement/Increment cursor
After writing to the LCD, it takes some time for it to complete its internal operations. During this
time, it will not accept any new commands or data. Figure 5.4.1 shows the command codes of LCD
and Figure 5.4.2 shows the LCD interfacing. We need to insert a time delay between any two
commands or data sent to LCD.
• The rows are connected to an output port(Port 1) and the columns are connected to an input port.
(Port 2)
• If no key has been pressed, reading the input port will yield 1s for all columns since they are all
connected to high (Vcc).
• If all the rows are grounded and a key is pressed, one of the columns will have 0 since the key
pressed provides the path to ground.
• It is the function of the microcontroller to scan the keyboard continuously to detect and identify the
key pressed.
KEY
SCAN To find out the key pressed , the controller grounds a row by sending a ‘0’ on the
corresponding line of the output port. It then reads the data at the columns using the input port. If data
from columns is D3-D0=1111, then no key is pressed. If any bit of the column is ‘0’, it indicates that
a key is pressed in that column. In this example, the column is identified by the following values:
1110 – key pressed in column
0 1101 – key pressed in column
1 1011 – key pressed in column
2 0111 – key pressed in column 3
STEPS TO FIND OUT KEY PRESSED
Beginning with the row 0, the microcontroller grounds it by providing a low to row D0 only. It then
reads the columns (port2). If the data read is all 1s, then no key in that row is activated and the process
is moved to the next row. It then grounds the next row, reads the columns, and checks for any zero.
This process continues until a row with a zero is identified. After identification of the row in which
the key has been pressed, the column to which the pressed key belongs is identified as discussed
above - by looking for a zero in the input values read. Example:
(a) D3 – D0 = 1101 for the row, D3 – D0 = 1011 for the column, indicate row 1 and column 3 are
selected. This indicates that key 6 is pressed.
(b) D3 – D0 = 1011 for the row, D3 – D0 = 0111 for the column, indicate row 2 and column 3 are
selected. Then key ‘B’ is pressed.
PROGRAM:
The program used for detection and identification of the key activated goes through the following
stages:
1. To make sure that the preceding key has been released, 0s are output to all rows at once, and the
columns are read and checked repeatedly until all the columns are high.
● When all columns are found to be high, the program waits for a short amount of time before it goes
to the next stage of waiting for a key to be pressed. ROHINI COLLEGE OF ENGINEERING &
TECHNOLOGY EC 8691 MICROPROCESSORS AND MICROCONTROLLERS 2. To see if any
key is pressed, the columns are scanned over and over in an infinite loop until one of them has a 0 on
it.
● Remember that the output latch is connected to rows, still have their initial zeros (in stage 1),
making them grounded.
● After the key press detection, it waits for 20-ms for the bounce and then scans the columns again.
i) It ensures that the first key press detection was not an erroneous one due to spike noise.
ii) After the 20-ms delay, if the key is still pressed, then it goes to the loop (step 3) to detect the actual
key pressed.
3. To detect which row the key pressed belongs to, it grounds one row at a time, reading the columns
each time.
• If it finds that all columns are high, this means that the key press does not belong to that row.
Therefore, it grounds the next row and continues until it finds the row, that the key pressed belongs to.
• Upon finding the row that the key pressed belongs to, it sets up the starting address for the lookup
table holding the scan codes for that row.
4 To identify the key pressed, it rotates the column bits, one bit at a time, into the carry flag and
checks to see if it is low.
• Upon finding the zero, it pulls out the ASCII code for that key from the look-up table.
• Otherwise, it increments the pointer to point to the next element of the look-up table. Figure 5.4.4
provides the flowchart for keyboard interfacing Program for scanning and identifying the pressed key.
Programming ADC/DAC 10.
Description
Analog-to-digital conversion (ADC) is necessary because, while embedded
systems deal with digital values, their surroundings typically involve many
analog signals such as, temperature, speed, pressure, the output of a
microphone, etc. They all need to be converted into digital data before being
processed by the microcontroller. Today, we will see how to read an external
analog signal using a PIC16F688 microcontroller, and display the conversion
output (a digital number) on a LCD. The input analog signal will be a varying
voltage between 0-5V derived using a potentiometer.
Required Theory
The PIC16F688 microcontroller has a built-in 10-bit ADC with eight input
channels. The eight channels are available at RA0, RA1, RA2, RA4, RC0, RC1,
RC2, and RC3. They have alternate labels, AN0-AN7, for this function, and are
multiplexed into a single Sample and Hold circuit. The output of the Sample
and Hold is connected to the input of the A/D converter. The 10-bit conversion
result is stored into the ADC result registers ADRESH (A/D Result Higher
byte) and ADRESL (A/D Result Lower byte). Each of these registers is 8-bit.
The functionality of the A/D module is controlled by three registers: ANSEL,
ADCON0, and ADCON1. The details of these control registers are discussed
in ADC channels in PIC16F688.
Circuit Diagram
The test circuit to demonstrate the 10-bit A/D conversion using PIC16F688 is
shown below. The test input voltage for ADC is derived from a 5K
potentiometer connected across the +5V power supply, and is connected to
RA2/AN2 pin of PIC16F688. The supply voltage (+5V) is chosen as the
reference voltage for A/D conversion. Therefore, the 10-bit ADC will convert
any analog voltage between 0-5V to a digital number ranging from 0-1023. The
number will be displayed on the LCD.
This circuit diagram is not much different from the one for our previous lab
(Lab 4: Interfacing a character LCD), except it has a 5K potentiometer for
generating test analog voltage for ADC operation.
The MC1408 DAC (or DAC0808)
In this chip the digital inputs are converted to current. The output current is known as Iout by
connecting a resistor to the output to convert into voltage. The total current provided by
the Iout pin is basically a function of the binary numbers at the input pins D0 - D7 (D0 is the LSB
and D7 is the MSB) of DAC0808 and the reference current Iref. The following formula is
showing the function of Iout
IOut=Iref⟮D72+D64+D58+D416+D332+D264+D1128+D0256⟯IOut=Iref⟮D72+D6
4+D58+D416+D332+D264+D1128+D0256⟯
The Iref is the input current. This must be provided into the pin 14. Generally 2.0mA is used as
Iref
We connect the Iout pin to the resistor to convert the current to voltage. But in real life it may
cause inaccuracy since the input resistance of the load will also affect the output voltage. So
practically Iref current input is isolated by connecting it to an Op-Amp with Rf = 5KΩ as
feedback resistor. The feedback resistor value can be changed as per requirement.
0 0 5 128
90 1.0 10 255
180 0 5 128
270 -1.0 0 0
360 0 5 128
For generating sinewave, at first we need a look-up table to represent the magnitude of the
sine value of angles between 0° to 360°. The sine function varies from -1 to +1. In the table
only integer values are applicable for DAC input. In this example we will consider 30°
increments and calculate the values from degree to DAC input. We are assuming full-scale
voltage of 10V for DAC output. We can follow this formula to get the voltage ranges.
Vout = 5V + (5 ×sinθ)
Let us see the lookup table according to the angle and other parameters for DAC.
Circuit Diagram −
Source Code
#include<reg51.h>
sfr DAC = 0x80; //Port P0 address
void main(){
int sin_value[12] = {128,192,238,255,238,192,128,64,17,0,17,64};
int i;
while(1){
//infinite loop for LED blinking
for(i = 0; i<12; i++){
DAC = sin_value[i];
}
}
}
Output
The output will look like this −
Interfacing with stepper motor 11.
Kit
STEPPER MOTOR
A stepper motor is a brushless, synchronous electric motor that converts digital
pulses into mechanical shaft rotation. Every revolution of the stepper motor is
divided into a discrete number of steps, and the motor must be sent a separate pulse
for each step.
Fig. 1
Interfacing Stepper Motor to Microcontroller
The 8051 trainer kit has three numbers of I/O port connectors, connected with I/O
Port lines (P1.0 – P1.7),(p3.0 – p3.7) to rotate the stepper motor. Ls293d is used
as a driver for port I/O lines, drivers output connected to stepper motor, connector
provided for external power supply if needed.
850 AGAIN:MOVX@DPTR,
F0 In AGAIN, Store
B A
850
03 RR A Rotate sequen
C
850
B1 11 ACALL DELAY w
D
851
DD F6 DJNZ R5, H3 Decrement R5&
B
851
22 RET Re
D
• Control the brightness of an LED using a hardware PWM (Pulse-width modulation) module.
In this lab you will LEARN the following:
• A PDF containing answers to all questions posed in this lab prompt, as well as a description of any
extra functionality you added in your implementation.
• Your fully commented and neatly presented code, in a zipped format. NOTE: Only source files
(*.c, *.h, etc) are necessary. Make it obvious which files were used in which portion of the lab.
These documents and web resources will be useful in completion of the lab and/or in answering the
questions posed.
• MSP430F2013 Datasheet
• Be sure to select “Treat as an assembly-only project” when creating the project in CCS. Question
1.1: How many lines of Assembly did this program require? How many lines of C? Question 1.2:
What was the resulting binary size (program memory utilization) for assembly and C versions
(Hint: one of the compiler output files will give you this information).
We will now take a brief interlude to introduce (or hopefully re-introduce) you to the
oscilloscope. This is an important tool for the embedded systems engineer, and will be useful
for Part 3 of this lab. For this section, please go through the Oscilloscope Tutorial on the
course website and answer the questions below. Reference the oscilloscope manual if needed.
Question
2.1: Which parameters of circuit operation (current, voltage, resistance, frequency , etc) is
your oscilloscope capable of directly measuring or calculating? Question
2.2: TRUE or FALSE: It’s OK to connect two oscilloscope probe ground clips to different
nodes (justify your answer).
3: PWM GENERATION WITH TIMER_A A pulse-width modulated (PWM) waveform is a
rectangular wave with a variable ON time. The ON time of the waveform relative to its
period is known as its duty cycle. PWM signals are used when there is a need to vary the
effective power of a signal, such as in a motor or lighting controller. Figure 1.
The green waveform is a PWM signal with varying duty cycle. Red represents the average
signal level. The TIMER_A peripheral of the MSP430 may be configured to produce a PWM
waveform directly on an output pin. Like many hardware peripherals of the MSP430, the
timer may be configured in a “set-and-forget” manner if desired, and will run continuously
until reconfigured.
The file “msp430x20x3_ta_16.c” configures the timer to produce a PWM signal, routes this
PWM signal to a physical output port, and then switches off the CPU entirely. The PWM
operation will run independent of the CPU and other subsystems of the microcontroller.
HINTS:
• Review the TIMER_A section in the MSP430F2013 datasheet.
• Only certain pins may be configured to produce the PWM signal. PROCEDURE:
1. Create a new project and import “msp430x20x3_ta_16.c”.
2. Connect the LED to the PWM output port of the MSP.
3. Connect an oscilloscope probe between the PWM output port and ground.
4. Run the application and observe the LED and oscilloscope waveform.
5. Change the duty cycle of the PWM waveform and reprogram the target. Observe changes.
6. Change the period of the PWM waveform and reprogram the target. Observe changes.
7. Produce an automatic LED fade effect by adjusting the PWM duty cycle in an ISR. The
LED should smoothly fade between low- and high-brightness states. Question
3.1: What are two advantages of direct hardware control of the PWM output, rather than
toggling the pin in a timer ISR? Question
3.2: How did changing the PWM period affect operation of the device?
GOALS: • Use the PWM module as a musical tone generator. Connect the PWM output to a
piezoelectric speaker element using the filter shown. • Select which musical tone (from the
table below) to play back based on light intensity. You should be able to “play” the optical
theremin by waving your hand over the light sensor
Programming ARM micro controller using
asm and c using simulator 13.
A micro-controller is a single Integrated Circuit (IC) which is comparable to
little stand alone computer and it is designed to perform the specific tasks of
embedded systems. 8051 and ARM comes under the family of micro-
controller. 8051 micro-controller and ARM micro-controller differs from
each other in terms of different architecture and different sets of instruction,
speed, cast, Memory, Power Consumption, Bus Width etc. Now let’s
understand in detail what actually they are and how they differs from each
other.
1. 8051 micro-controller :
It is a 8 bit family of micro-controller. It is an entry level micro-controller
used for most basic applications all across the world and it consumes low
power and available with low budget. It was developed by the Intel in the
year 1981. 8051 micro-controller has many features like Serial
Communication, Timers, Interrupts, etc. This micro-controller is used in
various devices and the major areas includes automobiles, medical
devices and energy management. Now a days 8051 Micro-controller
might seem little bit out of fashion but still it is recommended as best
platform to start work on the concept of Micro-controllers with 8051 Micro-
controller although this trend seems to be changed with the introduction of
Arduino of AVR community.
2. ARM micro-controller :
ARM micro-controller was introduced by Acron computer organization and is
manufactured by Apple, Nvidia, Qualcomm, Motorola, ST Microelectronics,
Samsung Electronics, and TI etc. ARM processor belongs to the family of
CPUs which are based on Reduced Instruction Set Computer (RISC) and
ARM microprocessor with RAM, ROM and other peripherals in one single
chip, we get an ARM micro-controller, for example, LPC2148. It is based on
Its speed is 12 clock cycles per machine cycle. Its speed is 1 clock cycle per machine cycle.
Flash, ROM, SRAM memory is used in 8051 Flash, EEPROM, SDRAM memory is used in ARM micro-
micro-controller. controller.
It is based on CISC Instruction set Architecture. It is based on RISC Instruction Set Architecture.
Its families include 8051 variants. Its families include ARMv4, 5, 6, 7 and cortex series.
Its manufacturers are Atmel, NXP, Silicon Labs, Its manufacturers are Nvidia, Qualcomm, Apple, Samsung
Dallas, Cyprus, Infineon, etc. Electronics, and TI etc.
8051 micro-controller costs very low as ARM micro-controller costs low as compared to features
compared to features provided. provided.
Popular micro-controllers include AT89C51, Popular micro-controllers include ARM Cortex-M0 to ARM
P89v51, etc. Cortex-M7, etc.
Programming with Arithmetic logic
instruction 14.
Arithmetic Instructions are the instructions which perform basic arithmetic
operations such as addition, subtraction and a few more. In 8085
microprocessor, the destination operand is generally the accumulator.
Following is the table showing the list of arithmetic instructions:
In the table, R stands for register M stands for memory Mc stands for
memory contents r.p. stands for register pair
GPIO programming in arm microcontroller 15.
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).
1. PORT0
2. PORT1
• 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.
LPC2148 Pin Diagram
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.
The Slow Registers allow backward compatibility with earlier family devices using the
existing codes.
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 :
c) Writing F to P0.7-P0.4
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;
IO0SET = (1<<4);
IO0CLR = (1<<4);
1. FIOxDIR (Fast 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.
2. FIOxMASK (Fast Mask register for port) : This is a 32-bit wide register. This register
controls the effect of fast registers (FIOxPIN, FIOxSET, FIOxCLR) on port pins. Setting
a bit to ‘0’ configures the corresponding pin access to the fast registers i.e. we can
write/read the corresponding pin in fast mode using fast registers. Setting a bit to ‘1’
configures the corresponding pin unaffected by fast registers.
3. FIOxPIN (Fast Port Pin value register using FIOMASK) : This is a 32-bit wide
register. This register is used to read/write the value on port pins, only if that
corresponding port pins have access to fast registers (Access to port pins using fast
registers is enabled using Zeroes in FIOxMASK register).
4. FIOxSET (Fast Port Output Set register using FIOMASK) : This is a 32-bit wide
register. This register is used to make pins of Port HIGH. Writing one to specific bit
makes that pin HIGH. Writing zero has no effect. Reading this register returns the
current contents of the port output register. Only bits enabled by ZEROES in FIOMASK
can be altered.
5. FIOxCLR (Fast Port Output Clear register using FIOMASK) : 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. Only bits enabled by ZEROES in
FIOMASK can be altered.
Aside from the 32-bit long and word only accessible registers mentioned above, every
fast GPIO port can also be controlled via several byte and half-word accessible
registers. Refer chapter 8 (Page 83) on GPIO in the datasheet of LPC2148 provided in
the attachments section for their use.
Examples :
a) Configure pin P0.0 to P0.3 as input pins and P0.4 to P0.7 as output pins.
FIO0DIR = 0x000000F0;
FIO0SET = (1<<4);
FIO0CLR = (1<<4);
Why this is called Fast GPIO :
Fast GPIO registers are relocated to the ARM local bus. This makes software access
to GPIO pins 3.5 times faster than access through Slow GPIO registers. This effect will
not always be visible when a program is written in c code. It may be more evident in
an assembly code than in a c code.
Example
Now, let’s write a simple program for turning LED ON or OFF depending on the status
of the pin.
Program
/*
Input-Output Pin Programming to Drive LED through switch
-ports-and-registers
http://www.electronicwings.com/arm7/lpc2148-32-bit-arm7tdmi-s-processor-gpio
*/
#include <lpc214x.h>
#include <stdint.h>
int main(void)
{
//PINSEL0 = 0x00000000; /* Configuring P0.0 to P0.15 as GPIO */
/* No need for this as PINSEL0 reset value is 0x00000000 */
IO0DIR = 0x00000001; /* Make P0.0 bit as output bit, P0.1 b
it as an input pin */
while(1)
{
if ( IO0PIN & (1<<1) ) /* If switch is open, pin is HIGH */
{
IO0CLR = 0x00000001; /* Turn on LED */
}
else /* If switch is closed, pin is LOW */
{
IO0SET = 0x00000001; /* Turn off LED */
}
}
}
The tick rate of the Timer Counter (TC) is controlled by the 32-bit number written in the Prescaler
Register (PR) in the following way. There is a Prescale Counter (PC) which increments on each tick of the
PCLK. When it reaches the value in the prescaler register, the timer count is incremented and the
Prescaler Counter (PC) is reset, on the next PCLK. This cause the timer counters to increment on every
PCLK when PR=0, every 2 PCLKs when PR=1, etc.
Prescale Register: The 32-bit register which hold the maximum value of prescale counter
PR
after which it reset
Timer Counter: This is 32-bit Timer Counter which gets incremented whenever PC Prescale
TC
Counter value reaches to its maximum value as specified in PR
Timer Control Register: Timer Control register used to control the timer control functions.
TCR
We’ll enable, disable and reset Timer Counter (TC) through this register
Count Control Register: This register selects Timer Counter Mode. In our example we have
used Timer Mode. This can be done by setting CTCR to 0x0. [In Timer Mode every rising PCLK
CTCR
edge can increment Timer’s Prescale Counter (PC) or clear PC and increment Timer Counter
(TC)]
EXAMPLE PROJECT: In this example project we’ll generate precise 1 Sec. of delay using Timer0. The
Timer uses PCLK (Peripheral Clock) as a clock source. From previous post we’ve seen how to set up PLL
in LPC2148 ARM7. The Peripheral Clock (PCLK) has to be initialized before using Timer. Here in this
example: we have used 12 MHz external clock to be tick at 60 MHz.
Circuit Timers in ARM7 LPC2148
Before we jump start on writing program. We have to understand setting up of Timer Registers or
you can say sequence of operations. We’ll be following along:
▪ Setup Timer T0 into Timer Mode (T0CTCR = 0x0)
▪ Setup Prescale value in T0PR (in our case 59999)
▪ Reset Timer by setting (T0TCR = 0x02)
▪ Setup T0TCR to 0x01 to Enable Timer when needed
▪ Reset T0TCR to 0x00 to Disable Timer when needed
You may be wondering, why we have set Prescale Value to 59,999. Let’s calculate prescale count value:
Required Time 1 Second = 1/1000 milliseconds = 0.001 seconds (Resolution=1 ms)
#include <lpc214x.h>
int main(void)
while(1)
delay_ms(1000);
//return 0;
void initTimer0(void)
void initClocks(void)
PLL0FEED = 0x55;
PLL0FEED = 0x55;