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
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