Hallo,
hab mir ein Programm gebastelt, indem ein ATmega8 daten zu einem
ATtiny2313 schickt und die Dort im EEPROM gespeichert werden.
Das Problem was ich momentan habe ist das der Slave die Start bzw. Stop
condition nicht richtig erkennt.
Der Slave erkennt die Stop condition garnicht.
Und Beim erneuten senden der Start condition wird die die Adresse nicht
mehr kontrolliert, sondern einfach in die nächste Adresse des EEPROM
geschriebn. Das setzt sich solange fort, bis der Speicher überläuft.
Dann hängt sich die verbindung auf.
Sieht vieleicht jemand den Fehler? oder hat eine Idee woran es liegen
könnte?
Grüße
Philipp
Mit meinem Master schicke ich:
zuerst die Adresse des µCs,
dann die Adresse im EEPROM
dann das Byte welches im EEPROM gespeichert werden soll
Schleife in der main() vom Master aus:
1 | while(1)
|
2 | {
|
3 | if (!TWIM_Start (SlaveAddress, TWIM_WRITE))
|
4 | {
|
5 | TWIM_Stop ();
|
6 | }
|
7 | else
|
8 | {
|
9 | //EEPROM ADDRESS
|
10 | TWIM_Write (0x05);
|
11 |
|
12 | //DATA 1 + 2 + 3
|
13 | TWIM_Write (0x58);
|
14 | TWIM_Write (0x59);
|
15 | TWIM_Write (0x5A);
|
16 | TWIM_Stop ();
|
17 |
|
18 | Delay_ms (1000);
|
19 | }
|
20 | }
|
Befehl für die Stop conditon:
1 | void TWIM_Stop (void)
|
2 | {
|
3 | // Send stop condition
|
4 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
5 |
|
6 | //Wait until stop condition is executed and bus released
|
7 | while (TWCR & (1<<TWINT));
|
8 | }
|
USI_START_vect im Slave:
1 | ISR(USI_START_vect )
|
2 | {
|
3 | //##################################################################### UART S = START
|
4 |
|
5 | overflowState = USI_SLAVE_CHECK_ADDRESS; // Set default starting conditions for new TWI package
|
6 | DDR_USI &= ~( 1 << PORT_USI_SDA ); // Set SDA as input
|
7 |
|
8 |
|
9 |
|
10 | // Wait for SCL to go low to ensure the Start Condition has completed (the
|
11 | // Start detector will hold SCL low ) - if a Stop Condition arises then leave
|
12 | // The interrupt to prevent waiting forever - don't use USISR to test for Stop
|
13 | // Condition as in Application Note AVR312 because the Stop Condition Flag is
|
14 | // going to be set from the last TWI sequence
|
15 |
|
16 | while ( ( PIN_USI & ( 1 << PIN_USI_SCL ) ) && !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) ));// SCL his high and SDA is low
|
17 |
|
18 | if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
|
19 | { // A Stop Condition did not occur
|
20 | USICR =
|
21 | ( 1 << USISIE ) | // Keep Start Condition Interrupt enabled to detect RESTART
|
22 | ( 1 << USIOIE ) | // Enable Overflow Interrupt
|
23 | ( 1 << USIWM1 ) | ( 1 << USIWM0 ) | // Set USI in Two-wire mode, hold SCL low on USI Counter overflow
|
24 | ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | // 4-Bit Counter Source = external, both edges; Clock Source = External, positive edge
|
25 | ( 0 << USITC ); // No toggle clock-port pin
|
26 |
|
27 | }
|
28 | else
|
29 | { // A Stop Condition did occur
|
30 | USICR =
|
31 | ( 1 << USISIE ) | // Enable Start Condition Interrupt
|
32 | ( 0 << USIOIE ) | // Disable Overflow Interrupt
|
33 | ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | // Set USI in Two-wire mode, no USI Counter overflow hold
|
34 | ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | // 4-Bit Counter Source = external, both edges; Clock Source = external, positive edge
|
35 | ( 0 << USITC ); // No toggle clock-port pin
|
36 | }
|
37 |
|
38 | USISR =
|
39 | ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | // Clear interrupt flags - resetting the Start Condition Flag will release SCL
|
40 | ( 1 << USIPF ) |( 1 << USIDC ) |
|
41 | ( 0x0 << USICNT0); // Set USI to sample 8 bits (count 16 external SCL pin toggles)
|
42 | }
|