Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interfacing PCF8574 with 89c52

Status
Not open for further replies.

yviswanathbe

Full Member level 4
Joined
Jun 14, 2007
Messages
221
Helped
10
Reputation
20
Reaction score
6
Trophy points
1,298
Activity points
3,066
Hi,

I want to interface PCF8574 I2C GPIO Expander with 89C52 micro controller.

My application is to interface 20x4 Character LCD and 4x4 Matrix Keypad with the 89C52 micro controller using I2C.

Before connecting LCD and KEYPAD, i am just trying to toggle LED.

I have connected the PCF8574 to the 89C52 with two GPIO's and LED is connected to the PCF8574.
I am using Bit banging as the 89C52 doesn't supports I2C.

But i am not able to communicate with the PCF8574.

I am simulating in Proteus. I have attached the Source code and Proteus File.

Can somebody please suggest me what is the mistake i am doing.

Thanks and Regards,
Viswanath

- - - Updated - - -

Hi,

I got solved my problem.

The bug is in I2C Functions send_byte and Receive_byte, i have declared a variable with XDATA.
I have removed this and my code is working fine.
Can somebody tell me the reason why when a variable declared with XDATA did not work.

Now i will try connecting the KEYPAD and LCD.

Thanks and Regards,
Viswanath.
 

Attachments

  • PCF8574.rar
    52.8 KB · Views: 50

Hi,

Now i have connected 20x4 LCD to ther Micro controller via PCF8574 I2C Expander.

I have used two PCF8574 chips to work with the LCD in 8 bit mode. This mode is working fine.

Now i have connected only one PCF8574 chip to connect the LCD in 4bit mode. But my LCD is blank.

I have attached the c code which i have written for 4 bit mode. can some body suggest me the bug in the code.

Code:
#include<reg52.h>
#include<stdio.h>

typedef unsigned char 	UC;
typedef unsigned int 	UI;
typedef unsigned long 	UL;

#define SCKHIGH  		SCK=1;
#define SCKLOW   		SCK=0;
#define SDAHIGH  		SDA=1;
#define SDALOW   		SDA=0;

sbit SDA			=	P0^1; //serial data pin
sbit SCK			=	P0^0; //serial clock pin

void lcd_reset();
void lcd_init(void);		// Initialize LCD
void lcd_busy(void);		// Check Busy	
void lcd_cmd(UC);
void lcd_data(UC);
void dis_cmd(UC);
void dis_data(UC);
void wrt_string(UC*);	// Sending String
void wrt_value(UC);		// Sending 8-bit Decimal value
void cursorxy(UC,UC);	// Bringing Cursor to (X,Y) location X -> 1,2 and Y -> 1-16

//void lcd_4bitcmd(char);
void delay_ms(int);
void delay_m(UI);
void start(void);
void stop(void);
void send_byte(UC);
UC receive_byte(UC);
void write_i2c(UC,UC,UC);
void write(UC,UC);
UC read_i2c(UC,UC);

char slave_ack;
//starts i2c, if both SCK & SDA are idle
void start(void)
{  
	if(SCK==0) 						//check SCK. if SCK busy, return else SCK idle
	{	
		return;
	}
	if(SDA==0) 						//check SDA. if SDA busy, return else SDA idle
	{
		return;
	}
	SDALOW 							//data low
	delay_m(1);
	SCKLOW  						//clock low    
	delay_m(1);
}           

//stops i2c, releasing the bus
void stop(void)
{         
	SDALOW 							//data low
	SCKHIGH 						//clock high
	delay_m(1);
	SDAHIGH 						//data high
	delay_m(1);
}
//transmits one byte of data to i2c bus
void send_byte(UC c)
{
	UC mask=0x80;
	do  							//transmits 8 bits
	{
		if(c&mask) 					//set data line accordingly(0 or 1)
		{
			SDAHIGH 				//data high
		}
		else
		{	
			SDALOW 					//data low
		}
		SCKHIGH   					//clock high
		delay_m(1);
		SCKLOW   					//clock low
		delay_m(1);
		mask/=2;  					//shift mask
	}while(mask>0);
	SDAHIGH  						//release data line for acknowledge
	SCKHIGH  						//send clock for acknowledge
	delay_m(1);
	slave_ack=SDA; 					//read data pin for acknowledge
	SCKLOW  						//clock low
	delay_m(1);
}       

//receives one byte of data from i2c bus
UC receive_byte(UC master_ack)
{
	UC c=0,mask=0x80;
	do  							//receive 8 bits
	{
		SCKHIGH 					//clock high
		delay_m(1);
		if(SDA==1) 					//read data
		{
			c|=mask;  				//store data
		}
		SCKLOW  					//clock low
		delay_m(1); 
		mask/=2; 					//shift mask
	}while(mask>0);
	if(master_ack==1)
	{
		SDAHIGH 					//don't acknowledge
	}
	else
	{
		SDALOW 						//acknowledge
	}
	SCKHIGH 						//clock high
	delay_m(1);
	SCKLOW 							//clock low
	delay_m(1);
	SDAHIGH 						//data high
	return c;
}

void write(UC device_id,UC c)
{
	do
	{
		start();      				//starts i2c bus
		send_byte(device_id); 		//select slave device
		if(slave_ack==1)  			//if acknowledge not received, stop i2c bus
		{		
			stop();
		}
	}while(slave_ack==1); 			//loop until acknowledge is received
	//send_byte(location); 			//send address location
	send_byte(c); 					//send data to i2c bus
	stop(); 						//stop i2c bus
	delay_m(4);
}       
//reads one byte of data(c) from slave device(device_id) at given address(location)
UC read_i2c(UC device_id,UC location)
{
	
	UC c=0;
	do
	{
		start();   					//starts i2c bus   
		send_byte(device_id); 		//select slave device
		if(slave_ack==1) 			//if acknowledge not received, stop i2c bus
		{	
			stop();
		}
	}while(slave_ack==1); 			//loop until acknowledge is received
	send_byte(location);  			//send address location      
	stop(); 						//stop i2c bus
	start(); 						//starts i2c bus   
	send_byte(device_id+1); 		//select slave device in read mode
	c=receive_byte(1); 				//receive data from i2c bus
	stop(); 						//stop i2c bus
	return c;
}
void delay_m(UI vall)
{
	int  di=0,dj=0;
	for(di=0;di<vall;di++)
	for(dj=0;dj<15;dj++);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	LCD Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void lcd_reset()
{
	delay_ms(20);
	write(0x40,0x03 | 0x80);
	write(0x40,0x00);
	delay_ms(10);
	write(0x40,0x03 | 0x80);
	write(0x40,0x00);
	delay_ms(1);
	write(0x40,0x03 | 0x80);
	write(0x40,0x00);
	delay_ms(1);
	write(0x40,0x02| 0x80);
	write(0x40,0x00);
	delay_ms(1);
} 
void lcd_init()
{
	lcd_reset();
	/*dis_cmd(0x38);
	dis_cmd(0x0F);
	dis_cmd(0x01);
	dis_cmd(0x06);*/
	dis_cmd(0x02);
	dis_cmd(0x28);
	dis_cmd(0x0C);
	dis_cmd(0x06);
	dis_cmd(0x80);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     waiting for LCD to execute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void lcd_busy()
{
	delay_ms(1);
}

void dis_cmd(char cmd_value)
{
	char cmd_value1;
	/*cmd_value1=cmd_value & 0xF0;
	lcd_cmd(cmd_value);
	cmd_value1=((cmd_value<<4) & 0xF0);
	lcd_cmd(cmd_value1); */
	cmd_value1=((cmd_value>>4) & 0x0F);
	lcd_data(cmd_value1);
	cmd_value1=(cmd_value & 0x0F);
	lcd_data(cmd_value1);
}


void dis_data(char data_value)
{
	char data_value1;
	/*data_value1=data_value & 0xF0;
	lcd_data(data_value);

	data_value1=(data_value<<4) & 0xF0;
	lcd_data(data_value1);*/
	data_value1=((data_value>>4) & 0x0F);
	lcd_data(data_value1);
	data_value1=(data_value & 0x0F);
	lcd_data(data_value1);		
}

void lcd_cmd(char cmdout)
{
	write(0x40,cmdout);
	write(0x40,cmdout | 0x00);
	write(0x40,cmdout | 0x00);
	write(0x40,cmdout | 0x80);
	delay_ms(1);
	write(0x40,cmdout | 0x00);
}

void lcd_data(char dataout)
{
	write(0x40,dataout);
	write(0x40,dataout | 0x20);
	write(0x40,dataout | 0x00);
	write(0x40,dataout | 0x90);
	delay_ms(1);
	write(0x40,dataout | 0x20);
}
void wrt_string(UC *string)
{
	while(*string)
	{
		dis_data(*string++);
	}		
}
void wrt_value(UC x)
{
	UC temp;
	temp = x/0x10;
	if(temp>9)
		return;
	else
		dis_data(temp+0x30);
	temp = x%0x10;
	if(temp>9)
		return;
	else
		dis_data(temp+0x30);
}

void cursorxy(UC x, UC y)
{
	if((x<1||x>2)&&(y<1||y>16))
	{
		x=1;
		y=1;
	}
	if(x == 1)
		dis_cmd(0x7F+y);
	else
		dis_cmd(0xBF+y);
}

void delay_1ms(void)
{
	TMOD=0x10;
	TR1=0;
	TL1=0x18;
	TH1=0xFC;
	TR1=1;
	while(TF1==0);
	TF1=0;
}

void delay_ms(int delay)
{
	int i=0;
	for(i=0;i<delay;i++)
	{
		delay_1ms();
	}
}
void main(void)
{
	int i=0;
	delay_ms(20);
	write(0x40,0x00);
	delay_ms(20);
	lcd_init();			//Intilize LCD in 4-Bit Mode			
	cursorxy(1,1);
	wrt_string("I2C Expander Demo");
	cursorxy(2,1);
	wrt_string("4 bit Mode");
	while(1)
	{
	}
	
}

Thanks and Regards,
Viswanath
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top