PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USI Clock Probleme/Initialiseriungsprobleme



curby23523
16.06.2013, 19:06
Hi Leute,

ich hab 2 Controller (ATTiny1313 und ATTiny861a) die über USI als Two-Wire verbunden sind. Der 2313 wartet eine Start Condition ab (über Interrupt), schickt dann ein Zeichen über RS232 an den PC und wartet dann wieder auf eine Stop Condition.

Der 861A sendet immer um 1 Sekunde verzögerung eine Start und dann eine Stopcondition. In Putty sehe ich nun das Zeichen, welches der 2313 sendet, also erkennt der erfolgreich die Conditions.
Dies funktioniert allerdings nur, solange ich beim 861A das USICR Register nicht initialisiere. Sobald ich das initialisiere bleibt meine SDA Leitung stets "low". Aus dem Datenblatt wird mir nicht ersichtlich, warum das so sein sollte. Die Conditions werden nicht erkannt und es wird kein Zeichen an den PC gesendet.

Ich nehme an, dass durch meine Initialisierung irgendwelche Flags oder Bedingungen gesetzt werden, die ich noch nicht erkannt/verstanden habe.

Ich zeige euch mal die Funktionen und die Main-Routinen. Kann mir jemand helfen?

So langsam frage ich mich, warum man nicht eine richtrige SPI und i2C implementiert hat..

Danke!

Master:


#define USI_DDR DDRB
#define USI_PORT PORTB
#define SDA_DDR PORTB0
#define SCL_DDR PORTB2
#define SDA_PIN PINB0
#define SCL_PIN PINB2
#define SDA_OUT PORTB0
#define SCL_OUT PORTB2

#define slave_addr 2


void usi_clear_flags(){
USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(0<<USIDC)|(0x0<<USICNT0); //Clear Flags and Timer
}

void usi_master_initialize(){
USI_PORT |= (1<<SDA_OUT)|(1<<SCL_OUT);
USI_DDR |= (1<<SDA_DDR)|(1<<SCL_DDR); //SDA und SCL als AUsgänge

//USICR = (0<<USISIE)|(0<<USIOIE)|(1<<USIWM1)|(0<<USIWM0)|(0<<USICS1)|(0<<USICS0)|(0<<USICLK)|(0<<USITC);
USIDR = 0xFF;

usi_clear_flags();
}

void usi_send_byte(unsigned char msg){
unsigned char x;
USIDR = msg;
for(x=0;x<8;x++){
USICR |= (1<<USICLK);
_delay_us(100);
USICR |= (1<<USITC);
_delay_us(100);
USICR |= (1<<USITC);
_delay_us(100);
}
usi_clear_flags();
}

void usi_free_scl(){
USISR |= (1<<USIOIF);
}

void usi_stop_condition(){
usi_clear_flags();

USI_PORT &= ~(1<<SDA_OUT);
USI_PORT |= (1<<SCL_OUT);
_delay_us(100);
USI_PORT |= (1<<SDA_OUT);
// PORTA = USISR;
}

void usi_start_condition(){
usi_clear_flags();

USI_PORT &= ~(1<<SDA_OUT); //SDA High to Low
_delay_us(100);
USI_PORT &= ~(1<<SCL_OUT);
USI_PORT |= (1<<SDA_OUT);

//usi_clear_flags();
}


DDRA = 0b11111111;
DDRB = 0b11111111;
PORTA = 0xFF;
PORTB = 0xFF;

ADCSRA = (1<<ACD);

usi_master_initialize();

sei();
//--------------------------------Initialisierung---------------------------------------

while(1){
for(x=0;x<10;x++){ _delay_ms(100);}
usi_start_condition();
for(x=0;x<10;x++){ _delay_ms(100);}
usi_stop_condition();
}

return 0;
}


Slave:


#define USI_DDR DDRB
#define USI_PORT PORTB
#define SDA_DDR PORTB5
#define SCL_DDR PORTB7
#define SDA_IN PINB5
#define SCL_IN PINB7
#define SDA_OUT PORTB5
#define SCL_OUT PORTB7

#define slave_addr 1

void usi_clear_flags(){
USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0x0<<USICNT0); //Clear Flags and Timer
}

void usi_clear_counter(){

USISR &= 0b11110000;

}

unsigned char usi_receive_byte(){
usi_clear_flags();
loop_until_bit_is_set(USISR,USIOIF);
return USIDR;
}

void usi_free_scl(){
USISR |= (1<<USIOIF);
}

void usi_initialize_slave(){
USI_PORT &= ~((1<<SDA_OUT)|(1<<SCL_OUT));
USI_DDR &= ~((1<<SDA_DDR)|(1<<SCL_DDR)); //SDA und SCL als Eingänge
USICR = (1<<USISIE)|(1<<USIWM1)|(0<<USIWM0)|(1<<USICS1); //Startinterrupt;

usi_clear_flags();
}


void usi_wait_for_stop_condition(){
loop_until_bit_is_set(USISR,USIPF);
USISR |= (1<<USIPF);
}


inline unsigned char getch(){
while(!(UCSRA & (1<<RXC)));
return UDR;
}

inline void putch(unsigned char x){
while(!(UCSRA & (1<<UDRE)));
UDR = x;
}

int main(void)
{
unsigned char x;

//--------------------------------Initialisierung---------------------------------------
DDRA = 0xFF;
DDRB = 0b01011111; //USI EIngang
DDRD = 0b11111110; //RXD Eingang
PORTA = 0;
PORTB = 0;
PORTD = 0;

UBRRH = 0; //Usart initialisieren
UBRRL = F_CPU/(16*baud) -1; //-- //--
UCSRB = (1<<RXEN)|(1<<TXEN); //Usartinterrupt freigeben
UCSRC = (1<<UCSZ1)|(1<<UCSZ0); //--
x = UDR;

ACSR = (1<<ACD);

usi_initialize_slave();

sei();

while(1);

//--------------------------------Initialisierung---------------------------------------
return 0;
}

ISR(USI_START_vect){
unsigned char x,y;
USISR |= (1<<USISIF);

putch('A');

usi_wait_for_stop_condition();

}