Witam
Już od kilku dni walczę z programowym i2c. Niestety nie bardzo mi to wychodzi
Mój kod wygląda następująco:
Czy widzi ktoś w nim jakieś błędy
PS Program ma emulować i2c z prędkością 100kHz. Zastosowany przy procesorze kwarc to 16MHz (konfiguracja fusów jest odpowiednia dla kwarcu zewnętrznego).
Z góry dziękuje za pomoc
Pozdrawiam maly_elektronik
Już od kilku dni walczę z programowym i2c. Niestety nie bardzo mi to wychodzi
Mój kod wygląda następująco:
#include <avr/io.h>
#include <util/delay.h>
#define DDR DDRC
#define PORT PORTC
#define PIN PINC
//
#define SDA 1
#define SCL 0
//////////////////////////////////////////////////////////////////////////////////////////
void i2c_write(unsigned char data)
{
DDR |= _BV(SDA);
DDR |= _BV(SCL);
char index;
PORT &= ~_BV(SCL);
for(index=0; index<8; index++)
{
if(data & 0x80)
PORT |= _BV(SDA); // ustawienie 1 jeżeli 1
else
PORT &= ~_BV(SDA);// ustawienie 0 jeżeli 0
_delay_us(10); // opuźnienie dla uzyskania prędkości 100kHz
PORT |= _BV(SCL);// ustawienie zegara na 1 w celu odczytania danych przez odbiornik
_delay_us(10); // opuźnienie dla uzyskania prędkości 100kHz
PORT &= ~_BV(SCL);
data<<=1;
}
}
///////////////////////////////////////////////////////////////////////////////////////////
unsigned char i2c_read(unsigned char ACK)
{
DDR &= ~_BV(SDA);
DDR |= _BV(SCL);
unsigned char data=0x00;
char index;
PORT &= ~_BV(SCL);
for(index=0; index<8; index++)
{
data<<=1;
_delay_us(10); // opuźnienie dla uzyskania prędkości 100kHz
PORT |= _BV(SCL);
if(bit_is_clear(PINC,SDA))
data = data;
else
data = (data | 0x01);
_delay_us(10); // opuźnienie dla uzyskania prędkości 100kHz
PORT &= ~_BV(SCL);// ustawienie zegara na 0 w celu zmiany danych wysylanych przez odbiornik
}
if(ACK)
{
PORT |= _BV(SDA);
_delay_us(10);
PORT |= _BV(SCL);
_delay_us(10);
PORT &= ~_BV(SCL);
}
return data;
}
///////////////////////////////////////////////////////////////////////////////////////////
void i2c_start(void)
{
DDR |= _BV(SDA);
DDR |= _BV(SCL);
PORT |= _BV(SDA);
_delay_us(10);
PORT |= _BV(SCL);
_delay_us(10);
PORT &= ~_BV(SDA);
_delay_us(10);
PORT &= ~_BV(SCL);
}
///////////////////////////////////////////////////////////////////////////////////////////
void i2c_stop(void)
{
DDR |= _BV(SDA);
DDR |= _BV(SCL);
PORT &= ~_BV(SDA);
_delay_us(10);
PORT |= _BV(SCL);
_delay_us(10);
PORT |= _BV(SDA);
_delay_us(10);
PORT &= ~_BV(SCL);
}
///////////////////////////////////////////////////////////////////////////////////////////
Czy widzi ktoś w nim jakieś błędy
PS Program ma emulować i2c z prędkością 100kHz. Zastosowany przy procesorze kwarc to 16MHz (konfiguracja fusów jest odpowiednia dla kwarcu zewnętrznego).
Z góry dziękuje za pomoc
Pozdrawiam maly_elektronik