Friday, July 26, 2013

Utilizing Alphanumeric LCD Displays

In this tutorial I am going to target peoples who do not have much experience in embedded designs. Interfacing a LCD display is not a tough work if you know C language and Data sheet reading mechanism. In internet you can find the milliner of tutorials about LCD interfacing but these all are very complicated because every tutorial writer uses another library written by a person they ever never known. Therefore they don’t know how to minimize the code effectively. Through this tutorial I wish to give very simple algorithm to interface any type of alphanumeric displays. I am sure you can write an own code for LCD interfacing after this tutorial.

Hardware Interfacing

 
Hint:
 In according to above diagram, RW is connected to ground .Because in my algorithm I wish to data transfer towards PIC to LCD only.
If you use RC port higher 4-bits, you should have discipline to connect it to LCD higher pin numbers. Otherwise, if you user lower 4 bits, you should have discipline to connect it to LCD lower pin numbers
For adjusting contrast of the LED, you can use a 1K variable resister to VEE pin. When you are working with LCD, it contrast should be low.( To increase the deadline on the LCD)

   

Identify LCD pin functions (20x4)

Data busses(D0-D7)

I have used 4-bit interfacing method. That mean, though the LCD has eight data busses, we have used only four data busses. By using these buses we can pass data, PIC to LCD or LCD to PIC. LCD module has a standard method to give instructions. Therefore, first we have to give command and secondly we can give data. However, data busses are the only one communication way. Therefore there is another variable which can identify data or command.

Register select (RS)

RS is the abbreviation name of Register select. Its function is identify, which are data or command. If RS has zero (0) bit value, data busses are going to communicate commands. If RS has one (1) bit value, data busses are going to communicate data. In according to before paragraph, these buses can pass data, PIC to LCD or LCD to PIC. So that, there should be another variable to identify what is the exact direction data are being travelling.

Read /write(RW)

R/w is the abbreviation name of Read /write. Its function is identifying the data travelling direction. If R/w has zero (0) bit value, data busses are going to communicate commands or data, PIC to LCD. If R/w has one (1) bit value, data busses are going to communicate commands or data, LCD to PIC.

Enable (E)

E is the abbreviation name of enable. Its function is getting external data from data busses or giving internal data to data busses. When it is in falling edge situation, that particular data communication will occur. That mean, it occurs when E terminal voltage reduced 5V to 0V.


Instruction set



To work LCD correctly we have to give some kind of instructions to LCD module by using PIC. By using these instructions we can configure it to data display.
Since we use 4bit interface mode, we use only four data busses. But all instruction set command has eight bits. Therefore, 8 bit command should communicate correctly with LCD by using 4 busses. You will see in function set instruction which is last three most significant bits has a code such as 001. That code identifies what the given instruction set command is.  Therefore, first we should commutate last four most significant bits then can be commutated first four bits.
Hint: - If you use last 4-bit of a port as data busses, you have to swap 8-bit after the first pulse calling. If you use first 4-bit of a port as data busses, you have to swap 8-bit before the first pulse calling.  
After the command given, RS should make as zero. Then it will identify given thing as instructions. Then RW should make as zero and it will identify data transferring direction as PIC to LCD. Next step is 8-bit code converting correctly to 4-bit code. After that, display will get given data by PIC through the data busses when E is in falling edge

Function set

Function set instructions gives information about size of font, number of lines and interfacing method.
0
0
1
DL
N
F
*
*
 
DL
DL=0 ; four bit interface
DL=1 eight bit interface
N
N=0  ;0ne duty line
 N=1; two duty line
F
F=0 ; 5x7 dots
F=1 ; 5x10 dots
 
In our program since we used four bit interfacing method, DL should be zero, and, both of N and F should be one since we used two lines with 5 by 10 sizes.
Code for function set
0
0
1
0
1
1
0
0
 

Display on\off

Display on\off instruction gives information about curser off\on, curser blink on\off and display on \off.
0
0
0
0
1
D
C
B
 
D
D=0 ; Display off
D=1  Display ON
C
C=0  ;curser off
C=1;  curser ON
B
B=0 ;  curser blink off
B=1 ;  curser blink ON
 
Code for Display on\off
0
0
0
0
1
1
1
1
 

Display clear

Code for Display clear
0
0
0
0
0
0
0
1
 

Entry mode set

Entry mode set instruction gives information about Sets cursor move direction, specifies to shift the display .These operations are performed during data read/write.
0
0
0
0
0
0
I/D
S
 
I/D
I/D=0 ; Decrement cursor position
I/D=1  Increment cursor position
S
S=0  ;No display shift
S=1;    display shift
 
Code for Entry mode set
0
0
0
0
0
0
1
0
 

Algorithm

#include<p18f2520.h>
#include <delays.h>
/*PIC 18f2520 CONFIGURATION BIT SET IN MANUAL */

#define E LATBbits.LATB2 // PORTB BIT 2 DEFINE AS E
#define RS LATBbits.LATB1// PORTB BIT 1 DEFINE AS RS

void lcd_int (void);
void send_cmd2 (unsigned char cmd2);
void LCD_send(unsigned char ch);
void send_data (void);
void pulse (void);
unsigned char l1=0x08,l2=0xC0,l3=0x94,l4=0xD4; //4 ROWS STARTING ADDRESS 
void send_char (unsigned char dat);
void SendString(unsigned char i,char *);
char text[]={"N.A SANUJI KALHAN"};// TEXTS NEED TO DISPLAY
char text1[]={"SRI LANKAN DUDE"}; // TEXTS NEED TO DISPLAY
/*-----------------------------------------------------------------------*/
void main()
{
 ADCON1=0x0f;     // ALL PORTS ARE DIGITAL
 TRISC=0 ;        // PORTC OUTPUT
 TRISB=0 ;  // PORTB OUTPUT
    E=0  ;
    lcd_int();      // CALL FOR LCD initiation
SendString(l2+2,text); // SHIFT 2 COLUMNS OF ROW 2 AND DISPLAY TEXT
SendString(l3+3,text1);// SHIFT 3 COLUMNS OF ROW 3 AND DISPLAY TEXT1
while(1);             // FOREVER HERE
}
/*-----LCD initialization------ */
void lcd_int (void)
{
 send_cmd2(0b0000000001); // CLEAR DISPLAY
 Delay1KTCYx(310);
 send_cmd2(0b0000000010);
  Delay1KTCYx(310);
 send_cmd2(0b0000000110); 
  Delay1KTCYx(1);
 send_cmd2(0b0000001110);
 Delay1KTCYx(1); 
  send_cmd2(0b0000101100);
 Delay1KTCYx(1);
}
/*-----SENDING COMMANDS--------- */
void send_cmd2 (unsigned char cmd2)
{
 RS=0;
 LCD_send(cmd2);
}
/*---SENDING DATA------- */
void send_char (unsigned char dat )
{
 RS=1;
 LCD_send(dat);
}
/*---DATA OR COMMAND PACK TO 4-BIT MODE------- */
void LCD_send(unsigned char cmd)
{
unsigned char cmd2;
cmd2=cmd;
Nop();
TRISC=0;
LATC=LATC&0b00001111;
cmd=cmd&0b11110000;
LATC=LATC|cmd;
Nop();
pulse();
LATC=LATC&0b00001111;
cmd2 =cmd2 <<4;
cmd2=cmd2&0b11110000;
LATC=LATC|cmd2;
Nop();
pulse();
Nop();
 Delay10TCYx(1000);
Nop();

}
/*--ENABLE TO DATA acquisition */
void pulse (void)
{  
      Delay10TCYx(100);
     E=1;
     Delay10TCYx(100);
     E=0;
  Delay10TCYx(100);
   
}
/*------SEND DATA AND ITS POINTER-----------  */
void SendString(unsigned char i,char *ptr)
{ send_cmd2(i);
  while(*ptr!=0)
  {
 send_char(*ptr);
 ptr++;
 }
}
 

After successful coding, text can be seen as following

 

 
 

Saturday, July 6, 2013

Identify OV7670 Cam is burned or not !

Lot of people start to work with OV7670+fifo buffer camara but they are stuck at the first step because they can not figure it out wherther camara is burned or not.  In this tutorial I just introduce a methord to idetyfy this vencher.

In these days peoples are more familiar  to work with Arduino bords rather than PIC microcontrolles. I heare also used the Arduino uno boad because I could find  I2c library eassily.

Important: You need to set two 4.7k or 10k resistor on pull up mode to the SCA and SDA lines seperatly otherwise it will not work.

code :
Figure 1
#include<I2C.h>
void setup(){
  
  Serial.begin(9600);
 
}
  void loop (){
   I2c.scan();
   
  }

figure 1 shows the results ! that mean your cam is still alive !!

How to read register value

In this example I am going to read Manufacture ID. Let's gets ov7670 camara data sheet and turn into page number 14. Then you will see following  register valuse (as a figure 2).

                                                                        Figure 2

now need to write a code to identify 1C and 1D registar address. I heare only go to identfy 1D. then anser should be 0xA2 hex ( in dec  162).it is shown below figure.

Code:

#include<I2C.h>
int start ();
int c;
void setup(){
  Serial.begin(9600);
}
  void loop (){
   
   Serial.println(start () );
   delay(500);
  }
   
int start ()
{
I2c.begin();
I2c.write(0x21,0x1D);
I2c.end();
delayMicroseconds(2);
I2c.begin();
I2c.read(0x21,0x1D);
c=I2c.receive();
I2c.end();
return(c);
}

Cheers ! Now you can read register values tooo so that be a happy man since your cam is still alive !!!!!!!!!!!!!!!!!!!!   see you soon !