Tuesday, 28 August 2012

KS0108 GLCD with ATmega16


In this tutorial we are going to explain how to interface the graphical LCD with ATmega16 microcontroller and the compiler used is codevision avr. The GLCD used is 128x64 pixel with KS0108 driver.
Since old compilers of codevision doesn't include library for GLCD. Then you have to download the KS0108 GLCD library and you can download it HERE
This library supports English and Arabic and we are going to explain how to use this library in the following steps.

1-Adding The Library to your codevision compiler :

After downloading the files extract them and go to the folder of your installed codevision avr and default it will be in drive c with folder named cvavr2 >> open it copy the files downloaded in the folder named (inc).

2-including the library in your project and configuring connections :

Make a new project and include the GLCD library by writing #include <glcd.h> and the press build all project so that the library is included to modify the connections as shown :


Now you will find that the library is included in the code navigator tab at your left ( see the arrow ) now press on glcd.h to define the PORTS to be connected with LCD as shown in the next figure :


In line1 : Define the PORT for data ( in example we use PORTA , but it can be replaced by any PORT )
In line2 : As PORTA is selected then write DDRA (direction of dataport)
In line3 : As PORTA is selected then write PINA
Line 4 to 8 define the pins of the control signals of the GLCD, you can choose any pin ( in example we used the 1st 5 pins of PORTB )
The last line #define CS_ACTIVE_LOW is used if the control signals cs1 and cs2 are active low, if they are active high this line is commented.

The last thing is to set the used PORTS in connection as OUTPUT pins :
DATADDR = 0xff;              // define data port as output
DDRB = 0x3f;                     // define control pins as output

The connection of the GLCD is shown in the following figure :


3- How to use the library (functions):

In this step we will explain how to use the library and it's functions :

Method
Description
Parameters
glcd_on()
Turn on the GLCD
No
glcd_off()
Turn off the GLCD
No
set_start_line(unsigned char line)
Changes the top line on the display
line: line number to be set at the top (Range: 0 - 63)
goto_col(unsigned int x)
Go to the specified column
x: Column number
(Range: 0 - 127)
goto_row(unsigned int y)
Go to the specified
row 
y: Row address
(Range: 0 - 7)
goto_xy(unsigned int x, unsigned ,int y)
Go to the specified column and row
x: Column number
y: Row address
glcd_write(unsigned char b)
Writes 1 byte data at the
current location
b: 1 – byte data to be written at the current
location
glcd_clrln(unsigned char ln)
Clears the specified row 
ln: the number of the row to be cleared (Range: 0 - 7)
glcd_clear()
Clears the display
No
glcd_read(unsigned char column)
Reads the byte at the current position
column: Current column number 
point_at(
unsigned int x,
unsigned int y,
byte color)
Adds a point at the specified location
x: column number
y: row number
color: 0 : Light spot
         1 : Dark spot
h_line(
unsigned int x,unsigned int y, byte l,byte s,byte c)
Draws a horizontal line
x: The column number at which the line starts
y: The row number at which the line starts
l: Line length
s: The space between line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1= Dark spots
v_line(
unsigned int x,unsigned int y, signed int l,byte s,byte c)
Draws a vertical line
x: The column number at which the line starts
y: The row number at which the line starts
l: Line length
s: The space between line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
line(unsigned int x1,unsigned int y1, unsigned int x2,unsigned int y2, byte s,byte c)
Draws a general (inclined) line
x1: The column number at which the line starts
y1: The row number at which the line starts
x2: The column number at which the line ends
y2: The row number at which the line ends
s: The space between line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
rectangle(
unsigned int x1,unsigned int y1, unsigned int x2,unsigned int y2,
               byte s,byte c)
Draws a rectangle
x1: The x of the upper left point
y1: The y of the upper left point
x2: The x of the lower right point
y2: The y of the lower right point
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
cuboid(
unsigned int x11,unsigned int y11, unsigned int x12,unsigned int y12,
unsigned int x21,unsigned int y21,
unsigned int x22,unsigned int y22,
        byte s,byte c)
Draws a cuboid by defining two surfaces
x11: The x of the upper left point of the first surface
y11: The y of the upper left point of the first surface
x12: The x of the lower right point of the first surface
y12: The y of the lower right point of the first surface
X21: The x of the upper left point of the second surface
Y21: The y of the upper left point of the second surface
x22: The x of the lower right point of the second surface
y22: The y of the lower right point of the second surface
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
h_parallelogram(
unsigned int x1,unsigned int y1,
unsigned int x2,unsigned int y2,
byte l,byte s,byte c)
Draws a parallelogram its upper and lower sides are horizontal
x1: The x of the upper left point
y1: The y of the upper left point
x2: The x of the lower right point
y2: The y of the lower right point
l: The length of the horizontal side (upper or lower)
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
v_parallelogram(
unsigned int x1,unsigned int y1,
unsigned int x2,unsigned int y2,
 byte l,byte s,byte c)
Draws a parallelogram its right and left sides are vertical
x1: The x of the upper left point
y1: The y of the upper left point
x2: The x of the lower right point
y2: The y of the lower right point
l: The length of the vertical side (right or left)
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
h_parallelepiped(
unsigned int x11,unsigned int y11,
unsigned int x12,unsigned int y12,
byte l1,
unsigned int x21,unsigned int y21, unsigned int x22,unsigned int y22,
byte l2,
byte s,byte c)
Draws a parallelepiped its bases are two horizontal parallelograms
(Seeh_parallelogram)
x11: The x of the upper left point of the first surface
y11: The y of the upper left point of the first surface
x12: The x of the lower right point of the first surface
y12: The y of the lower right point of the first surface
X21: The x of the upper left point of the second surface
Y21: The y of the upper left point of the second surface
x22: The x of the lower right point of the second surface
y22: The y of the lower right point of the second surface
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
l1: The length of the horizontal side of the first surface
l2: The length of the horizontal side of the second surface
v_parallelepiped(
unsigned int x11,unsigned int y11,
unsigned int x12,unsigned int y12, byte l1,
unsigned int x21,unsigned int y21,
unsigned int x22,unsigned int y22, byte l2,
byte s,byte c)
Draws a parallelepiped its bases are two vertical parallelograms
(Seev_parallelogram)
x11: The x of the upper left point of the first surface
y11: The y of the upper left point of the first surface
x12: The x of the lower right point of the first surface
y12: The y of the lower right point of the first surface
X21: The x of the upper left point of the second surface
Y21: The y of the upper left point of the second surface
x22: The x of the lower right point of the second surface
y22: The y of the lower right point of the second surface
s: The space between each line points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
l1: The length of the vertical side of the first surface
l2: The length of the vertical side of the second surface
circle(
unsigned int x0,unsigned int y0,
unsigned int r,byte s,byte c)
Draws a circle
x0: The x point of the center of the circle
y0: The y point of the center of the circle
r: Circle’s radius
s: The space between perimeter points:
    0 = solid line
    1 = dotted line
  >1 = dashed line
c:  0 = Light spots
     1 = Dark spots
glcd_putchar(byte c,int x,int y,byte l, byte sz)
Writes a character at the specified position, with size sz
c: The character to be typed
x: The column number to start typing the character at (One character occupies 8 columns)
y: The row number to type the character at
l: The language of the character
   0 = English
   1 = Arabic
sz: Font size (from 1 to 7)
glcd_puts(
byte *c,int x,int y,unsigned char l, byte sz,signed char space)
Writes a string ,stored in the flash memory ,on the display
c: A pointer to the string to be written on the display
x: The column number to start typing the character at (One character occupies 8 columns)
y: The row number to type the character at
l: The language of the character
   0 = English
   1 = Arabic
sz: Font size (from 1 to 7)
space:
English: Character spacing
Arabic and Farsi:Word spacing
bmp_disp(flash byte *bmp,
unsigned int x1,unsigned int y1,
unsigned int x2,unsigned int y2)
Displays a bmp image array stored in the flash memory
bmp: A pointer to the array where the bmp image is stored
x1: The x of the upper left point of the image on the glcd
y1: The y of the upper left point of the image on the glcd
x2: The x of the lower right point of the image on the glcd
y2: The y of the lower right point of the image on the glcd

Examples :

h_line(1,1,20,0,0) à Draws bright horizontal line
h_line(1,1,20,0,1) à Draws dark horizontal line

Writing Arabic and English texts :

#pragma used+
char ar_string[] = "بسم الله الرحمن الرحيم";   
char en_string[] = "Hello";
#pragma used-
glcd_clear();
glcd_puts(ar_string,127,0,1,1,0);//Writes an Arabic string
glcd_puts(en_string,5,5,0,1,0);  //Writes an English(Latin) string

/* note : codevision avr don't support Arabic so when you write Arabic it will appear like this in the editor :"ÈÓã Çááå ÇáÑÍãä ÇáÑÍíã" don't change it */


Special Thanks To Osama's Lab for this great library.
For More details : Osama's Lab : GLCD library

Download the project and it's simulation HERE
Download this tutorial in PDF HERE

Monday, 20 August 2012

Displaying variables on LCD

variables on lcd
LCD is very important when you use micro-controllers.It helps you to know what is happening inside micro-controller.When you use analog sensors such as temperature or humidity sensors and you want to display their values.The value is not constant and keep changing by time (variable).Then how you are going to display this value.

In this simple tutorial  we are going to display variables on LCD using ATmega16 and avr codevision compiler.

The idea is to convert the variable into a string and to do so there is a library called stdlib.h ,which must be included into your program, used to convert a variable of any type to string.This library containing many functions but we are going to explain functions used to display variables :

1- itoa(int n,char *str) :
converts the integer n to characters in string str. i.e. this function convert the int variable n (variable you want to display) to a string and this is an example on how to use it  :
/* 1st you have to define an array of character whose number of elements is max number of digits you are going to display on the lcd i.e. if you are going to display a variable whose max value is 9999 i.e 4 digits then the array will have 4 elements only */
char buffer [4];
/* then convert your variable into a string and each digit in the string is stored in array buffer */
itoa(n,buffer);
// then display your variable using lcd_puts function :
lcd_puts(buffer);

2- ltoa(long int n, char *str) :
converts the long integer n to characters in string str.The same as itoa but for variables with large value ( long ).

3- ftoa(float n, unsigned char decimals, char *str) :
converts the floating point number n to characters in string str. 
The number is represented with a specified number of decimals. 
It's used whe you want to display decimal value where deciamls is the number of digits you want after the deciaml point.
// example :
#include <stdlib.h>
char buffer[8];
x=240.2468;
ftoa(x,4,buffer);     //to display 4 digits after the decimal point
lcd_puts(buffer);


4- ftoe(float n, unsigned char decimals, char *str) :
converts the floating point number n to characters in string str.
The number is represented as a mantissa with a specified number of decimals and an integer power of 10 exponent (e.g. 12.35e-5).
i.e. display your variable in exponential format as shown.
#include <stdlib.h>
char buffer[8];
x=0.0000000245;
ftoe(x,2,buffer);
lcd_puts(buffer);


Download this tutorial in PDF HERE

Thursday, 16 August 2012

Interfacing 7 segment to PIC with just two Pins

In this tutorial we are going to explain how to interface 7 segment display to PIC 16f877a with just two pins !!!!  as shown in the following figure :


As you know that 7 segment requires 7 pins to be connected to PIC and if you use display driver such as 7447 IC it will be reduced to only four pins but if you added a decade counter ( a counter that counts from 0 to 9 ) the number of pins will be reduced to two pins only the connection is shown in the following figure :

 
Now it's very simple assume you want display number 5 on the 7 segment , you only have to send 5 pulses to the counter on the clk pin (in this example we use 7493 decade counter) and the output of the counter will be " 0101 " which is decoded by 7447 IC into it's 7 segment code and displayed it's so simple ...

To send for example 5 pulses to the counter set the pin high >> wait for small time  >> clear the pin >> wait for small time and repeat this sequence for 5 times .
Note : you have to reset the counter after every display so that the counter starts from the beginning and here is a sample of the code to display number 5 :
////////////////////////////////////////////////////////////////
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<5;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
///////////////////////////////////////////////////////////////
note that the delay is very small so that you can't notice the counter counts from 0 to 5 on the 7 segment and only see the digit 5.

Here is the complete function :
void display(char w)
{
if(w==0)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4); // reset timer
}

if(w==1)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);// reset timer
output_high(pin_b0);delay_us(50);output_low(pin_b0);// send digital pulse

}
if(w==2)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<2;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==3)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<3;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==4)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<4;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==5)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<5;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==6)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<6;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==7)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<7;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==8)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<8;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}

if(w==9)
{
output_high(pin_b4);delay_us(50);output_low(pin_b4);
for(i=0;i<9;i++)
{
output_high(pin_b0);delay_us(50);output_low(pin_b0);delay_us(50);
}
}
}

Download the code and simulation HERE
Download this tutorial in PDF HERE

PIC 16f877a with Seven-Segment Display and keypad

Introduction to seven segments display:

The segments in a 7-segment display are arranged to form a single digit from 0 to F. We can display a multi-digit number by connecting additional displays. Even though LCD displays are more comfortable to work  with , 7-segment displays are still standard in the industry. This is due to their temperature robustness and visibility.

Segments are marked with non-capital letters: a, b, c, d, e, f, g and dp , where dp is the decimal point. The 8 LEDs inside each display can be arranged with a common cathode or common anode. With a common cathode display, the common cathode must be connected to the 0V rail and the LEDs are turned on with a logic one. Common anode displays must have the common anode connected to the +5V rail. The segments are turned on with a logic zero. 7-segment displays come in different colors, including: red,orange, and green.

Interfacing :

1- use a display driver such as the 7447 IC which convert the BCD number to it's seven segment code with the PIC (number of pins used is 4 ).
2- Alternatively displays can be driven by a micro-controller (number of pins used is 7 plus the decimal point ).
3- use 7447 with a decade counter (counter counts from 0 to 9) with the microcontroller (uses one pin but is not so fast) More Details

Multiplixing :

if more than one display is required, the method of driving them is called "multiplexing." The main difference between the two methods is the number of  "drive lines." If a single display is to be driven from a micro-controller, 7 lines will be needed plus one for the decimal point. For each additional display, only one extra line is needed.

Each display is turned on at a rate above 100 times per second, and it will appear that all the displays are turned on at the same time. As each display is turned on, the appropriate information must be delivered to it so that it will give the correct reading. Up to 6 displays can be accessed like this without the brightness of each display being affected.

The following truth table shows the seven segment code for each number from 0 to 9
when we used common anode seven- segment:

Keypad :

It's an array of switches such as the following figure :





This is an example of a 3x4 keypad to connect it to the micro-controller it needs 12 digital pins !! which is a large number .





Scanning keypad :

To decrease the number of digital pins required . the keypad is divided into 3 columns and 4 rows  only one column is enabled at a time for example column 1 is enabled by connecting it to 5v . if button 1is pressed then A will be high ,if button 4 is pressed then B will be high and so on then column 2 is enabled and then column 3 is enabled and this sequence is repeated very fast so it appears that it's scanning all the 12 buttons but in fact it scans only four buttons at a time in this manner we decrease the number of digital pins to 7.


The next program scans a keypad and the key pressed is dissplayed on the seven segment display .the microcontroller used is PIC16f877A .
The keypad is connected to PORTC and the 7447 driver is connected to PORTB as shown.



Download the code and simulation HERE
Download this tutorial in PDF HERE