Witam.
Mam dość spory problem nad którym głowie się już od dłuższego czasu i bez żadnych wyników. Mianowicie chciałbym się połączyć z ATtiny2313 za pomocą I2C z EEPROMem AT24C16. Jest to częś grubszego projektu wyświetlacza diodowego. Schemat projektu jest w załączniku.
Poczytałem sobie trochę w książkach o AVRach i Internecie. Przejrzałem noty katalogowe obu elementów. Z nabytą wiedzą zasiadłem do pisania programu. Muszę przyznać, że szło topornie, bo dopiero poznaję język C. Ale coś wydukałem. Efekty mojej pracy jednak nie działają. Kod wklejam poniżej. Jeżeli ktoś mógłby sprawdzić i ewentualnie pomóc to byłbym wdzięczny.
Mam dość spory problem nad którym głowie się już od dłuższego czasu i bez żadnych wyników. Mianowicie chciałbym się połączyć z ATtiny2313 za pomocą I2C z EEPROMem AT24C16. Jest to częś grubszego projektu wyświetlacza diodowego. Schemat projektu jest w załączniku.
Poczytałem sobie trochę w książkach o AVRach i Internecie. Przejrzałem noty katalogowe obu elementów. Z nabytą wiedzą zasiadłem do pisania programu. Muszę przyznać, że szło topornie, bo dopiero poznaję język C. Ale coś wydukałem. Efekty mojej pracy jednak nie działają. Kod wklejam poniżej. Jeżeli ktoś mógłby sprawdzić i ewentualnie pomóc to byłbym wdzięczny.
#include <avr/io.h>
unsigned char word = 0x01; // Adres komórki pamięci
unsigned char dane = 0x7A; // Dane
void main(void)
{
while(1)
{
unsigned char dioda;
long int j;
bitstartu();
zapis_I2C(word, dane);
bitstopu();
bitstartu();
dioda = odczyt_I2C(word);
bitstopu();
word++;
for(j=0; j<1000; j++) // pętla uruchamiająca rejestr przesuwny 74HC595
{
DDRD = 0x3F; // Porty D jako wyjścia
DDRB = 0x7F; // Porty B jako wyjścia
PORTB = dioda; // ustawić powinno wartość 0x7A
PORTD = 0x14; // Narastanie zbocza zegara SCK i sygnał na SI; wrzuca 1 a nastepnie ja przesuwa
PORTD = 0x24; // Opadanie zbocza zegara SCK, narastanie zbocza RCK i sygnał na 1
PORTD = 0x14;
PORTD = 0x24;
PORTD = 0x14;
PORTD = 0x24;
PORTD = 0x14;
PORTD = 0x24;
PORTD = 0x14;
PORTD = 0x24;
PORTD = 0x14;
PORTD = 0x24;
PORTD = 0x14;
PORTD = 0x24;
}
}
}
void bitstartu(void)
{
DDRB = 0xFF;
PORTB = 0x00;
czekaj_I2C(10);
DDRD = 0xFF;
PORTD = 0x00;
czekaj_I2C(10);
DDRB = 0xFF;
PORTB = 0x80;
czekaj_I2C(10);
DDRD = 0xFF;
PORTD = 0x40;
czekaj_I2C(10);
}
void bitstopu(void)
{
DDRB = 0xFF;
PORTB = 0x80;
czekaj_I2C(10);
DDRD = 0xFF;
PORTD = 0x00;
czekaj_I2C(10);
DDRB = 0xFF;
PORTB = 0x00;
czekaj_I2C(10);
}
void zapis_I2C(unsigned char word, unsigned char dane)
{
unsigned char adr_slave;
unsigned char adr_word;
unsigned char dana;
DDRB = 0xFF;
DDRD = 0xFF;
adr_slave = 0xA2;
przesyl(adr_slave);
czekaj_I2C(10);
if (PINB&0x80)
return;
adr_word = word;
przesyl(adr_word);
czekaj_I2C(10);
if (PINB&0x80)
return;
dana = dane;
przesyl(dana);
czekaj_I2C;
if (PINB&0x80)
return;
}
void odczyt_I2C(unsigned char word)
{
unsigned char adr_slave;
unsigned char adr_word;
unsigned char dana;
unsigned char zapal;
DDRB = 0xFF;
DDRD = 0xFF;
adr_slave = 0xA2;
przesyl(adr_slave);
czekaj_I2C(10);
if (PINB&0x80)
return;
adr_word = word;
przesyl(adr_word);
czekaj_I2C(10);
if (PINB&0x80)
return;
bitstartu();
adr_slave = 0xA3;
przesyl(adr_slave);
czekaj_I2C(10);
if (PINB&0x80)
return;
zapal = przechwyt();
czekaj_I2C(10);
PORTB = 0x00;
return zapal;
}
void przesyl(unsigned char adress)
{
unsigned char i;
unsigned char adress_pom;
for(i=0;i<8;i++)
{
adress_pom = adress;
adress &= 0x80;
if (adress==0x80)
{
PORTB = 0x80;
czekaj_I2C(10);
PORTD = 0x08;
czekaj_I2C(10);
PORTD = 0x00;
czekaj_I2C(10);
}
PORTB = 0x00;
czekaj_I2C(10);
PORTD = 0x08;
czekaj_I2C(10);
PORTD = 0x00;
czekaj_I2C(10);
adress = adress_pom;
adress<<=1;
}
}
void przechwyt(void)
{
unsigned char diody;
unsigned char i;
DDRB = 0x00;
DDRD = 0xFF;
for(i=0;i<8;i++)
{
PORTD = 0x08;
czekaj_I2C(10);
if (PINB&0x80)
{
diody |= 0x01;
diody <<= 1;
}
diody <<= 1;
PORTD = 0x00;
czekaj_I2C(10);
}
return diody;
}
void czekaj_I2C(unsigned char tauI2C)
{
do
{
asm("nop");
}while(--tauI2C!=0);
}