Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8][C] Nie działa komunikacja I2C

darekbranka 11 Jul 2010 21:09 2190 7
  • #1
    darekbranka
    Level 11  
    Witam

    Mam problem z uruchomieniem I2C na atmega8. To znaczy program zawiesza się po wysłaniu pierwszej komendy na magistralę. Program się kompiluje ale nie działa w Proteusu

    main:

    Code:
    #define F_CPU 8000000UL
    
    #include <avr/io.h>       
    #include <util/delay.h> 
    #include "TWI.h"



    void MCP(unsigned char devAddr, unsigned char regAddr, unsigned char regVal)
    {
    twistart();
    twiwrite(0x40 | (devAddr << 1));
    twiwrite(regAddr);
    twiwrite(regVal);
    twistop();
    }

    int main (void)
    {


    MCP(0x01,0x06,0x0f);

    _delay_ms(3);

    MCP(0x00,0x00,0x00);

    MCP(0x00,0x06,0x0f);



    MCP(0x00,0x09,0xff);
    }


    TWI.c

    Code:
    #include "TWI.h"
    

    // procedura transmisji sygnału START
    void twistart(void)
    {
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT)));
    }

    // procedura transmisji sygnału STOP
    void twistop(void)
    {
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    while ((TWCR & (1<<TWSTO)));
    }

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

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


    TWI.h



    Code:
    #include <avr/io.h>
    

    #define ACK 1
    #define NOACK 0

    // procedura transmisji sygnału START
    void twistart(void);
    // procedura transmisji sygnału STOP
    void twistop(void);
    // procedura transmisji bajtu danych
    void twiwrite(char data);
    //procedura odczytu bajtu danych
    char twiread(char ack);


    Bardzo proszę o pomoc
  • #2
    Andrzej__S
    Level 28  
    darekbranka wrote:

    To znaczy program zawiesza się po wysłaniu pierwszej komendy na magistralę. Program się kompiluje ale nie działa w Proteusu


    ...to znaczy próbowałeś go na sprzęcie, czy w symulatorze tylko?

    Nie ustawiłeś TWBR ani bitów TWPS w TWSR. Ich wartość jest inicjowana podczas startu jako 0, a to daje przy 8MHz zegarze częstotliwość magistrali ponad 444kHz. Jesteś pewien, że to prawidłowa wartość?
  • #4
    Andrzej__S
    Level 28  
    No cóż, sterownik użyty przez autora tematu jest bardzo uproszczony (np. brak sprawdzania potwierdzenia przy wysyłaniu danych). Nie znam tego sterownika z postu zaproponowanego przez mojego przedmówcę, ale ja osobiście używam oryginalnego sterownika ATMELa opartego na przerwaniach. Był wprawdzie napisany dla IAR, ale przerobienie go dla WinAvr nie sprawia większych problemów. Jego zaletą jest nie tylko to, że można sprawdzać poprawność transmisji, ale również fakt, że nie trzeba czekać do końca transmisji przed kontynuowaniem programu. Szczególnie ważne, jeśli wysyłamy większą ilość danych. Gdyby ktoś był zainteresowany, mogę udostępnić.

    Niezależnie od użytych sterowników wartość TWBR trzeba ustawić adekwatnie do oczekiwanej szybkości transmisji, a mam wrażenie, że autor tematu chyba to przeoczył.
  • #5
    flapo213
    Level 21  
    Witam,

    Takie rzeczy jak adres urządzenia to pasuje sobie chyba dobrać trudo abym jeszcze dostosowywał każdemu adres urządzenia. Naturalnie z moich procedur korzystać nie trzeba ja je wkleiłem żeby sobie porównać co być może jest nie tak a nie żeby z nich ślepo korzystać.
  • #6
    Andrzej__S
    Level 28  
    @flapo213:
    Chyba źle mnie zrozumiałeś. Nie krytykowałem Twoich procedur. Zwróciłem tylko uwagę, że autor tematu (czyli darekbranka, a nie Ty) zapomniał prawdopodobnie ustawić wartość rejestru TWBR, od którego jest zależna szybkość transmisji, a wydaje mi się, że to ważny parametr.

    Pisząc "sterownik autora tematu" też nie miałem na myśli Twojego sterownika, tylko kod załączony przez autora tego tematu (czyli darekbranka). Ponadto "uproszczony" nie musi wcale oznaczać "zły". Niekiedy taki uproszczony sterownik jest wystarczająco dobry dla konkretnej aplikacji.
  • #7
    flapo213
    Level 21  
    Witam,

    Domyślam się, dając komuś moje procedury zawsze mam na myśli pomoc w sensie podpatrzenia rozwiązania już przetestowanego i porównanie go z własnym. Podejście każdego programisty może być bardzo różne w efekcie coś ma zadziałać.

    Ale jest ok.

    Pozdrawiam