connect MC9S08QG8  to a lcd with an 8 bit I/O expander I2C bus

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

connect MC9S08QG8  to a lcd with an 8 bit I/O expander I2C bus

1,415 Views
marmor
Contributor III

hello.
I want to communicate the MC9S08QG8  microcontrolle to a lcd with an 8 bit I/O expander I2C bus(PCF8574A).


I have doubts about the i2c protocol.
assuming that the direction of the 8 bit I/O expander I2C bus(PCF8574A) is 0x38 ( 00111000 )
If I want to send data from the microcontroller ( master) to the lcd (slave ) the steps would be:
1. The start signal is sent
2. Slave address is sent along with the RW bit ( RW = read or write bit .) which will be the LSB bit of the byte to be sent , This bit will be 0 for be a write process. So i place it in the i2c module data register (IICD ) 0x70 ( 01110000 )
3. Expect the acknowledgment signal sent by the slave
4. Sent a data byte
5. Expect the acknowledgment signal sent by the slave
6. Sent a data byte
.....
9. Expect the acknowledgment signal sent by the slave
10. The stop signal is sent


If I want the microcontroller ( master) read data from  lcd (slave ) the steps would be the following :

1. The start signal is sent
2. Slave address is sent along with the RW bit ( RW = read or write bit .) which will be the LSB bit of the byte to be sent , This bit will be 1 for be a read  process. So i place it in the i2c module data register(  IICD) 0x71 ( 01110001 )
3. Ex pect the acknowledgment signal sent by the slave
4 . Read the data byte sent by the slave. This byte is in IICD, so we need to read this register.
5. The master sends an acknowledge signal
6. Read the data byte sent by the slave. This byte is in IICD, so we need to read this register.

7. The master sends an acknowledge signal
....
10. The stop signal is sent


is this right?

 

 

This is the code i've written. it's right?

 

#define PCF8574A_ADDR_FIXED 0x40

#define  RW_READ 0x01

#define  RW_WRITE 0x00

 

void IIC_write_byte(char data,char dir){

 

IICC|=0x30; // MST=1 TX=1 

set_address(dir,RW_WRITE); 

while(IICS_IICIF!=1);

while(IICS_RXAK!=0);     

IICD=data;              

while(IICS_IICIF!=1);   

IICC_MST=0;            

 

}

 

char IIC_read_byte(char dir){

 

char aux_data;

IICC|=0x28; // MST=1 TX=0 TXAK=1

set_address(dir,RW_READ); 

while(IICS_IICIF!=1);    

IICD=data;              

while(IICS_IICIF!=1);  

IICC_MST=0;

}

 

 

void set_address(char dir,char RW){

char aux_dir= dir<<1;        

aux_dir&=0x0F;               

IICD=aux_dir|PCF8574A_ADDR_FIXED|RW;

}


 

MC9S08QG8 datasheet: http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08QG8.pdf

 

PCF8574A datasheet :http://www.nxp.com/documents/data_sheet/PCF8574_PCF8574A.pdf

 

 

This would be the connection between the 8 bit I/O expander I2C bus and the lcd. In the picture refers to a Arduino instead of a MC9S08QG8 microcontroller, but the scheme is the same.

 

11374_11374.jpgSchematic_diagram.jpg

Labels (1)
3 Replies

894 Views
marmor
Contributor III

Hello.
I modified the code I put in the previous post. I have tried this programobserving the SDA line with an oscilloscope and no signal has not appeared. Does anyone know why?

does anyone know how I can check the SDA line with the simulator codewarrior (True -Time simulator & real-time debugger)?

The void set_address (char dir, char RW) function is the same, and is responsible for placing in the IICD register a byte that consists of the slave address shifted one position to the left plus the read or write bit being this the LSB.


void set_address(char dir,char RW){

aux_dir= dir<<1;      

aux_dir&=0x0F;              

IICD=aux_dir|PCF8574A_ADDR_FIXED|RW;

}


The IIC_write_byte function (char data, char dir) is also the same and is responsible for sending a data byte (char data) from master to slave. First send a start signal (MS = 1), then a byte containing the slave address shifted one position to the left,plus the write  bit being this the LSB. We waited for the byte transmit and receive the ACK from slave and then we send the data byte placing it in the IICD register .Wait for the byte is transmitted and receive the ACK from the slave and ended the communication by sending the stop signal (MS = 0).


void IIC_write_byte(char data,char dir){

while(IICS_BUSY!=0);

IICC|=0x30;

set_address(dir,RW_WRITE); 

while(IICS_TCF!=1);

while(IICS_RXAK!=0);     

IICD=data;              

while(IICS_TCF!=1);

while(IICS_RXAK!=0);   

IICC_MST=0;                   

}


The IIC_read_byte function (char dir) has changes . First we set the master as transmitter (TX = 1) and send a start signal (MS = 1) then send a byte containing the slave address shifted one position to the left,the reading  bit being this  the LSB . We waited for the byte transmit and receive the ACK from the slave and we set master as a receiver (TX = 0) and the ACK sending  by the master is canceled( TXAK = 1). We wait until the slave transmit one byte of data and we copy the contents of IICD register in an auxiliary variable ( char_aux ) . We send a stop signal to terminate the communication. Finally we return the value of the auxiliary variable.


char IIC_read_byte(char dir){

    char aux_data;

    while(IICS_BUSY!=0);

    IICC|=0x30; // MST=1 TX=1 TXACK=0

    set_address(dir,RW_READ); 

    while(IICS_TCF!=1);    

    while(IICS_RXAK!=0);

    IICC_TX=0;

    IICC_TXAK=1;

    while(IICS_TCF!=1);   

    aux_data=IICD;            

    while(IICS_TCF!=1);

    IICC_MST=0;                   

    return aux_data;

}

The module initialization function is as follows


void IIC_init() {

   IICF=0x0B; // SCL = 100kps

   IICC_IICEN=1; // Enable IIC

   IICC_IICIE=1; //  Enable interrupts

   IICC_MST=0;    // Slave mode. STOP

   IICC_TXAK=0;   // Enable ACK bit.

}


thanks for reading.

regards

0 Kudos
Reply

894 Views
weapon
Senior Contributor I

Hi Maria,

Three points need to care:

1. Be sure SCL and SDA are pulled up

2. Please Polling  IICIF rather than TCF. and if you are using polling, please disable interrupt by clearing IICIE

3. After polling, IICIF should be cleared by writing '1' to this bit.

I attached a sample code of IIC for your reference.

Have a noice day.

894 Views
marmor
Contributor III
Hi weapon.

   I tested your code for the I2C communication and I have adapted to my microcontroller, the write function works fine, but on the function an error reading:

When multiple bytes are sent the last byte is not read and reads the next byte that sends the slave device (which should not happen because it sent the NACK bit) or if it does not send any more bytes the microcontoller reads $ FF and I do not know why it occurs. Any idea what may be going wrong?


I have attached a picture of the input and output data in the I2C module.
The slave device has to send 5 bytes with value $ 5, $ 6, $ 7, $ 8, $ 9, but the master device (microncontrolador) will only read the first 4 bytes ($ 5, $ 6, $ 7, $ 8), the problem is that it reads bytes $ 5, $ 6, $ 7, $ 9 and the microcontroller does not send the NACK bitI2C reading simulation.png


Saludos y gracias de antemano

0 Kudos
Reply