Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATMEGA16][C] TWI nie działa w C, w Bascomie tak

18 Maj 2009 17:04 1668 11
  • Poziom 19  
    Celem jest zapisanie w pamięci AT24C04 jakiś danych.

    Program w Bascomie:
    Code:

    $regfile = "m16def.dat"
    $crystal = 4000000

    Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
    Config Lcd = 20 * 4
    Dim Temp As Byte
    Cls
    Cursor On Blink

    I2cstart
    I2cwbyte 162
    I2cwbyte 1
    I2cwbyte 100
    I2cstop
    Waitms 15

    I2cstart
    I2cwbyte 162
    I2cwbyte 1
    I2cstart
    I2cwbyte 163
    I2crbyte Temp , 9
    I2cstop

    Lcd "Temp: " ; Temp
    End

    Zapisuje do adresu 1 wartość 100 i wyświetla ją na LCD.

    Program w C:
    Code:

    #define SCL_CLOCK  100000L
    #define F_CPU 4000000
    #include <util/twi.h>
    #include <avr/io.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
       char SLA_W = 162, DATA1 = 1, DATA2 = 100;
       DDRA=0xFF;
       PORTA =0xFF;
       LCDinit();
       LCDcls();

       TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //start
       while (!(TWCR & (1<<TWINT)));
       if ((TWSR & 0xF8) != 0x08)
          LCDstr("START");
       TWDR = SLA_W; //zapis adresu
       TWCR = (1<<TWINT) | (1<<TWEN);
       while (!(TWCR & (1<<TWINT)));
       if ((TWSR & 0xF8) != 0x18)
          LCDstr("MT_SLA_ACK");
       TWDR = DATA1; //zapis komórki
       TWCR = (1<<TWINT) | (1<<TWEN);
       while (!(TWCR & (1<<TWINT)));
       if ((TWSR & 0xF8) != 0x28)
          LCDstr("MT_DATA_ACK");
       TWDR = DATA2; //zapis danych
       TWCR = (1<<TWINT) | (1<<TWEN);
       while (!(TWCR & (1<<TWINT)));
       if ((TWSR & 0xF8) != 0x28)
          LCDstr("MT_DATA_ACK");
       TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    }

    No i w efekcie wywala wszystkie możliwe błędy... Kod ten jest na żywca ściągnięty z pdfa o ATMEGA16 i nie działa :/
  • Poziom 39  
    A gdzie jakaś biblioteka do LCD? Przecież kompilator nie będzie wiedział co z tymi poleceniami LCD ma zrobić...
  • Poziom 19  
    Przy wklejaniu usuwałem niepotrzebne includy i lcd też poszedł. Problem nie leży w LCD, tylko w TWI.
  • Poziom 39  
    Uściślijmy:
    "wywala wszystkie błędy" - czyli kompilacja nie przechodzi czy przechodzi (u mnie przechodzi po usunięciu procedur LCD)?
    "i nie działa" - czyli program zatrzymuje się wogóle czy na jakimś etapie skoro się kompiluje?
  • Poziom 32  
    Polecam sprawdzone przez siebie źródło:Link
  • Poziom 19  
    ZbeeGin, masz rację - źle się wyraziłem. Wszystko się kompiluje bez błędów. Na LCD wyświetla wszystkie błędy I2C, które mogą obsługuje ww. program czyli:
    - START
    - MT_SLA_ACK
    - MT_DATA_ACK
    - MT_DATA_ACK

    dawid512, gdybyś przyjżał się dokładnie obu kodom, zauważyłbyś, że... są identyczne - ten od radzia również próbowałem i nie działa.
  • Poziom 39  
    A gdzie jest inicjalizacja TWI? W szczególności jego preskalera, bo jednym DEFINE tego raczej nie załatwisz...
  • Poziom 19  
    Rozumiem, że chodzi o rejestr TWBR? Zakładając, że chcę z max szybkością, to wpisuję TWBR = 0x01, tak? Czy muszę dodać coś jeszcze? O dziwo na stronach które czytałem nie ma zbytnio inicjalizacji (np. na stronie radzia), dataszit też jakoś tego nie zaznacza w przykładzie.
  • Poziom 32  
    Proszę bardzo:
    Code:
    TWSR = 0; 
    
    TWBR = 114;


    Reszta w datasheecie.
  • Poziom 19  
    dawid512 dzięki - mógłbyś jeszcze podać z której strony datasheeta to wziąłeś i gdzie jeszcze mam patrzeć?

    Dodano po 9 [minuty]:

    Chyba jestem głupi jakiś, ale wpisałem tą inicjalizację i nadal nie działa tak jak nie działało... Dodałem też opóźnienie 50ms między kolejnymi komendami.
  • Poziom 19  
    Dzięki, nie rozumiem dlaczego, ale działa - mimo, że jest chyba identyczne z tym co ja napisałem wcześniej... Cuda na kiju.