Skocz do zawartości

Zapis/odczyt danych na eeprom przez i2c


maly_ZE

Pomocna odpowiedź

Witam;

Korzystając ze strony http://radzio.dxp.pl/ napisałem (w WinAVR) procedurki obsługujące zapis i odczyt danych z zewnętrznej pamięci eeprom 24c32 po I2C. Problem w tym że nie działają. Tzn zlokalizowałem problem ale nie wiem jak się go pozbyć. Oto listing programu:

 
#include <avr/io.h> 
#include <stdio.h> 
#include <util/delay.h> 
#include <string.h> 
#include <util/twi.h> 
#include "hd44780.h"

// start
void twistart(void) 
{ 
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 
  while (!(TWCR & (1<<TWINT))); 
} 

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

// zapis bajtu danych 
void twiwrite(unsigned char data) 
{ 
  TWDR = data; 
  TWCR = (1<<TWINT) | (1<<TWEN); 
  while (!(TWCR & (1<<TWINT))); 
} 

//odczyt bajtu danych 
int twiread(int ack) 
{ 
TWCR = ack ?  ((1 << TWINT) | (1 << TWEN) | (1 << TWEA)) : ((1 << TWINT) | (1 << TWEN)) ; 
  while (!(TWCR & (1<<TWINT)));
  return TWDR;
} 

int main (void) 
{ 
int j = 0;    
TWBR = 255; 
char tekst[20]="Zmienna: ";

//zapis do eeprom 
twistart(); 
twiwrite(0b10100000); 
twiwrite(2);      //adres      
twiwrite(123);    //wartosc    
twistop();      
_delay_ms(200); 

//odczyt z eeprom uprzednio zapisanej wartosci 
twistart(); 
twiwrite(0b10100000); 
twiwrite(2); 
twistart(); 
twiwrite(0b10100001); 
j=twiread(0);      //O - NOACK 
twistop();

//na wyswietlacz
LCD_LOCATE(0,0);
lcd_puts(tekst);
LCD_LOCATE(9,0);
sprintf(tekst,"%d",j);
lcd_puts(tekst);
return 0;
}


Problem jest z funkcją twiread a mianowicie w miejscu: while (!(TWCR & (1<

Nie mam pojęcia dlaczego sie tak dzieje, może ktoś mi pomóc wyeliminować problem.?

Z góry serdecznie dziękuję

Pozdrawiam

Adrian

Link do komentarza
Share on other sites

Witam, rozwiązałeś już problem z tym I2C?

Jeżeli NIE:

1) Jeśli taki oto kod kompilujesz i wgrywasz do mikrokontrolera to nie będzie działał. Mikrokontroler przechodzi przez program dokładnie 1 raz po czym go opuszcza, jeśli chcesz aby program działał cyklicznie, musisz w funkcji main zaraz po konfiguracji portów i rejestrów wrzucić pętlę while, a w nią ten kawałek kodu, który ma się w kółko mielić i np mrugać ledą, czy odczytywać dane po I2C 😉

2) Ustawiasz TWBR na wartość 255. Wrzuczsz do programu bibliotekę nie definiując wcześniej wartości F_CPU (czyli domyślnie ATmega ustawia się na skalibrowany zegar RC o prędkości 1MHz), stąd prędkość zegara na szynie SCL wynosi ok 4,86kHz - prawdopodobnie za mało dla tej pamięci, gdyż pewno chce prędkości SCL rzędu 100kHz lub 400kHz.

Jeżeli TAK:

Jak wrażenia? Sam mam zamiar postawić I2C na mikrokontrolerze i nie wiem czy mój program zadziała (a jest podobny do Twojego) 😋

Link do komentarza
Share on other sites

Magistrala I2C nie ma ograniczenia prędkości pracy w dół - można i taktować z częstotliwością 1Hz.

Ja osobiście dopiero zaczynam zabawę z I2C 😋 i dobrze wiedzieć, że tak jest, bo chcę odczytać dane z kontrolera Nunchuk do Nintendo WII, który chodzi z prędkością 400kHz - więc dzięki za info. Na razie bawiłem się zdalnym portem PCF8574A i funkcje do obsługi zapisu i odczytu działają bez zarzutu u mnie. Co do tej kostki EEPROM, to prawdopodobnie jutro ją sobie kupię, bo kosztuje śmieszne pieniądze, mnie osobiście się przyda a i Autorowi wątku coś może dopomogę 😉

Dobrze, żeby Autor wątku dopisał, z jakiego mikrokontrolera korzysta...

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Magistrala I2C nie ma ograniczenia prędkości pracy w dół - można i taktować z częstotliwością 1Hz.

Jednak trzeba uważać na timeout'y po stronie urządzenia. Zazwyczaj w dokumentacji jest jak długo urządzenie po przejściu w tryb transmitter czeka na adres z którego ma wysłać dane. Jeżeli się go przekroczy trzeba nawiązać komunikację ponownie.

Jeżeli już mowa o I2C to przestrzegam przed używaniem konwerterów napięć przy liniach SDA i SCL (ja próbowałem skorzystać z modułu KAmodLVC). Usiłowałem skomunikować Atmege 5V z urządzeniami na 3.3V - bezskutecznie. Ale czasu straciłem co nie miara;)

Link do komentarza
Share on other sites

Cóż, a ja właśnie z powodzeniem komunikowalem się przez ten konwerter z lis35de po i2c. A co do timeoutow to trzeba to dla każdej kostki sprawdzić.

Co do problemu, czy Autor ma rezystory podciagające na liniach w odpowiednich miejscach?

Link do komentarza
Share on other sites

Cóż, a ja właśnie z powodzeniem komunikowalem się przez ten konwerter z lis35de po i2c.

To dziwna sprawa... Ja mam dwa takie konwertery i zarówno z SPI oraz UARTEM działają, natomiast ani z bmp085 ani z żadnym z dwóch termometrów tmp102 nie udało mi się skomunikować. Nie mam pojęcia od czego to zależy;/

Link do komentarza
Share on other sites

A gdzie masz pull-upy i jakie?

Jak kurcze teraz nie mam za bardzo czasu żeby to sprawdzić bo pracuję nad swoim pierwszym amatorskim robocikiem, ale na 200% działało mi to I2C.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.