Thursday 3 January 2013

Programming for Bipolar Stepper Motor

Programming for Bipolar Stepper Motor

►C Programming
CODE:
void main(){
        while(1){
                stepper = 0x08;
                delay();
                stepper = 0x02;
                delay();
                stepper = 0x04;
                delay();
                stepper = 0x01;
                delay();
        }
}



►Assembly Programming
CODE:
main:
        mov stepper, #08H
        acall delay
        mov stepper, #02H
        acall delay
        mov stepper, #04H
        acall delay
        mov stepper, #01H
        acall delay
        sjmp main



Now you're ready to use stepper motors.

Programming for 2-wire connection of Unipolar Stepper Motor

Programming for 2-wire connection of Unipolar Stepper Motor

►C Programming
CODE:
void main(){
        while(1){
                stepper = 0x03;
                delay();
                stepper = 0x01;
                delay();
                stepper = 0x00;
                delay();
                stepper = 0x02;
                delay();
        }
}



►Assembly Programming
CODE:
main:
        mov stepper, #03H
        acall delay
        mov stepper, #01H
        acall delay
        mov stepper, #00H
        acall delay
        mov stepper, #02H
        acall delay
        sjmp main


The working of the above code can be seen in the demo animation below.

unipolar stepper motor in 2-wire connection mode

Programming Half Step Sequence

►Programming Half step Sequence

►C Programming
Just the main routine changes rest everything remains same, i mean same delay routine.


CODE:
void main(){
        while(1){
                stepper = 0x08;
                delay();
                stepper = 0x0C;
                delay();
                stepper = 0x04;
                delay();
                stepper = 0x06;
                delay();
                stepper = 0x02;
                delay();
                stepper = 0x03;
                delay();
                stepper = 0x01;
                delay();
                stepper = 0x09;
                delay();
        }
}



►Assembly Programming
Here also the main routine changes rest everything remains same.


CODE:
main:
        mov stepper, #08H
        acall delay
        mov stepper, #0CH
        acall delay
        mov stepper, #04H
        acall delay
        mov stepper, #06H
        acall delay
        mov stepper, #02H
        acall delay
        mov stepper, #03H
        acall delay
        mov stepper, #01H
        acall delay
        mov stepper, #09H
        acall delay
        sjmp main


The working of the above code can be seen in the demo animation below.

unipolar stepper motor in half step sequence

Programming Full Step Sequence

►Programming Full step Sequence

►C Programming
I am assuming that stepper motor is connected at Port 1.0 to Port 1.3. Adjusting the delay will increase or decrease the speed of the motor. Here just for demonstration i have taken some delay, you can change it as you want.

[Tip: Do testing.. ]




CODE:
#include <REG2051.H>.
#define stepper P1
void delay();

void main(){
        while(1){
                stepper = 0x0C;
                delay();
                stepper = 0x06;
                delay();
                stepper = 0x03;
                delay();
                stepper = 0x09;
                delay();
        }
}

void delay(){
        unsigned char i,j,k;
        for(i=0;i<6;i++)
        for(j=0;j<255;j++)
       for(k=0;k<255;k++);
}



►Assembly Programming

CODE:
        org 0H

stepper equ P1

main:
        mov stepper, #0CH
        acall delay
        mov stepper, #06H
        acall delay
        mov stepper, #03H
        acall delay
        mov stepper, #09H
        acall delay
        sjmp main

delay:
        mov r7,#4
wait2:
        mov r6,#0FFH
wait1:
        mov r5,#0FFH
wait:
        djnz r5,wait
        djnz r6,wait1
        djnz r7,wait2
        ret
        end


The working of the above code can be seen in the demo animation below.

unipolar stepper motor in full step sequence

Connecting Bipolar Stepper Motor

Connecting Bipolar Stepper Motor

As we have studied that, Bi-polar stepper motors has 2 different coils. The step sequence for Bipolar stepper motor is same as that of unipolar stepper motors. The driving circuit for this require an H-Bridge as it allows the polarity of the power applied to be controlled independently. This can be done as shown in the figure below:

[lightbox=bipolar_stepper_big.gif|Bipolar Stepper Motor connection|stepper motor connections][/lightbox]
Please click on the image to enlarge it

Now we have seen the methods for connecting stepper motors with your microcontroller. So keeping these circuits in mind,we will now look at the programming of microcontroller to control stepper motors. This is discussed in the next section of the tutorial.

2 Wire Connection For Unipolar motor

►2-wire connection for Unipolar Stepper Motor

We have seen the generally used 4-wire connection method for interfacing unipolar stepper motor, but we can simplify the design to make controller use less pins with the help of 2-wire connection method. The circuit for 2-wire connection is shown below.

[lightbox=unipolar_stepper_big.gif|Unipolar Stepper Motor connection|stepper motor connections][/lightbox]
Please click on the image to enlarge it

Stepper Motor Connections

►Connecting Unipolar Stepper Motor

There are actually many ways you can interface a stepper motor to your controller, out of them the most used interfaces are:

  1. Interface using L293D - H-Bridge Motor Driver
  2. Interface using ULN2003/2004 - Darlington Arrays

We will dicuss both connection techniques one by one. The above mentioned methods need 4 controller pins for interface.

Connecting Unipolar stepper using L293D

[lightbox=l293d-stepper-big.gif|Stepper motor interfacing using L293D|stepper motor connections][/lightbox]
Please click on the image to enlarge it

As you see in the circuit above the four pins "Controller pin 1",2,3 and 4 will control the motion and direction of the stepper motor according to the step sequece programmed in the controller.

Step Sequence Of Stepper Motor

Stepper motors can be driven in two different patterns or sqeunces. namely,
  • Full Step Sequence
  • Half Step Sequence
we will go through these sequences one by one.


►Full Step Sequence

In the full step sequence, two coils are energized at the same time and motor shaft rotates. The order in which coils has to be energized is given in the table below.

Full Mode Sequence
Step A B A\ B\
0 1 1 0 0
1 0 1 1 0
2 0 0 1 1
3 1 0 0 1


The working of the full mode sequence is given in the animated figure below.

Full step stepper sequence


►Half Step Sequence

In Half mode step sequence, motor step angle reduces to half the angle in full mode. So the angualar resolution is also increased i.e. it becomes double the angular resolution in full mode. Also in half mode sequence the number of steps gets doubled as that of full mode. Half mode is usually preffered over full mode. Table below shows the pattern of energizing the coils.




Half Mode Sequence
Step A B A\ B\
0 1 1 0 0
1 0 1 0 0
2 0 1 1 0
3 0 0 1 0
4 0 0 1 1
5 0 0 0 1
6 1 0 0 1
7 1 0 0 0


The working of the half mode sequence is given in the animated figure below.

half step stepper sequence


►Step Angle

Step angle of the stepper motor is defined as the angle traversed by the motor in one step. To calculate step angle,simply divide 360 by number of steps a motor takes to complete one revolution. As we have seen that in half mode, the number of steps taken by the motor to complete one revolution gets doubled, so step angle reduces to half.


As in above examples, Stepper Motor rotating in full mode takes 4 steps to complete a revolution, So step angle can be calculated as...

Step Angle ø = 360° / 4 = 90°

and in case of half mode step angle gets half so 45°.

So this way we can calculate step angle for any stepper motor. Usually step angle is given in the spec sheet of the stepper motor you are using. Knowing stepper motor's step angle helps you calibrate the rotation of motor also to helps you move the motor to correct angular position.

►Step Sequence for 2-wire control of Unipolar stepper motor

As seen in above explanation, In every step of the sequence, two wires are always set to opposite polarities. Because of this, it's possible to control steppers with only two wires instead of four, with a slightly more complex circuit. The stepping sequence is the same as it is for the two coils A and B, and the opposite polarity value is given to A\ and B\. The sequence is given in the table below:

2-wire Mode Sequence
Step A B
0 0 1
1 1 1
2 1 0
3 0 0

►Step Sequence for Bipolar stepper motor

Bipolar motor has simpler construction. It has two windings with no center taps and a permanent magnet at the center just like unipolar stepepr motors. Being simpler in contruction, the stepping sequence is a little complex, as the power for both the coils has to be controlled in such a way that the polarity of the poles get reversed. This polarity sequence is shown in the table below.

Polarity Sequence
Step A A\ B B\
0 +ve -ve -ve -ve
1 -ve -ve +ve -ve
2 -ve +ve -ve -ve
3 -ve -ve -ve +ve

The above polarity sequence can be interpreted in terms of logic levels for microcontroller by activating one coil at a time as shown in the table below.

Step Sequence
Step A A\ B B\
0 1 0 0 0
1 0 0 1 0
2 0 1 0 0
3 0 0 0 1

We have now learnt most of the necessary things regarding a stepper motor. In the next section we will discuss about the various techniques to interface a stepper motor.

Intoduction To Stepper Motor

►Introduction

This section of tutorial will explain you everything that you need to know about stepper motors. Stepper motors can be used in various areas of your microcontroller projects such as making robots, robotic arm, automatic door lock system etc. This tutorial will explain you construction of stepper motors (unipolar and bipolar stepper motors ), basic pricipal, different controlling types (Half step and Full step), Interfacing Techniques (using L293D or ULN2003) and programming your microcontroller in C and assembly to control stepper motor.


Unipolar stepper motor
The unipolar stepper motor has five or six wires and four coils (actually two coils divided by center connections on each coil). The center connections of the coils are tied together and used as the power connection. They are called unipolar steppers because power always comes in on this one pole.


Bipolar stepper motor
The bipolar stepper motor usually has four wires coming out of it. Unlike unipolar steppers, bipolar steppers have no common center connection. They have two independent sets of coils instead. You can distinguish them from unipolar steppers by measuring the resistance between the wires. You should find two pairs of wires with equal resistance. If you've got the leads of your meter connected to two wires that are not connected (i.e. not attached to the same coil), you should see infinite resistance (or no continuity).




As already said, we will talk mostly on "Unipolar stepper motors" which is most common type of stepper motor available in the market.A simple example of 6 lead step motor is given below and in 5 lead step motor wire 5 and 6 are joined together to make 1 wire as common.


Unipolar stepper motor coils


►Working of Stepper Motor

Now lets discuss the operation pricipal of a stepper motor. When we energize a coil of stepper motor, The shaft of stepper motor (which is actually a permanent magnet) align itself according to poles of energized coil. So when motor coils are energized in a particular sequence, motor shaft tend to align itself according to pole of coils and hence rotates. A small example of energizing operation is given below.

working principal of stepper motor


You can see in the example, when coil "A" is energized, A north-south polarity is generated at "A+A\" as shown in the figure above and magnetic shaft automatically align itself according to the poles generated. When the next coil is energized the shaft again align itself and take a step. Hence the working pricipal.

working principal of stepper motor


We have seen that to make the stepper motor work, we need to energize coil in a sqeuence. The explaination and generation of the sequence is explaind in the next section of the tutorial.

Sending Data To LCD

►Sending Data to LCD

To send data we simply need to select the data register. Everything is same as the command routine. Following are the steps:
  • Move data to LCD port
  • select data register
  • select write operation
  • send enable signal
  • wait for LCD to process the data

Keeping these steps in mind we can write LCD command routine as.


CODE:
;Ports used are same as the previous example
;Routine to send data (single character) to LCD

LCD_senddata:
         mov   LCD_data,A     ;Move the command to LCD port
         setb  LCD_rs         ;Selected data register
         clr   LCD_rw         ;We are writing
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the data
         ret                  ;Return from busy routine

; Usage of the above routine
; A will carry the character to display on LCD
; e.g. we want to print A on LCD
;
; mov   a,#'A'         ;Ascii value of 'A' will be loaded in accumulator
; acall LCD_senddata   ;Send data


The equivalent C code Keil C compiler. Similar code can be written for SDCC.

CODE:
void LCD_senddata(unsigned char var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 1;        //Selected data register
     LCD_rw   = 0;        //We are writing
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}
// Using the above function is really simple
// we will pass the character to display as argument to function
// e.g.
//
// LCD_senddata('A');


Now you have seen that its really easy to send command and data to LCD. Now what if we have a string to send to LCD? how we are going to do that?

Is simple, we will store the LCD string in the ROM of controller and call the string character by character. A simple exmple is shown below.


CODE:
;Sending string to LCD Example

LCD_sendstring:
         clr   a                 ;clear Accumulator for any previous data
         movc  a,@a+dptr         ;load the first character in accumulator
         jz    exit              ;go to exit if zero
         acall lcd_senddata      ;send first char
         inc   dptr              ;increment data pointer
         sjmp  LCD_sendstring    ;jump back to send the next character
exit:
         ret                     ;End of routine

; Usage of the above routine
; DPTR(data pointer) will carry the address
; of string to send to LCD.
; e.g. we want to print "LCD Tutorial" on LCD then
;
; mov   dptr,#my_string   ;my_string is the label where the string is stored
; acall LCD_sendstring    ;Send string
;
; To store a string..
; my_string:
; DB   "LCD Tutorial", 00H
; 00H indicate that string is finished.


The equivalent C code Keil C compiler. Similar code can be written for SDCC.

CODE:
void LCD_sendstring(unsigned char *var)
{
     while(*var)              //till string ends
       LCD_senddata(*var++);  //send characters one by one
}
// Using the above function is really simple
// we will pass the string directly to the function
// e.g.
//
// LCD_sendstring("LCD Tutorial");
 



Now we are ready with sending data and sending command to LCD. Now the last and final section which is creating custom characters or patterns to display on LCD. Please proceed to the next section to read more.

Sending Commands to LCD

Sending Commands to LCD

To send commands we simply need to select the command register. Everything is same as we have done in the initialization routine. But we will summarize the common steps and put them in a single subroutine. Following are the steps:
  • Move data to LCD port
  • select command register
  • select write operation
  • send enable signal
  • wait for LCD to process the command

Keeping these steps in mind we can write LCD command routine as.


CODE:
;Ports used are same as the previous example
;Routine to send command to LCD

LCD_command:
         mov   LCD_data,A     ;Move the command to LCD port
         clr   LCD_rs         ;Selected command register
         clr   LCD_rw         ;We are writing in instruction register
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the command
         ret                  ;Return from busy routine

; Usage of the above routine
; A will carry the command for LCD
; e.g. we want to send clear LCD command
;
; mov   a,#01H         ;01H is command for clearing LCD
; acall LCD_command    ;Send the command


The equivalent C code Keil C compiler. Similar code can be written for SDCC.

CODE:
void LCD_command(unsigned char var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in instruction register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}
// Using the above function is really simple
// var will carry the command for LCD
// e.g.
//
// LCD_command(0x01);



Setting cursor position on LCD
To set the cursor position on LCD, we need to send the DDRAM address...
CODE:
Bit7  6   5   4   3   2   1   0
 1   AD6 AD5 AD4 AD3 AD2 AD1 AD0


The seventh bit is always 1, and bit 0 to 7 are DDRAM address (See the introduction section of LCD). so if you want to put the cursor on first position the address will be '0000000B' in binary and 7th bit is 1. so address will be 0x80, so for DDRAM all address starts from 0x80.

For 2 line and 16 character LCD. The adress from 0x80 to 0x8F are visible on first line and 0xC0 to 0xCF is visible on second line, rest of the DDRAM area is still available but is not visible on the LCD, if you want to check this thing, then simply put a long sting greater than 16 character and shift the entire display, you will see all the missing character coming from the back.. this way you can make scrolling line on LCD (see more on shifting display in commands section).

Below is an example for setting cursor position on LCD.

CODE:
;We are placing the cursor on the 4th position
;so the DDRAM address will be 0x03
;and the command will be 0x80+0x03 = 0x83
mov a,#83H           ;load the command
acall LCD_command    ;send command to LCD


CODE:
// to do the same thing is C
// as we done before
LCD_command(0x83);

Checking Busy Flag

►Reading the busy Flag

As discussed in the previous section, there must be some delay which is needed to be there for LCD to successfully process the command or data. So this delay can be made either with a delay loop of specified time more than that of LCD process time or we can read the busy flag, which is recomended. The reason to use busy flag is that delay produced is almost for the exact amount of time for which LCD need to process the time. So is best suited for every application.


Steps to read busy flag

when we send the command, the BF or D7th bit of the LCD becomes 1 and as soon as the command is processed the BF = 0. Following are the steps to be kept in mind while reading the Busy flag.
  • Select command register
  • Select read operation
  • Send enable signal
  • Read the flag

So following the above steps we can write the code in assembly as below...


CODE:
;Ports used are same as the previous example

LCD_busy:
         setb   LCD_D7        ;Make D7th bit of LCD data port as i/p
         setb   LCD_en        ;Make port pin as o/p
         clr    LCD_rs        ;Select command register
         setb   LCD_rw        ;we are reading
check:
         clr    LCD_en        ;Enable H->L
         setb   LCD_en
         jb     LCD_D7,check  ;read busy flag again and again till it becomes 0
         ret                  ;Return from busy routine


The equivalent C code Keil C compiler. Similar code can be written for SDCC.

CODE:
void LCD_busy()
{
     LCD_D7   = 1;           //Make D7th bit of LCD as i/p
     LCD_en   = 1;           //Make port pin as o/p
     LCD_rs   = 0;           //Selected command register
     LCD_rw   = 1;           //We are reading
     while(LCD_D7){          //read busy flag again and again till it becomes 0
           LCD_en   = 0;     //Enable H->L
           LCD_en   = 1;
     }
}


The above routine will provide the necessary delay for the instructions to complete. If you dont want to read the busy flag you can simply use a delay routine to provide the a specific ammount of delay. A simple delay routine for the LCD is given below.

CODE:
LCD_busy:
         mov  r7,#50H
back:
         mov  r6,#FFH
         djnz r6,$
         djnz r7,back
         ret                  ;Return from busy routine



CODE:
void LCD_busy()
{
         unsigned char i,j;
         for(i=0;i<50;i++)        //A simple for loop for delay
            for(j=0;j<255;j++);
}

Now we are ready with the initialization routine and the busy routine for LCD. In the next section we will see how to send data and command to the LCD.

Initialization of LCD

►LCD Initialization

Before using the LCD for display purpose, LCD has to be initialized either by the internal reset circuit or sending set of commands to initialize the LCD. It is the user who has to decide whether an LCD has to be initialized by instructions or by internal reset circuit. we will dicuss both ways of initialization one by one.


Initialization by internal Reset Circuit

An internal reset circuit automatically initializes the HD44780U when the power is turned on. The following instructions are executed during the initialization. The busy flag (BF) is kept in the busy state until the initialization ends (BF = 1). The busy state lasts for 10 ms after VCC rises to 4.5 V.
  • Display clear
  • Function set:
    DL = 1; 8-bit interface data
    N = 0; 1-line display
    F = 0; 5 x 8 dot character font
  • Display on/off control:
    D = 0; Display off
    C = 0; Cursor off
    B = 0; Blinking off
  • Entry mode set:
    I/D = 1; Increment by 1
    S = 0; No shift

Note: If the electrical characteristics conditions listed under the table Power Supply Conditions Using Internal Reset Circuit are not met, the internal reset circuit will not operate normally and will fail to initialize the HD44780U. For such a case, initial-ization must be performed by the MCU as explained in the section, Initializing by Instruction.



As mentioned in the Note, there are certain condtions that has to be met, if user want to use initialization by internal reset circuit. These conditions are shown in the Table 5 below.

Power supply condition for internal reset circuit
Table 5: Power Supply condition for Internal Reset circuit

Figure 7 shows the test condition which are to be met for internal reset circuit to be active.
Internal power supply reset
Figure 7: Internal Power Supply reset


Now the problem with the internal reset circuit is, it is highly dependent on power supply, to meet this critical power supply conditions is not hard but are difficult to achive when you are making a simple application. So usually the second menthod i.e. Initialization by instruction is used and is recommended most of the time.



Initialization by instructions

Initializing LCD with instructions is really simple. Given below is a flowchart that describles the step to follow, to initialize the LCD.
LCD initialization flow chart
Figure 8: Flow chart for LCD initialization

As you can see from the flow chart, the LCD is initialized in the following sequence...
1) Send command 0x30 - Using 8-bit interface
2) Delay 20ms
3) Send command 0x30 - 8-bit interface
4) Delay 20ms
5) Send command 0x30 - 8-bit interface
6) Delay 20ms
7) Send Function set - see Table 4 for more information
8) Display Clear command
9) Set entry mode command - explained below

The first 3 commands are usually not required but are recomended when you are using 4-bit interface. So you can program the LCD starting from step 7 when working with 8-bit interface. Function set command depends on what kind of LCD you are using and what kind of interface you are using (see Table 4 in LCD Command section).

LCD Entry mode
From Table 3 in command section, you can see that the two bits decide the entry mode for LCD, these bits are:
a) I/D - Increment/Decrement bit
b) S - Display shift.
With these two bits we get four combinations of entry mode which are 0x04,0x05,0x06,0x07 (see table 3 in LCD Command section). So we get different results with these different entry modes. Normally entry mode 0x06 is used which is No shift and auto incremement. I recommend you to try all the possible entry modes and see the results, I am sure you will be surprised.


Programming example for LCD Initialization

CODE:
LCD_data equ P2    ;LCD Data port
LCD_D7   equ P2.7  ;LCD D7/Busy Flag
LCD_rs   equ P1.0  ;LCD Register Select
LCD_rw   equ P1.1  ;LCD Read/Write
LCD_en   equ P1.2  ;LCD Enable

LCD_init:
         mov   LCD_data,#38H  ;Function set: 2 Line, 8-bit, 5x7 dots
         clr   LCD_rs         ;Selected command register
         clr   LCD_rw         ;We are writing in instruction register
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the command
         mov   LCD_data,#0FH  ;Display on, Curson blinking command
         clr   LCD_rs         ;Selected instruction register
         clr   LCD_rw         ;We are writing in instruction register
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the command
         mov   LCD_data,#01H  ;Clear LCD
         clr   LCD_rs         ;Selected command register
         clr   LCD_rw         ;We are writing in instruction register
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the command
         mov   LCD_data,#06H  ;Entry mode, auto increment with no shift
         clr   LCD_rs         ;Selected command register
         clr   LCD_rw         ;We are writing in instruction register
         setb  LCD_en         ;Enable H->L
         clr   LCD_en
         acall LCD_busy       ;Wait for LCD to process the command
         ret                  ;Return from routine


Now we can do the same thing in C, I am giving example using Keil C. Similar code can be written for SDCC.
CODE:
#include <AT89X51.H>.
#define LCD_data P2
#define LCD_D7   P2_7
#define LCD_rs   P1_0
#define LCD_rw   P1_1
#define LCD_en   P1_2

void LCD_init()
{
     LCD_data = 0x38;     //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x0F;     //Display on, Curson blinking command
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x01;     //Clear LCD
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x06;     //Entry mode, auto increment with no shift
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_busy();
}



With the help of the above code, you are able to initialize the LCD. Now there is a function/subroutine coming in the code i.e. LCD_busy, which is used to put delay for LCD so that there should not be any command or data sent to the LCD untill it finish executing the command. More on this delay routine is explained in the next section.

LCD COMMANDS

►Commands and Instruction set

Only the instruction register (IR) and the data register (DR) of the LCD can be controlled by the MCU. Before starting the internal operation of the LCD, control information is temporarily stored into these registers to allow interfacing with various MCUs, which operate at different speeds, or various peripheral control devices. The internal operation of the LCD is determined by signals sent from the MCU. These signals, which include register selection signal (RS), read/write signal (R/W), and the data bus (DB0 to DB7), make up the LCD instructions (Table 3). There are four categories of instructions that:

  • Designate LCD functions, such as display format, data length, etc.
  • Set internal RAM addresses
  • Perform data transfer with internal RAM
  • Perform miscellaneous functions


LCD type HD44780 command and instruction set
Table 3: Command and Instruction set for LCD type HD44780


Although looking at the table you can make your own commands and test them. Below is a breif list of useful commands which are used frequently while working on the LCD.


No. InstructionHexDecimal
1 Function Set: 8-bit, 1 Line, 5x7 Dots 0x3048
2 Function Set: 8-bit, 2 Line, 5x7 Dots 0x3856
3 Function Set: 4-bit, 1 Line, 5x7 Dots 0x2032
4 Function Set: 4-bit, 2 Line, 5x7 Dots 0x2840
5Entry Mode0x066
6 Display off Cursor off
(clearing display without clearing DDRAM content)
0x088
7 Display on Cursor on 0x0E14
8 Display on Cursor off 0x0C12
9 Display on Cursor blinking 0x0F15
10 Shift entire display left 0x1824
12 Shift entire display right 0x1C30
13 Move cursor left by one character 0x10 16
14 Move cursor right by one character 0x1420
15 Clear Display (also clear DDRAM content)0x011
16 Set DDRAM address or coursor position on display 0x80+add* 128+add*
17 Set CGRAM address or set pointer to CGRAM location0x40+add**64+add**
Table 4: Frequently used commands and instructions for LCD

* DDRAM address given in LCD basics section see Figure 2,3,4
** CGRAM address from 0x00 to 0x3F, 0x00 to 0x07 for char1 and so on..

The table above will help you while writing programs for LCD. But after you are done testing with the table 4, i recommend you to use table 3 to get more grip on working with LCD and trying your own commands. In the next section of the tutorial we will see the initialization with some of the coding examples in C as well as assembly.


LCD Tutorial Index
Introduction to LCD Sending command & Data to LCD
Basics of LCD Creating custom characters
LCD Commands LCD in 4-bit Mode - Introduction
Initializing the LCD LCD in 4-bit Mode - Programming
Checking Busy Flag of LCD