Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

i2c question

Status
Not open for further replies.

bassem

New Member
hay sir
thank for you good program
please i have a problem with ATmega32u4 i2c communication
so first i use ATmega32 with PCA9536 so the programme work correctly
now i like to use ATmega32u4 with PCA9536
so i use your i2c program but i dont have a result maybe you have a idea to help me
the adresse of PCA9536 is 0x82

so this is the programme with ATmega32u4

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#define SCL_CLOCK 400000L

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <util/twi.h>
#include <stdlib.h>
//#include "i2c_master.h"

void init_i2c();
void send_i2c(uint8_t);
int8_t read_i2c();
void send_address_i2c(uint8_t adr, uint8_t w);
void start_i2c();
void connect_i2c(uint8_t,uint8_t);
void stop_i2c();

void init_i2c() {
PORTD &= ~(1 << 0);
PORTD &= ~(1 << 1);
// TODO Port für SCL und SDA
TWBR = ((( F_CPU / SCL_CLOCK ) - 16) / 2);
TWSR = 0;
TWCR = ( 1 << TWEN ); // enable the i2c bus f
}
void connect_i2c(uint8_t adr, uint8_t w) {

start_i2c();
send_address_i2c(adr,w);
}

void start_i2c() {
uint8_t twstatus;
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

// wait until transmission completed
while ( !(TWCR & (1<<TWINT))) ;
twstatus = TW_STATUS & 0xF8;
if ((twstatus != TW_START) && (twstatus != TW_REP_START)){
//#ifdef DEBUG
//print("\n |Error: Start -> ");
//phex(TWSR & 0xF8);
//#endif
}
}

void send_address_i2c(uint8_t adr, uint8_t w) {
uint8_t twstatus;
TWDR = (adr<<1) | w ;
TWCR = (1 << TWINT) | (1<<TWEN);

while(!(TWCR & (1 << TWINT)));
twstatus = TW_STATUS & 0xF8;
if ( (twstatus != TW_MT_SLA_ACK) && (twstatus != TW_MR_SLA_ACK) ) {
//#ifdef DEBUG
//print("\n |Error: ADRESS -> ");
//phex(TWSR & 0xF8);
//#endif
}
}

void stop_i2c() {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
while(TWCR & (1 << TWSTO));
}

void send_i2c(uint8_t data) {
uint8_t twstatus;
// send data to the previously addressed device
TWDR = data;
TWCR = (1 << TWINT) | (1<<TWEN);

// wait until transmission completed
while(!(TWCR & (1 << TWINT)));
twstatus = TW_STATUS & 0xF8;
if( twstatus != TW_MT_DATA_ACK){

//#ifdef DEBUG
//print("\n |Error: Data -> ");
//phex(TWSR & 0xF8);
//phex(TW_MT_DATA_ACK);
//#endif
}
}
int8_t read_i2c() {
TWCR = (1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
return TWDR;
}

int main(void)
{


init_i2c(); // Starte I2C Bus
/* PCA9536 auf OUTPUT MODUS umstellen - Nur einmal notwendig! */
start_i2c(0x82); /* 0x82 = Schreib Modus */
send_i2c(0x03); /* Index auf CONFIG REGISTER stellen */
send_i2c(0x00); /* Alle Port Pins auf OUTPUT MODUS stellen */
stop_i2c();

while(1)
{

start_i2c(0x82); // Adresse PCA 9536 0x82 = Schreib Modus
send_i2c(0x01); // Index auf OUTPUT DATA stellen
send_i2c(0x00); // Pins stellen – alle aus
stop_i2c();
_delay_ms(50);

start_i2c(0x82); // Adresse 0x82 = Schreib Modus
send_i2c(0x01); // Index auf OUTPUT DATA stellen
send_i2c(0x01); // Pins stellen – 1 an
stop_i2c();
_delay_ms(50);

start_i2c(0x82); // Adresse 0x82 = Schreib Modus
send_i2c(0x01); // Index auf OUTPUT DATA stellen
send_i2c(0x02); // Pins stellen – 2 an
stop_i2c();
_delay_ms(50);

start_i2c(0x82); // Adresse 0x82 = Schreib Modus
send_i2c(0x01); // Index auf OUTPUT DATA stellen
send_i2c(0x04); // Pins stellen – 3 an
stop_i2c();
_delay_ms(50);

start_i2c(0x82); // Adresse 0x82 = Schreib Modus
send_i2c(0x01); // Index auf OUTPUT DATA stellen
send_i2c(0x08); // Pins stellen – 4 an
stop_i2c();
_delay_ms(50);

}



}



// this the program with ATmega32 ho the PCA9536 work correctly

// master.h
#define I2C_READ 0x01
#define I2C_WRITE 0x00

void i2c_init(void);
uint8_t i2c_start(uint8_t address);
uint8_t i2c_write(uint8_t data);
uint8_t i2c_read_ack(void);
uint8_t i2c_read_nack(void);
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
void i2c_stop(void);

//master.c
#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <util/twi.h>

#include "i2c_master.h"

#define F_SCL 100000UL // SCL frequency
#define Prescaler 1
#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)

void i2c_init(void)
{
TWBR = (uint8_t)TWBR_val;
}

uint8_t i2c_start(uint8_t address)
{
// reset TWI control register
TWCR = 0;
// transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );

// check if the start condition was successfully transmitted
if((TWSR & 0xF8) != TW_START){ return 1; }

// load slave address into data register
TWDR = address;
// start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );

// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

return 0;
}

uint8_t i2c_write(uint8_t data)
{
// load data into data register
TWDR = data;
// start transmission of data
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );

if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }

return 0;
}

uint8_t i2c_read_ack(void)
{

// start TWI module and acknowledge data after reception
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// return received data from TWDR
return TWDR;
}

uint8_t i2c_read_nack(void)
{

// start receiving without acknowledging reception
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// return received data from TWDR
return TWDR;
}

uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
{
if (i2c_start(address | I2C_WRITE)) return 1;

for (uint16_t i = 0; i < length; i++)
{
if (i2c_write(data)) return 1;
}

i2c_stop();

return 0;
}

uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
{
if (i2c_start(address | I2C_READ)) return 1;

for (uint16_t i = 0; i < (length-1); i++)
{
data = i2c_read_ack();
}
data[(length-1)] = i2c_read_nack();

i2c_stop();

return 0;
}

uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
{
if (i2c_start(devaddr | 0x00)) return 1;

i2c_write(regaddr);

for (uint16_t i = 0; i < length; i++)
{
if (i2c_write(data)) return 1;
}

i2c_stop();

return 0;
}

uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
{
if (i2c_start(devaddr)) return 1;

i2c_write(regaddr);

if (i2c_start(devaddr | 0x01)) return 1;

for (uint16_t i = 0; i < (length-1); i++)
{
data = i2c_read_ack();
}
data[(length-1)] = i2c_read_nack();

i2c_stop();

return 0;
}

void i2c_stop(void)
{
// transmit STOP condition
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
//main.c

#include <avr/io.h>
#include <util/delay.h> // add this to use the delay function
#include <stdio.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <stdlib.h>
#include "i2c_master.h"


int main(void)
{
i2c_init(); // int I2C Bus

i2c_start(0x82); /* 0x82 adresse of PCA9536*/
i2c_write(0x03); /* configurate the registre of PCA9536*/
i2c_write(0x00); /* put all port of PCA9536 output*/
i2c_stop(); /* stop TWI */

while(1)
{

i2c_start(0x82); /* 0x82 adresse of PCA9536*/
i2c_write(0x01); // Index auf OUTPUT DATA stellen
i2c_write(0x00); // put all output in 0V
i2c_stop(); /* stop TWI */
_delay_ms(50);

i2c_start(0x82); /* 0x82 adresse of PCA9536*/
i2c_write(0x01); // Index auf OUTPUT DATA stellen
i2c_write(0x01); // Index auf OUTPUT DATA stellen
i2c_stop(); /* stop TWI */
_delay_ms(50);

}
}

thank you for answer and for you help
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top