TWI-ISR definieren

OP #1742830
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
#1743429
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?
Gast #1743539
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.

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