Forum: Compiler & IDEs TWI-ISR definieren


von Jey B. (jeybee)


Lesenswert?

Moin Moin

Ich bin gerade wie deran, am TWI-Slave zu basteln. Da ich zur zeit noch 
keine Interrupts verwende, sondern alles polle, kann der Slave sonst 
halt nicht viel machen. Darum will ich nun meinen TWI-Slave mit dem 
Interrupt betreiben.

Hierzu habe ich in Datasheet des ATmega16s im Kapittel "Interrupts" 
geseh, dass es schon einen TWI vektor gibt. Nun gut.

Anscheinend verstehe ich da was falsch: Ich habe nun die 
<avr/interrupt.h> eingebunden, sei(); gesetzt und nun die ISR mit dem 
TWI-Vektor initialisiert. Jedoch passiert nun garnichts. Der Master 
sendet die Slave Adresse etc, jedoch kriegt weder der Master noch der 
Slave irgend ein Ack oder so.

Wo ist mein Fehler? habe ich irgend welche Register übersehen, die es zu 
sezten gibt?

Hier mein Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include "twislave.h"
5
#include "lcd.h"
6
7
8
int main(void)
9
{
10
  uint8_t twisend;             // TWI sendevariable
11
  uint8_t twirecive;          // TWI empfangsvariable
12
  unsigned char buffer[10];      // Buffer für itoa
13
  
14
  lcd_init(LCD_DISP_ON);
15
  twi_slave_init(0x00);               // TWI Slave initialisieren & Adresse festloegen
16
  sei();
17
18
19
  while(1)
20
  {
21
    twisend = 0xCB;
22
23
/*
24
    twi_slave_transmit(twisend);
25
26
    //twirecive = twi_slave_recive();
27
28
    lcd_clrscr();
29
    lcd_gotoxy(0,0);
30
    lcd_puts("I am your Slave");
31
    lcd_gotoxy(0,1);
32
    lcd_puts("Senden: 0x");
33
    lcd_puts(itoa(twisend, buffer, 16));
34
  */
35
  }
36
}
37
38
39
ISR(TWI_vect)
40
{
41
  lcd_clrscr();
42
  lcd_gotoxy(0,0);  
43
  lcd_puts("Okay");    //Test
44
}


Danke und Greez Jey

von Oliver (Gast)


Lesenswert?

Tja, der Fehler liegt vermutlich in Zeile 42 von twi_slave_init().

Oliver

von Klaus (Gast)


Lesenswert?

Oliver schrieb:
> Tja, der Fehler liegt vermutlich in Zeile 42 von twi_slave_init().

QUATSCH!!!  Deine Glaskugel ist nur Kaputt ;-)

von Jey B. (jeybee)


Lesenswert?

Was ist denn nun? warum sollte in der init ein Fehler sein?

von me (Gast)


Lesenswert?

ich glaube, dass der Fehler eher in der "twislave.h" ist. Ein 
Deklarationsfehler.

von Karl H. (kbuchegg)


Lesenswert?

Jey Bee schrieb:
> Was ist denn nun? warum sollte in der init ein Fehler sein?

Weil irgendwo ein Fehler ist.
Und in dem was du gepostet hast, ist er nicht (ausser das du TWINT nicht 
löscht, das ist aber jetzt noch nciht das Problem). Das ist aber auch 
keine Kunst, den das was du gepostet hast, macht ausser andere 
Funktionen aufrufen ja auch nichts wirklich Aufregendes.

Und nachdem es die LCD Funktionen höchst wahrscheinlich nicht sind, 
bleibt eigentlich nur noch die twi_slave_init als Kandidat übrig. Du 
hast doch dort den Interrupt freigeschaltet, oder?

von JeyBee (Gast)


Lesenswert?

Moin,

Also das LCD funktioniert.
Tschuldigung, habe am anfang vergessen, die twislave.c mit zu posten.
Hier mal die twislave.c:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "twislave.h"
5
6
void twi_slave_init(uint8_t slaveadr)
7
{
8
   TWAR = slaveadr;
9
   TWCR |= (1<<TWEN) | (1<<TWEA);
10
}
11
12
uint8_t twi_slave_transmit(uint8_t twi_transmit)
13
{
14
  while(!(TWCR & 0b10000000)); //solange warten, bis was ankommt
15
  TWDR = twi_transmit;    //Zu Übermittelnden Wert in TWDR schreiben
16
  TWCR |= (1<<TWINT);
17
  return 0;
18
}
19
20
uint8_t twi_slave_recive(void)
21
{
22
  uint8_t twi_status;
23
  uint8_t twirecive;
24
  
25
  while(!(TWCR & 0b10000000));   //  solange warten, bis was ankommt
26
  twi_status = TWSR;        //  Status abfragen..
27
28
  TWCR &=~ (1<<TWINT);      //  TWINT auf 0 setzten damit TWI wieder arbeitet
29
  TWCR |=  (1<<TWEA);        //  TWEA auf 1 setzten um Ack zu senden  
30
    
31
  if(TWSR == 128)
32
  {
33
    twirecive = TWDR;
34
  }
35
  return twirecive;
36
}

Also speziell für die Interrupts hab ich jetzt nichts geändert, demfall 
muss da der Fehler liegen.

von Stefan E. (sternst)


Lesenswert?

Ich sehe nicht, dass du da irgendwo den TWI-Interrupt freischaltest.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

· Bit 0 ­ TWIE: TWI Interrupt Enable

When this bit is written to one, and the I-bit in SREG is set,
the TWI interrupt request will be activated for as long as the
TWINT Flag is high.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.