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

Atmega32 - program w C komunikacji za pomocą magistrali I2C

Odiosum 18 Sty 2011 00:14 1210 1
  • #1 18 Sty 2011 00:14
    Odiosum
    Poziom 2  

    Witam

    Mam Atmege32 połączoną z czujnikiem MMC2120MG (http://profmason.com/wp-content/uploads/2010/09/MMC2120MG.pdf). Jak widać z datasheeta komunikuje się on za pomocą magistrali I2C.

    Próbuję napisać program w C, który umożliwi mi komunikację z tym czujnikiem, jednak nie udaje mi się uzyskać żadnych odczytów.

    Tak wygląda kod z którego korzystam

    Code:

    #define F_CPU 4000000UL  // 4 MHz

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

    /*
    Adres czujnika 011000x (x : 0 - zapis, 1 - odczyt
    */

    // 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)));
    }

    // transmisja 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 daneCzujnik[5],i;   
    TWBR = 255;

    /* na porcie A i D - podpięte przez rezystor diody do zasilania - świecą dla 0 */
    DDRA = 0xFF;
    PORTA = 0xFF;
    DDRD = 0xFF;
    PORTD = 0xFF;


    while(1){
       
       twistart();
       twiwrite(0b01100000); //1 cykl z noty katalgowej

       twiwrite(0);      //2 cykl - adres     
       twiwrite(1);    //3 cykl - wake up call     
       twistop();     
       
       _delay_ms(10);

       twistart();
       twiwrite(0b01100000); // 4 cykl - z poleceniem zapisu

       twiwrite(0); // 5 cykl adres z którego mamy czytać
       twiwrite(0b01100001); // 6 cykl - z poleceniem odczytu
          
          for(i=0;i<5;i++){
             daneCzujnik[i] = twiread(0);      //cykle 7-11 dane
          }

       twistop(); // kończymy komunikacje

    DDRA=daneCzujnik[1]; // przepisujemy na port A i D odczytane wartości
    DDRD=daneCzujnik[2];

    while(1){}// wieczna pętla, aby tylko raz dokonać pomiaru

    }
    }



    Nie znam się zbytnio na programowaniu mikrokontrolerów, dlatego zgłaszam się tutaj po pomoc.

    Nie wiem co może być przyczyną braku komunikacji moje przewidywania:
    1. Błędy w programie
    2. Zły dobór częstotliwości z jaką mają pracować układy ?
    3. Brak rezystorów podciągających na liniach SDA i SDL (podobno nie trzeba ich dawać bo można skorzystać z wewnętrznych będących w atmedze ?)

    Z góry dziękuję za pomoc

    0 1
  • #2 18 Sty 2011 07:28
    p_zag
    Poziom 13  

    Witam
    Przeanalizuj mój działający program Atmega8 i TWI , ale jak zacząć... , co prawda jest na atmege8 ale rejestry magistrali TWI powinny być takie same, być może coś znajdziesz dla siebie.

    0