TWI Problem mit Timer0 Atmega8

Gast #3693416
Lesenswert?

Hallo zusammen,

Ich versuche einen Beschleunigungssensor mit TWI Schnittstelle 
auszulesen.
Ich will die Ergebnisse via UART im 50Hz Takt an den PC schicken.
Dazu nutze ich den Timer0 und eine if-Bedingung, etwa so:
1
#define timer0 TCNT0
2

3
uint8_t address = 0x1D;  //Adresse des Sensors
4
I2C Bus(100000);         //Instanz meiner TWI Klasse (100kHz Bitrate)
5
MMA8452Q Sensor(Bus);    //Instanz meiner Sensor Klasse
6
int Data[3];          //Speicher für Sensordaten
7

8
int main()
9
{
10
  init_timer0();
11
  init_UART();
12
  Sensor.init();
13
  while(1)
14
  {
15
  if(timer0 - 156 >= 0)  //50Hz Schleife
16
  {
17
    timer0 = 0;
18
    Sensor.update_state();  //hol Daten vom Sensor
19
    Sensor.get_state(Data); //speicher Daten in pointer
20

21
    UART_String("\r");
22
    for(int i = 0;i<3;i++)  //Ausgabe der Werte via UART
23
    {
24
      UART_int(Data[i]);
25
      UART_String("  ");
26
    }
27

28

29
  }
30

31
  }
32

33

34
  return 0;
35
}

Der Controller bleibt aber in einer while Schleife meiner TWI_Start 
Funktion hängen. Dieses Problem habe ich aber nur, wenn ich den Timer0 
benutze um meinen Code im 50 Hz Takt auszuführen. Wenn ich also im 
obigen Code die Bedingung:
1
if(timer0 - 156 >= 0)  //50Hz loop
weglasse, dann klappt alles prima.
Was für einen Zusammenhang gibt es denn zwischen dem TWI und Timer0?
Hier noch die TWI_Start Funktion, wo der Controller hängen bleibt:
1
uint8_t I2C::TWIM_Start (uint8_t address, uint8_t TWIM_Type)
2
{
3
  uint8_t    twst;
4
  /*
5
  ** Send START condition
6
  */
7
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
8
  /*
9
  ** Wait until transmission completed
10
  */
11
    while (!(TWCR & (1<<TWINT))){} !!!!!!hier bleibt der Controller hängen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12
  /*
13
  ** Check value of TWI Status Register. Mask prescaler bits.
14
  */
15
    twst = TWSR & 0xF8;
16
    //UART_String("\n\rStatus:\n\r");
17
    //UART_int8(twst);
18
    //UART_String("\n\r");
19
    if ((twst != TWI_START) && (twst != TWI_REP_START)) return FALSE;
20
  /*
21
  ** Send device address
22
  */
23
    TWDR = (address<<1) + TWIM_Type;
24
    TWCR = (1<<TWINT)|(1<<TWEN);
25
  /*
26
  ** Wait until transmission completed and ACK/NACK has been received
27
  */
28
    while (!(TWCR & (1<<TWINT))){}
29
  /*
30
  ** Check value of TWI Status Register. Mask prescaler bits.
31
  */
32
    twst = TWSR & 0xF8;
33
    if ((twst != TWI_MTX_ADR_ACK) && (twst != TWI_MRX_ADR_ACK)) return FALSE;
34

35
    return TRUE;
36
}

Ich kann mir im Moment wirklich nicht vorstellen an was das Problem 
liegen könnte, hat jemand von euch eine Idee?

Liebe Grüsse,
Roman
#3693505
Lesenswert?

Hast du PullUps an den TWI Leitungen?
Sonst bleibt er gerne an der beschriebenen Bedingung hängen.
1
while (!(TWCR & (1<<TWINT))){} !!!!!!hier bleibt der Controller hängen!!!!!

Ich sehe auch nirgendwo ein sei() um die Interrupts einzuschalten.
Dann funktioniert das
1
if(timer0 - 156 >= 0)  //50Hz loop
nicht.

Nur so als Ideen. Hab mir den Code nicht so genau angesehen.
#3693519
Lesenswert?

Karl Heinz schrieb:
> Doch. Tut es. Und zwar wegen#define timer0 TCNT0
>
> (persönliche halte ich das für keine gute Idee, aber ok.)

Ach ja richtig, er benutzt ja gar keinen Overflow IRQ, sondern direkt 
den Zählerwert.
Dann ist es aber komisch, dass es ohne die if-Bedingung funktionieren 
soll.
Wie weit zählt denn der Timer?
Vielleicht wird die Bedingung nie wahr?!
Gast #3693524
Lesenswert?

Nils Nachname schrieb:
> Hast du PullUps an den TWI Leitungen?

Ja habe ich (10kOhm). Das TWI funktioniert ohne die if Anweisung auch 
immer problemlos.

Nils Nachname schrieb:
> Ich sehe auch nirgendwo ein sei() um die Interrupts einzuschalten.
> Dann funktioniert das if(timer0 - 156 >= 0)  //50Hz loop
> nicht.

Ok, habe ich etwas verpasst? Ich aktiviere den Timer0 und lasse ihn 
einfach hochzählen und wenn er grösser gleich 156 ist, dann setze ich 
ihn wieder auf null. Wofür brauche ich Interrupts???
Gast #3693570
Lesenswert?

Ich hatte mit dem gleichen Sensor schon mal ein ähnliches Problem, bei 
dem der Controller in der selben while Schleife hängen geblieben ist.
Das Problem trat dann auf, wenn man vom Sensor Daten über das TWI 
gelesen hat.
Die NACK Funktion (not acknowledge) muss man als Master anscheinend 
nicht nach dem letzen empfangenen Byte aufrufen, sondern schon nach dem 
zweitletzen Byte.
Für mich macht das wenig Sinn und ich verstehe es auch nicht.
Aber wenn man es nicht so macht, dann steckt der Controller genau wieder 
in der Schleife.
Hat jemand von euch schonmal das gleiche Problem gehabt?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren