burnde
29.06.2011, 23:17
Hallo,
ich versuche schon seit einigen Tagen die USI als TWI am Attiny2313 zum laufen zu bekommen doch irgendwie gelingt es mir nicht. Ich habe einen Atmega8 als Master und der Attiny stellt den Slave da. Als Pull-Ups habe ich jeweils 4,7kOhm Wiederstände an den Leitungen. Am Ende des Projektes sollen noch mehrere Slaves hinzukommen darum viel die Wahl auf I2C.
Der Atmega8 spricht gutes I2C das habe ich mit einem anderen Atmega getestet. Das Problem liegt darin das die Start detection des Attiny's meinen Interrupt nicht auslöst. Ich möchte ersteinmal nur das der tiny einen START auf dem Bus erkennt. Ich sitze da schon ne ganze weile dran und wahrscheinlich ist es nur ein kleiner Fehler den ich übersehe aber langsam sehe ich die richtigen Register einstellungen vor lauter USI Artikeln nichtmehr :(
Achso beide laufen mit einem 16Mhz quarz.
Hier mal die main vom tiny. Ist noch nicht viel aber wie gesagt ich hänge ja schon bei der Start detection.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usi/usi.h"
ISR(USI_START_vect)
{
PORTD |= (1<<PD1);
//USISR |= (1<<USISIF);
}
ISR(USI_OVERFLOW_vect)
{
PORTD |= (1<<PD1);
//USISR |= (1<<USISIF);
}
int main(void)
{
DDRD |= (1<<PD1)|(1<<PD0);
PORTD |= (1<<PD1)|(1<<PD0);
cli();
initI2C();
i2cSetStartInterrupt();
sei();
PORTD &= ~(1<<PD1);
while(1)
{
PORTD &= ~(1<<PD0);
}
return 0;
}
Ich habe 2 LED's an PD0 und PD1 als Indicatoren fürs funktionieren.
Und hier die zugehörige usi.c
#include <avr/io.h>
/** @brief initI2C
*
* @todo: document this function
*/
void initI2C()
{
DDRB |= (1<<PB7);
DDRB |= (1<<PB5);
PORTB |= (1<<PB7);
PORTB |= (1<<PB5);
DDRB &= ~(1<<PB5);
USICR = (1<<USISIE) | (1<<USIOIE) | (1<<USIWM1) | (1<<USIWM0) | (1<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);
USISR = 0xf0;
}
/** @brief i2cSetStartInterrupt
*
* @todo: document this function
*/
void i2cSetStartInterrupt()
{
USICR |= (1<<USISIE);
}
ich versuche schon seit einigen Tagen die USI als TWI am Attiny2313 zum laufen zu bekommen doch irgendwie gelingt es mir nicht. Ich habe einen Atmega8 als Master und der Attiny stellt den Slave da. Als Pull-Ups habe ich jeweils 4,7kOhm Wiederstände an den Leitungen. Am Ende des Projektes sollen noch mehrere Slaves hinzukommen darum viel die Wahl auf I2C.
Der Atmega8 spricht gutes I2C das habe ich mit einem anderen Atmega getestet. Das Problem liegt darin das die Start detection des Attiny's meinen Interrupt nicht auslöst. Ich möchte ersteinmal nur das der tiny einen START auf dem Bus erkennt. Ich sitze da schon ne ganze weile dran und wahrscheinlich ist es nur ein kleiner Fehler den ich übersehe aber langsam sehe ich die richtigen Register einstellungen vor lauter USI Artikeln nichtmehr :(
Achso beide laufen mit einem 16Mhz quarz.
Hier mal die main vom tiny. Ist noch nicht viel aber wie gesagt ich hänge ja schon bei der Start detection.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usi/usi.h"
ISR(USI_START_vect)
{
PORTD |= (1<<PD1);
//USISR |= (1<<USISIF);
}
ISR(USI_OVERFLOW_vect)
{
PORTD |= (1<<PD1);
//USISR |= (1<<USISIF);
}
int main(void)
{
DDRD |= (1<<PD1)|(1<<PD0);
PORTD |= (1<<PD1)|(1<<PD0);
cli();
initI2C();
i2cSetStartInterrupt();
sei();
PORTD &= ~(1<<PD1);
while(1)
{
PORTD &= ~(1<<PD0);
}
return 0;
}
Ich habe 2 LED's an PD0 und PD1 als Indicatoren fürs funktionieren.
Und hier die zugehörige usi.c
#include <avr/io.h>
/** @brief initI2C
*
* @todo: document this function
*/
void initI2C()
{
DDRB |= (1<<PB7);
DDRB |= (1<<PB5);
PORTB |= (1<<PB7);
PORTB |= (1<<PB5);
DDRB &= ~(1<<PB5);
USICR = (1<<USISIE) | (1<<USIOIE) | (1<<USIWM1) | (1<<USIWM0) | (1<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);
USISR = 0xf0;
}
/** @brief i2cSetStartInterrupt
*
* @todo: document this function
*/
void i2cSetStartInterrupt()
{
USICR |= (1<<USISIE);
}